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