http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59609
Bug ID: 59609
Summary: LRA generates bad code for libgcc function udivmoddi4
on thumb1 target
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: blocker
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: terry.guo at arm dot com
Created attachment 31523
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31523&action=edit
a reduced case
Thumb-1 target like cortex-m0 hasn't hardware div instruction, thus the
function __udivmoddi4 in libgcc is used. However this function is wrongly
compiled by LRA which is enabled in recent gcc, codes that use __udivmoddi4
will get a wrong results. When print unsigned long long value using printf
function, the printf function will use __udivmoddi4 and eventually will end up
with dead loop.
Attachment is a reduced case based on __udivmoddi4 function.And I am using the
latest gcc trunk code. Compile the attached case with command:
arm-none-eabi-gcc -mthumb -mcpu=cortex-m0 -O2 -S myudi.c
then check the assembly code:
sub r3, r3, #32 << should initialize ip after this insn
bpl .LCB31
b .L4 @long jump
.LCB31:
mov ip, r3
mov r3, r9
mov r2, ip
lsl r3, r3, r2
mov r7, r3
.L5:
mov r3, r9
lsl r3, r3, r1
mov r6, r3
cmp r7, r5
bhi .L20
beq .L29
.L22:
mov r3, ip << Here is the wrong code, the ip is uninitialized.
sub r4, r4, r6
sbc r5, r5, r7
cmp r3, #0
bge .LCB50