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: [email protected]
ReportedBy: [email protected]
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