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.