https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85593
Bug ID: 85593 Summary: GCC on ARM allocates R3 for local variable when calling naked function with O2 optimizations enabled Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: inline-asm Assignee: unassigned at gcc dot gnu.org Reporter: austinpmorton at gmail dot com Target Milestone: --- Created attachment 44048 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44048&action=edit example code triggering bug When calling a naked function declared in the same translation unit which includes inline assembly that modifies registers which are not preserved across function calls according to the arm abi (R0-R3), GCC 5+ can incorrectly allocate these registers for local variables in the caller and expect them to persist between function calls. * -O2 must be enabled to observe this behavior. * the function must be declared in the same translation unit, if declared extern gcc correctly allocates preserved registers for its locals * GCC 4.6.4 correctly allocates R4 in the example code given * GCC 5.4, and all higher versions tested incorrectly allocates R3 in the example code given * I have built a clean copy of GCC trunk and observed this issue as well note: this issue is present on all arm triplets I have tested, not just arm-none-eabi. compile bug.c with the following options to observe the bug arm-none-eabi-gcc -O2 -DBUG -S bug.c -o - compile bug.c with the following options to observe the correct behavior with an extern declaration arm-none-eabi-gcc -O2 -S bug.c -o - note that in the non-working compiler versions gcc attempts to load a value from r3 between calls to test2, whereas in the working compiler versions gcc will produce identical code save for using r4. for convenience sake, here is the example shown in working vs nonworking compiler versions on godbolt: https://godbolt.org/g/kMSn8W