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



             Bug #: 56552

           Summary: conditional move can generate unnecessary conversion

                    code

    Classification: Unclassified

           Product: gcc

           Version: 4.8.0

            Status: UNCONFIRMED

          Severity: normal

          Priority: P3

         Component: middle-end

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

        ReportedBy: s...@gcc.gnu.org

            Target: mips*-*-*





With this test program:



unsigned short foo(unsigned short a1, unsigned short a2)

{

  unsigned short i, x;

  for (i = 0; i < 8; i++) {

    x = (a1 & 1) ^ (a2 & 1);

    a1 >>= 1;

    if (x == 1) a2 ^= 0x2006;

    a2 >>= 1;

    if (x == 1) a2 |= 0x8800;

    else        a2 &= 0x77ff;

  }

  return a2;

}



The GCC 4.8 MIPS compiler generates a 'andi r,r,0xffff' instruction after

a movz (conditional move) that was not present in GCC 4.7.  This instruction

is generated because MIPS does not implement a 'short' conditional move so

expand_cond_expr_using_cmove promotes the mode then it has to 'demote' it back

to short and that generates the andi instruction.  But if the source and

destination of the conditional move are both shorts to begin with this andi

instruction is not needed.



The problem was fixed with this patch:



http://gcc.gnu.org/ml/gcc-patches/2012-11/msg01148.html



However it caused bug PR56548 (ICE on x86) and the fix for that

bug causes the extra andi instruction to once again be generated.

Reply via email to