http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56369



             Bug #: 56369

           Summary: Missed opportunity to combine comparisons with zero

    Classification: Unclassified

           Product: gcc

           Version: 4.8.0

            Status: UNCONFIRMED

          Severity: enhancement

          Priority: P3

         Component: tree-optimization

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: olege...@gcc.gnu.org

            Target: sh*-*-* arm*-*-*





I'm not sure whether this is really a tree-optimization or middle-end (e.g.

combine) issue...



With rev 196091 the following example:



extern int func_10 (void*);



int

func_11 (void* x)

{

 int status = 0;



 do

 {

   status = func10 (x);

   status = status < 0 ? status : 0;

 } while (status >= 0);



 return status;

}



compiled for SH4 with -O2 -m4 results in:

_func_11:

        mov.l   r8,@-r15

        mov.l   r9,@-r15

        mov     r4,r9

        mov.l   .L8,r8

        sts.l   pr,@-r15

        .align 2

.L4:

        jsr     @r8

        mov     r9,r4



        cmp/pl  r0      // T = r0 > 0

        bt/s    .L4

        tst     r0,r0   // T = r0 == 0

        bt      .L4



        lds.l   @r15+,pr

        mov.l   @r15+,r9

        rts

        mov.l   @r15+,r8

.L9:

        .align 2

.L8:

        .long    _func10





As seen above, the two comparisons could be done with a single one:

  cmp/pz  r0   // T = r0 >= 0



I've tried out a few SH specific things to see if combine would do it, but it

just won't combine the two.  I guess because the two comparisons end up in two

different basic blocks.



On ARM, there's a smin insn defined, but the problem is the similar.  The

example above compiled with -O2 results in:



func_11:

        stmfd    sp!, {r4, lr}

        mov    r4, r0

.L3:

        mov    r0, r4

        bl    func10



        and    r0, r0, r0, asr #31    // smin (r0, 0)

        cmp    r0, #0                  // r == 0

        beq    .L3

        ldmfd    sp!, {r4, lr}

        bx    lr



which could be done without the smin (r0, 0), and save the and insn:



func_11:

    stmfd    sp!, {r4, lr}

    mov    r4, r0

.L3:

    mov    r0, r4

    bl    func10



    cmp    r0, #0

    bge    .L3

    ldmfd    sp!, {r4, lr}

    bx    lr

Reply via email to