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: unassig...@gcc.gnu.org ReportedBy: wwie...@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: ---------------------------------------