This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/40672] New: constant address loads moved into loop unnecessarily
- From: "froydnj at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 7 Jul 2009 14:56:09 -0000
- Subject: [Bug target/40672] New: constant address loads moved into loop unnecessarily
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
The testcase below:
typedef unsigned char uint8_t;
#define UART3_LSR (*(volatile uint8_t *)(0x49020000+20))
#define UART3_RBR (*(volatile uint8_t *)(0x49020000+0))
int IsSerialBufferFull(void)
{
return (UART3_LSR & 0x20) == 0;
}
void SendSerialByte(uint8_t byte)
{
while (IsSerialBufferFull())
;
UART3_RBR = byte;
}
when compiled with arm-none-eabi-gcc -O2 results in suboptimal code for
SendSerialByte:
SendSerialByte:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
mov r3, #1224736768
add r3, r3, #131072
.L3:
ldrb r2, [r3, #20] @ zero_extendqisi2
tst r2, #32
mov r2, #1224736768
add r2, r2, #131072
beq .L3
strb r0, [r2, #0]
bx lr
.size SendSerialByte, .-SendSerialByte
The load of the constant for UART3_RBR (mov r2/add r2) should not be moved into
the loop, since it's not needed until after the loop. Furthermore, the
necessary value is already available in r3.
The same problem doesn't happen on other platforms, e.g. mips-sde-elf gives:
andi $4,$4,0x00ff
li $2,1224867840 # 0x49020000
.L6:
lbu $3,20($2)
andi $3,$3,0x20
beq $3,$0,.L6
nop
sb $4,0($2)
j $31
nop
or powerpc-eabi:
lis 9,0x4902
ori 9,9,20
.L4:
lbz 0,0(9)
andi. 11,0,32
beq+ 0,.L4
lis 9,0x4902
stb 3,0(9)
blr
(which is not quite perfect, but better than the arm-none-eabi code...).
--
Summary: constant address loads moved into loop unnecessarily
Product: gcc
Version: 4.5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: froydnj at gcc dot gnu dot org
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: arm-none-eabi
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40672