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



             Bug #: 55987

           Summary: Redundant constant emitted

    Classification: Unclassified

           Product: gcc

           Version: 4.7.2

            Status: UNCONFIRMED

          Severity: normal

          Priority: P3

         Component: pending

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

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

            Target: arm





For this code



  uint32_t add (uint32_t x, uint32_t y)

  {

      uint32_t a, b;



      a = (x & 0x7f7f7f7f) + (y & 0x7f7f7f7f);

      b = (x ^ y) & ~0x7f7f7f7f;



      return a ^ b;

  }



gcc 4.7.2 generates the following machine code for ARMv5:



$ gcc -Wall -O2 -mtune=arm9tdmi -march=armv5te -S add.c



    ldr    r2, .L2     @ .word  2139062143

    ldr    r3, .L2+4   @ .word -2139062144

    eor    ip, r1, r0

    and    r1, r1, r2

    and    r2, r0, r2

    and    r3, ip, r3

    add    r0, r1, r2

    eor    r0, r3, r0

    bx    lr



gcc missed that we can use bic to clear the low bits, which means

we don't need that 2nd constant:



    ldr    r2, .L2     @ .word 2139062143

    eor    ip, r1, r0

    bic    ip, ip, r2  @ use bic instead of and

    and    r1, r1, r2

    and    r0, r0, r2

    add    r0, r0, r1

    eor    r0, r0, ip

    bx    lr

Reply via email to