Consider this simple test case:
extern void foo (void);
extern void bar (void);
void bgtutest (unsigned int a, unsigned int b)
{
if (a + b > 0)
foo ();
else
bar ();
}
gcc mainline revision 127532 -O2 -S -dp:
bgtutest:
.LFB2:
addl %edi, %esi # 7 *addsi_1/1 [length = 2]
testl %esi, %esi # 8 *cmpsi_ccno_1/1 [length = 2]
jne .L5 # 9 *jcc_1 [length = 2]
jmp bar # 15 *call_0 [length = 5]
.p2align 4,,10
.p2align 3
.L5:
jmp foo # 11 *call_0 [length = 5]
The reason is that combine insists on simplifying a + b > 0 as a == -b (as seen
in the dump file):
Failed to match this instruction:
(set (reg:CCZ 17 flags)
(compare:CCZ (reg/v:SI 59 [ b ])
(neg:SI (reg/v:SI 58 [ a ]))))
Failed to match this instruction:
(set (pc)
(if_then_else (eq (neg:SI (reg/v:SI 58 [ a ]))
(reg/v:SI 59 [ b ]))
(label_ref 13)
(pc)))
--
Summary: combine not combining add + test in if (a + b) > 0
Product: gcc
Version: 4.3.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: enhancement
Priority: P3
Component: rtl-optimization
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: rask at gcc dot gnu dot org
GCC build triplet: x86_64-unkonwn-linux-gnu
GCC host triplet: x86_64-unkonwn-linux-gnu
GCC target triplet: x86_64-unkonwn-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33089