Hi, I have observed a wrong code bug that I judge to be so serious that IMHO one should discourage use of the avr port for 4.x.x until it is resolved. Unfortunately the bug showed up in a deeply embedded code segment of *really* confidential code owned by my employer. I unfortunately cannot pass the test case I am having to the public. I am working hard for reproducing the bug in a non-confidential stripped file. Meanwhile, I have the following diagnosis: ( I, know that this will be difficult, but maybe someone could never the less give me an indication already on this base.) 1.) Background info for those not too familiar with the AVR port: AVR uses the hard reg 28 (also called Y-Register) as frame pointer, when necessary. If a pseudo happens to end up on a stack slot and needs to be loaded into a register of class POINTER_REG (one of the hard regs 26 (reg X), 28 (reg Y) or 30(reg Z)), reload sometimes generates code where the frame pointer 28 (reg Y) itself is used as spill register. GCC, however, still uses the Y register as frame pointer and does not recognize that it no longer points to the stack. 2.) Description of the bug: Excerpt from the debugging dump originating from the reload pass for my testcase (test.c.23.greg): Reload 0: reload_in (HI) = (reg/v/f:HI 65 [ pointer_to_next_C ]) reload_out (HI) = (reg/v/f:HI 65 [ pointer_to_next_C ]) POINTER_REGS, RELOAD_OTHER (opnum = 1) reload_in_reg: (reg/v/f:HI 65 [ pointer_to_next_C ]) reload_out_reg: (reg/v/f:HI 65 [ pointer_to_next_C ]) reload_reg_rtx: (reg:HI 28 r28) The corresponding asm output reads (Problem case plus part of the prologue for illustration. descriptive comments added by me): ;; Section of the prologue allocating space on the stack for a HImode ;; variable. in r28,__SP_L__ in r29,__SP_H__ sbiw r28,2 in __tmp_reg__,__SREG__ cli out __SP_H__,r29 out __SREG__,__tmp_reg__ out __SP_L__,r28 ;; Stack pointer and frame pointer r28:r29 are now increased by 2 for ;; making place for a pointer variable. Y+1 and Y+2 point to the ;; lsb and the msb of this pointer variable. ... some complicated code ... ;; Now the variable on the stack slot is needed in a spill register ;; of class "pointer registers" (i.e. r26-r31). ;; GCC chooses to use the Frame pointer r28 as spill register. ;; r28 is overwritten by the value of the variable on the stack ;; (GCC uses special pattern for loading Y from an address Y is ;; pointing to by use of the tmp reg. ldd __tmp_reg__,Y+1 ldd r29,Y+2 mov r28,__tmp_reg__ ; Now the frame pointer no longer points to the stack! ; Use Y for accessing the memory the pointer variable on the stack ; points to. ld r18,Y+ ld r19,Y+ ld r20,Y+ ld r21,Y+ ;; GCC now assumes that it could write Y back to the stack ;; by the following two commands. BUG!!! Also all of the subsequent ;; Accesses to the stack by the frame pointer will fail. std Y+2,r29 std Y+1,r28 The bug exists already in January 05 and in today's head 4.1. It was present in all of the intermediate snapshots I have analyzed so far. I was able to reproduce the problem identically on a cygwin-woe200 host, an i386-linux host and an amd64-linux host. I am working hard to reduce the test case so that it will be possible for me to post it here. Meanwhile, I'd appreciate very much any advice on where to look for the origin. Yours, Björn -- Summary: Wrong code for 4.0 and head: Reload clobbers the frame pointer by using it as spill register without recognizing the clobbering Product: gcc Version: 4.0.0 Status: UNCONFIRMED Severity: critical Priority: P2 Component: middle-end AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bjoern dot m dot haase at web dot de CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: cygwin-x86 and linux-x86 GCC host triplet: cygwin-x86 and linux-x86 GCC target triplet: avr-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21990