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

Reply via email to