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.
Subject: Bug 37466 Author: aesok Date: Fri Sep 12 16:45:34 2008 New Revision: 140321 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=140321 Log: PR target/37466 * config/avr/avr.md (movsi_lreg_const peephole2): Add match_dup for scratch register after 'set' pattern. Modified: trunk/gcc/ChangeLog trunk/gcc/config/avr/avr.md
Subject: Bug 37466 Author: aesok Date: Fri Sep 12 17:29:38 2008 New Revision: 140323 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=140323 Log: PR target/37466 * config/avr/avr.md (movsi_lreg_const peephole2): Add match_dup for scratch register after 'set' pattern. Modified: branches/gcc-4_3-branch/gcc/ChangeLog branches/gcc-4_3-branch/gcc/config/avr/avr.md
Fixed.
*** Bug 39593 has been marked as a duplicate of this bug. ***