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



             Bug #: 56096

           Summary: Bad code generated for conditional shift

    Classification: Unclassified

           Product: gcc

           Version: 4.7.2

            Status: UNCONFIRMED

          Severity: normal

          Priority: P3

         Component: target

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

        ReportedBy: til...@code-monkey.de





Compiling this snippet



unsigned f1 (unsigned x, unsigned m)

{

    x >>= ((m & 0x008080) ? 8 : 0);

    return x;

}



with gcc 4.7.2 gives this code for ARMv5:



$ armv5tel-softfloat-linux-gnueabi-gcc -O2 -S -o- f.c

[...]

    ldr    r3, .L4

    and    r3, r1, r3

    cmp    r3, #0

    movne    r3, #8           @ XXX

    moveq    r3, #0           @ XXX

    mov    r0, r0, lsr r3   @ XXX

    bx    lr

[...]



Those three mov instructions are clearly sub-optimal.



Replacing the ternary operator with an if-statement gives the expected code

sequence:



unsigned f1 (unsigned x, unsigned m)

{

    if (m & 0x008080)

        x >>= 8;



    return x;

}



-> 

    ldr    r3, .L6

    and    r3, r1, r3

    cmp    r3, #0

    movne    r0, r0, lsr #8

    bx    lr



ie we saved two mov instructions.

Reply via email to