This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/52474] New: Regression: AVR-GCC: arithmetics produce completely wrong result
- From: "wwieser at gmx dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sat, 03 Mar 2012 23:58:24 +0000
- Subject: [Bug c/52474] New: Regression: AVR-GCC: arithmetics produce completely wrong result
- Auto-submitted: auto-generated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52474
Bug #: 52474
Summary: Regression: AVR-GCC: arithmetics produce completely
wrong result
Classification: Unclassified
Product: gcc
Version: 4.5.3
Status: UNCONFIRMED
Severity: critical
Priority: P3
Component: c
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: wwieser@gmx.de
Host: x86_64-unknown-linux-gnu
Target: avr
Build: Debian version gcc-avr 4.5.3-1 and -4
A bug exists in avr-gcc 4.5.3 which was not present in 4.3.5.
I did not find a bug report for that, yet do not have the resources to test
this on the newest development version of avr-gcc.
The bug causes certain arithmetic computations to yield completely wrong
results. It seems negative values are not handeled correctly.
The bug only shows up with optimization turned on (-O2) and not if turned off
(-O0).
Test case:
//-----------------------------------------------------------------
int16 slope = 1025 + QUERY();
int16 v = (int16)( (int32)(-800) * slope / 512L ) ;
// This will compute: v=31166 instead of the correct v=-1601.
if(v>0) ERROR(v); else SUCCESS(v);
//------------------------------------------------------------------
With these external functions:
extern void ERROR(int16 v);
extern void SUCCESS(int16 v);
extern int16 QUERY(void); // <-- just returns 0
The code should calculate:
slope = 1025
v = -800 * 1025 / 512 = -820000 / 512 = 1601
Instead, it computes v = 31166 which happens to be 32767-1601.
With -O2, the compiler will produce the following assembler code:
This code mis-behaves and calls ERROR(31166).
---------------------------------------
call QUERY
movw r18,r24
subi r18,lo8(-(1025))
sbci r19,hi8(-(1025))
ldi r20,lo8(-800)
ldi r21,hi8(-800)
call __mulhisi3
ldi r18,lo8(512)
ldi r19,hi8(512)
ldi r20,hlo8(512)
ldi r21,hhi8(512)
call __divmodsi4
cp __zero_reg__,r18
cpc __zero_reg__,r19
brlt .+2
rjmp .L33
movw r24,r18
call ERROR
.L34:
......
.L33:
movw r24,r18
call SUCCESS
rjmp .L34
---------------------------------------
With -O0, the compiler generates:
This code works correctly and calls SUCCESS(-1601).
---------------------------------------
call QUERY
subi r24,lo8(-(1025))
sbci r25,hi8(-(1025))
std Y+6,r24
std Y+7,r25
ldd r24,Y+6
ldd r25,Y+7
clr r26
sbrc r25,7
com r26
mov r27,r26
ldi r18,lo8(-800)
ldi r19,hi8(-800)
ldi r20,hlo8(-800)
ldi r21,hhi8(-800)
movw r22,r24
movw r24,r26
call __mulsi3
movw r26,r24
movw r24,r22
ldi r18,lo8(512)
ldi r19,hi8(512)
ldi r20,hlo8(512)
ldi r21,hhi8(512)
movw r22,r24
movw r24,r26
call __divmodsi4
movw r26,r20
movw r24,r18
std Y+8,r24
std Y+9,r25
ldd r24,Y+8
ldd r25,Y+9
cp __zero_reg__,r24
cpc __zero_reg__,r25
brge .L38
ldd r24,Y+8
ldd r25,Y+9
call ERROR
rjmp .L39
.L38:
ldd r24,Y+8
ldd r25,Y+9
call SUCCESS
.L39:
---------------------------------------