https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89222
Bug ID: 89222 Summary: [7.x regression] ARM thumb-2 misoptimisation of func ptr call with -O2 or -Os Product: gcc Version: 7.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: jifl-bugzilla at jifvik dot org Target Milestone: --- Created attachment 45616 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45616&action=edit C file to demonstrate problem [ I have set the Component as "Other" as I don't know which part of GCC's optimization is at fault] On GCC 7.3.0 I am experiencing a problem where GCC is misoptimizing code built with either -O2 or -Os. The effect of the misoptimization is that it calls a function pointer without the LS bit set, even though the function is a Thumb function (it's Cortex-M, so ARM mode isn't even allowed). The attached pared-down code demonstrates this, although I couldn't manage to divorce it from my embedded run-time, so unfortunately you will have to inspect the asm :-/ The key part is that if a certain magic constant is 1, then it fails. This constant is used to compare against function pointers (it is the value of SIG_DFL from signal.h and this sort of comparison is standard practise, e.g. in glibc etc.). Values of SIG_DFL other than 1 work - it is the fact it is 1 that confuses GCC. In the asm (I used -Os as it made more tractable output), right at the start of main(), r5 is loaded with e.g. 0x200003a7. Then this value plus one is put into $r6. For most of the rest of the function r6 is left as-is, and is saved and restored around the call to the hal_setjmp function. Shortly after, there is a "blx r6" and that's when the processor gets the exception. The C file shows this when built with: arm-eabi-gcc -c -mcpu=cortex-m3 -mthumb -Os signal1.c Or -O2 equally.