https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77543
Bug ID: 77543 Summary: ARM: G++ generates redundant instructions at -O0 Product: gcc Version: 5.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: mh at ashwireless dot com Target Milestone: --- (This is using the 2016q2 release of the ARM toolchain, GCC 5.4.1). Use first arm-none-eabi-gcc and then arm-none-eabi-g++ to compile this code (without any optimisation i.e. -O0): ------------------------- void doStuff(void); int getNum(void); void compare1(int n) { if(n > 33) { doStuff(); } if(getNum() > 44) { doStuff(); } } -------------------------- GCC generates pretty much what I'd expect: 27 0010 08301BE5 ldr r3, [fp, #-8] 28 0014 210053E3 cmp r3, #33 29 0018 000000DA ble .L2 30 001c FEFFFFEB bl doStuff 31 .L2: 32 0020 FEFFFFEB bl getNum 33 0024 0030A0E1 mov r3, r0 34 0028 2C0053E3 cmp r3, #44 35 002c 000000DA ble .L4 36 0030 FEFFFFEB bl doStuff 37 .L4: But from G++: 32 0010 08301BE5 ldr r3, [fp, #-8] 33 0014 210053E3 cmp r3, #33 34 0018 000000DA ble .L2 35 001c FEFFFFEB bl _Z8doStuffv 36 .L2: 37 0020 FEFFFFEB bl _Z6getNumv 38 0024 0030A0E1 mov r3, r0 39 0028 2C0053E3 cmp r3, #44 40 002c 0130A0C3 movgt r3, #1 ; if >44, set flag = 1 41 0030 0030A0D3 movle r3, #0 ; if <=44, set flag = 0 42 0034 FF3003E2 and r3, r3, #255 ; treat as a byte 43 0038 000053E3 cmp r3, #0 ; compare flag == 0? 44 003c 0000000A beq .L4 45 0040 FEFFFFEB bl _Z8doStuffv 46 .L4: Similar constructions are generated for Thumb and Thumb-2 instruction-sets. So the bug occurs only if compiling as C++, and only when testing a value returned from a function. It seems to be using a uint8_t as a flag, initially setting it true, changing it to false if the condition is not met, then zero-extending the uint8_t to 32 bits before jumping based on its value - 7 instructions instead of 2 (and using an extra register). So two questions - why is it using a flag at all, and why is the flag handled as a byte rather than a word? The redundant instructions disappear if I enable optimisation O1 or Og, but it would be better not to generate them in the first place.