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.