Compile the following function with options -Os -mthumb -march=armv5te
int ldrb(unsigned char* p)
{
if (p[8] <= 0x7F)
return 2;
else
return 5;
}
Gcc generates following codes:
push {lr}
mov r3, #8
ldrsb r3, [r0, r3]
mov r0, #2
cmp r3, #0
bge .L2
mov r0, #5
.L2:
@ sp needed for prologue
pop {pc}
The source code if (p[8] <= 0x7F) is translated to:
mov r3, #8
ldrsb r3, [r0, r3]
cmp r3, #0
A better code sequence should be:
ldrb r3, [r0, 8]
cmp r3, 0x7F
This can save one instruction.
The tree dump shows in a very early pass (ldrb.c.003t.original) the comparison
was transformed to
if ((signed char) *(p + 8) >= 0)
I guess gcc thinks comparing with 0 is much cheaper than comparing with other
numbers. Am I right?
Unfortunately in thumb mode, loading a signed byte costs more than loading an
unsigned byte and comparing with 0 has same cost as comparing with 0x7F.
--
Summary: unnecessary conversion from unsigned byte load to signed
byte load
Product: gcc
Version: 4.5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: carrot at google dot com
GCC build triplet: i686-linux
GCC host triplet: i686-linux
GCC target triplet: arm-eabi
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40603