== C source == typedef unsigned char uint8_t; typedef unsigned int uint16_t; extern uint8_t f1 (const uint8_t*); extern void f2 (uint8_t*, uint8_t); void func (uint16_t parameter, uint8_t *addr, uint8_t data) { uint8_t status; status = f1 (addr + 8); addr++; if (*addr == parameter + 8) *addr = parameter; f2 (addr, data); f2 (addr + 8, status + 1); } == Command line == $ avr-gcc bug.c -S -Os -mmcu=atmega8 bug.c: In function 'func': bug.c:20:1: error: unable to find a register to spill in class 'POINTER_REGS' } ^ bug.c:20:1: error: this is the insn: (insn 37 15 16 2 (set (reg:QI 20 r20) (mem/c:QI (plus:HI (reg/f:HI 28 r28) (const_int 1 [0x1])) [3 S1 A8])) bug.c:15 70 {movqi_insn} (nil)) bug.c:20:1: internal compiler error: in spill_failure, at reload1.c:2123 bug.c:20:1: internal compiler error: Segmentation fault == configure == Configured with: ../../gcc.gnu.org/trunk/configure --target=avr --prefix=/local/gnu/install/gcc-4.8-mingw32 --host=i386-mingw32 --build=i686-linux-gnu --enable-languages=c,c++ --disable-nls --disable-shared --with-dwarf2 == Notes == The compile passes with -fno-caller-saves
Created attachment 30906 [details] bug.c C source code
Assuming 4.9 doesn't work either.
Instruction 37 is generated by save_call_clobbered_regs. When the eliminable registers were initialized, the frame size was zero, and the frame pointer could be eliminated. The frame size grew when the save area for r20 was allocated, but reload does not update the eliminable registers in this case. Therefore, the frame pointer r28 was eliminated to the stack pointer in insn 37. Thus, finding reloads and spilling finished with insn 37 using the stack pointer and needing a POINTER_REGS reload. Then, before it comes to selecting the reload registers, the eliminables are updated, but not the reloads that depend on them. Thus, we try - unnecessarily - to reload the frame pointer, and can't because r28 is in use as the frame pointer.
Created attachment 30951 [details] patch currently under test
Author: amylaar Date: Wed Oct 30 23:55:46 2013 New Revision: 204234 URL: http://gcc.gnu.org/viewcvs?rev=204234&root=gcc&view=rev Log: gcc: PR other/58545 * reload1.c (update_eliminables_and_spill): New function, broken out of reload. (reload): Use it. Check for frame size change after frame size alignment, and call update_eliminables_and_spill first if continue-ing. gcc/testsuite: PR other/58545 * gcc.target/avr/pr58545.c: New test. Added: trunk/gcc/testsuite/gcc.target/avr/pr58545.c Modified: trunk/gcc/ChangeLog trunk/gcc/reload1.c trunk/gcc/testsuite/ChangeLog
I assume fixed on trunk.
*** Bug 60040 has been marked as a duplicate of this bug. ***
The 4.7 branch is being closed, moving target milestone to 4.8.4.
GCC 4.8.4 has been released.
Fixed for 4.9.0.