https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91384
Bug ID: 91384 Summary: Compare with negation is not eliminated Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: ubizjak at gmail dot com Target Milestone: --- Following testcase: --cut here-- void foo (void); void bar (void); int test (int a) { int r; if (r = -a) foo (); else bar (); return r; } --cut here-- results in (-O2): movl %edi, %r12d negl %r12d testl %edi, %edi je .L2 The combine pass can't do anything, since it sees: (insn 6 3 7 2 (parallel [ (set (reg/v:SI 82 [ <retval> ]) (neg:SI (reg/v:SI 83 [ a ]))) (clobber (reg:CC 17 flags)) ]) "neg.c":9:9 464 {*negsi2_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) (insn 7 6 8 2 (set (reg:CCZ 17 flags) (compare:CCZ (reg/v:SI 83 [ a ]) (const_int 0 [0]))) "neg.c":9:6 7 {*cmpsi_ccno_1} (expr_list:REG_DEAD (reg/v:SI 83 [ a ]) (nil))) Please note that the compare is with the original value (reg: 83), not with the result of the negation (reg: 82). Tree optimizers give us: r_3 = -a_2(D); if (a_2(D) != 0) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] This is a regression from 4.1.2, where the compiler is able to eliminate the compare: movl %esi, %ebx negl %ebx je .L2