public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/37466]  New: [AVR] avr-gcc generating incorrect assembly for expression with the long constant operands
@ 2008-09-10 19:31 aesok at gcc dot gnu dot org
  2008-09-10 19:35 ` [Bug target/37466] " aesok at gcc dot gnu dot org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: aesok at gcc dot gnu dot org @ 2008-09-10 19:31 UTC (permalink / raw)
  To: gcc-bugs

Reported by geckosenator on avrfreaks.net


Code:

int sat; 

static volatile long data[3]; 
static volatile int datacount[3]; 

static volatile int chan; 
static volatile long val; 

int __attribute__((always_inline)) transfer(int data) 
{ 
   return (*(int *)((0x00))); 
} 

int init_status; 

long read_scale(void) 
{ 
   long val; 
   if(init_status) 
      val |= (long)transfer(0) << 16; 
   val |= (long)transfer(0) << 8; 
   return val; 
} 

void get_mode(int *mode, int *psw) 
{ 
    int val = transfer(0); 
    *psw = val & 0x10 ? 1 : 0; 
} 

long __attribute__((always_inline)) read_data(void) 
{ 
   long val; 

   val <<= 8; 
   if(init_status) 
      val |= transfer(0); 

   return val - 0x80; 
} 

void function1() 
{ 
    long data2 = read_data(); 
    sat = (data2 > 1) || (data2 < -100); 
    val += data2; 
    data[chan] += val; 
    datacount[chan] ++; 
} 

void function2(long *data) 
{ 
    int i, j; 
    data[i] += i + j; 
} 




Compile with: 

Code:

avr-gcc -std=gnu99 -fgnu89-inline -Os -mmcu=at90usb1287 -c testcase.c -o
testcase.S -S 



Then look in testcase.S for: 

Code:

.L16: 
   ldi r16,lo8(-128) 
   mov r14,r16 
   ldi r16,hi8(-128) 
   mov r15,r16 
   ldi r16,hlo8(-128) 
   mov r16,r16    <-----  bad, this does nothing! 
   ldi r16,hhi8(-128) <-- nice, we just clobbered r16 
   mov r17,r16 
   add r14,r18 
   adc r15,r19 
   adc r16,r20 
   adc r17,r21 
   sts (sat)+1,__zero_reg__ 



It looks like the compiler got confused and tried to use r16 in two different
ways at the same time. 


The bug occurs in peephole optmisation. Here avr-gcc looks for a spare register
R16-R31 that it can use to load a constant value into operands which are
located in lower register (R2-R15). 

The test for "spare" occurred before instruction. So if the instruction
happened to use that register (because it was spare), bad things
happen.Typically this will happen with long - or long long registers.


-- 
           Summary: [AVR] avr-gcc generating incorrect assembly for
                    expression with the long constant operands
           Product: gcc
           Version: 4.2.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: aesok at gcc dot gnu dot org
GCC target triplet: avr-*-*


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37466


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-04-06 22:38 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-10 19:31 [Bug target/37466] New: [AVR] avr-gcc generating incorrect assembly for expression with the long constant operands aesok at gcc dot gnu dot org
2008-09-10 19:35 ` [Bug target/37466] " aesok at gcc dot gnu dot org
2008-09-12 16:48 ` aesok at gcc dot gnu dot org
2008-09-12 17:32 ` aesok at gcc dot gnu dot org
2008-09-12 17:38 ` aesok at gcc dot gnu dot org
2009-04-06 22:38 ` eric dot weddington at atmel dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).