This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/52474] New: Regression: AVR-GCC: arithmetics produce completely wrong result


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:
---------------------------------------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]