Bug 60040

Summary: AVR: error: unable to find a register to spill in class 'POINTER_REGS'
Product: gcc Reporter: Sebastian Huber <sebastian.huber>
Component: otherAssignee: Senthil Kumar Selvaraj <saaadhu>
Status: RESOLVED FIXED    
Severity: normal CC: amylaar, gjl, joel
Priority: P3 Keywords: ice-on-valid-code
Version: 4.8.3   
Target Milestone: 7.0   
Host: Target: avr
Build: Known to work:
Known to fail: 4.8.3, 4.9.0 Last reconfirmed: 2014-02-18 00:00:00
Bug Depends on:    
Bug Blocks: 56183    
Attachments: Test case.
tentative patch for tentative reloads
Second testcase, needs -Os to break
Modified patch which clears failure

Description Sebastian Huber 2014-02-03 11:13:13 UTC
avr-rtems4.11-gcc -fpreprocessed -w -mmcu=atmega128 -O2 -s test.i -o /dev/null
test.i: In function 'rtems_fdisk_recycle_segment':
test.i:107:1: error: unable to find a register to spill in class 'POINTER_REGS'
 }
 ^
test.i:107:1: error: this is the insn:
(insn 30 29 31 2 (set (reg:HI 26 r26)
        (reg/v/f:HI 51 [ dpd ])) test.i:95 82 {*movhi}
     (nil))
test.i:107: confused by earlier errors, bailing out
Comment 1 Sebastian Huber 2014-02-03 11:13:45 UTC
Created attachment 32024 [details]
Test case.
Comment 2 Georg-Johann Lay 2014-02-17 16:41:14 UTC
Seems like PR58545

*** This bug has been marked as a duplicate of bug 58545 ***
Comment 3 Sebastian Huber 2014-02-18 08:12:08 UTC
With avr-rtems4.11-gcc (GCC) 4.9.0 20140218 (experimental) I still get the error:

avr-rtems4.11-gcc -fpreprocessed -w -mmcu=atmega128 -O2 -s test.i -o /dev/null
test.i: In function 'rtems_fdisk_recycle_segment':
test.i:107:1: error: unable to find a register to spill in class 'POINTER_REGS'
 }
 ^
test.i:107:1: error: this is the insn:
(insn 30 29 31 2 (set (reg:HI 26 r26)
        (reg/v/f:HI 51 [ dpd ])) test.i:95 82 {*movhi}
     (nil))
test.i:107:1: internal compiler error: in spill_failure, at reload1.c:2106
0x825135 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
        /home/sh/archive/gcc-git/gcc/rtl-error.c:109
0x81a888 spill_failure
        /home/sh/archive/gcc-git/gcc/reload1.c:2106
0x81a888 find_reload_regs
        /home/sh/archive/gcc-git/gcc/reload1.c:2032
0x8230a7 select_reload_regs
        /home/sh/archive/gcc-git/gcc/reload1.c:2052
0x8230a7 reload(rtx_def*, int)
        /home/sh/archive/gcc-git/gcc/reload1.c:973
0x72c04d do_reload
        /home/sh/archive/gcc-git/gcc/ira.c:5469
0x72c04d rest_of_handle_reload
        /home/sh/archive/gcc-git/gcc/ira.c:5598
0x72c04d execute
        /home/sh/archive/gcc-git/gcc/ira.c:5627
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.

The output is different though.
Comment 4 Georg-Johann Lay 2014-02-18 10:50:18 UTC
Confirmed on current 4.9 trunk from 2014-02-18 (SVN 207837).
Comment 5 Jorn Wolfgang Rennecke 2014-03-17 12:38:47 UTC
Created attachment 32372 [details]
tentative patch for tentative reloads

In this case, reload already knows that it has to re-do the reloads, but it
goes ahead anyway and computes reloads registers for this iteration.
Unfortunately, when find_reload_regs fails, it then calls spill_failure,
giving a hard error for a reload that we don't need in the first place.

The patch in this attachment passes down something_changed from reload
as tentative to select_reload_regs and then on to find_reload_regs to
not worry about the failure.
Also, in reload, I made it not 'goto failure' in that case.
Comment 6 Sebastian Huber 2014-04-07 13:19:16 UTC
GCC 4.9.0 20140407 with the proposed patch fixes the problem for me.
Comment 7 Joel Sherrill 2014-11-05 16:19:41 UTC
Was the proposed patch ever committed so this can be closed?
Comment 8 Matthijs Kooijman 2015-10-13 12:55:25 UTC
Seems not - just tried with avr-gcc 5.1 and it is still broken:

$ avr-gcc -fpreprocessed -w -mmcu=atmega128 -O2 -s test.i -o /dev/null
        test.i: In function 'rtems_fdisk_recycle_segment':
        test.i:107:1: error: unable to find a register to spill in class 'POINTER_REGS'
         }
         ^
        test.i:107:1: error: this is the insn:
        (insn 30 29 31 2 (set (reg:HI 26 r26)
                (reg/v/f:HI 51 [ dpd ])) /home/matthijs/test.i:95 83 {*movhi}
             (nil))
        test.i:107: confused by earlier errors, bailing out

$ avr-gcc --version
        avr-gcc (GCC) 5.1.0
        Copyright (C) 2015 Free Software Foundation, Inc.
        This is free software; see the source for copying conditions.  There is NO
        warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

On the Arduino bugtracker [1], another testcase with the same symptoms was
reported. I'm attaching that here. This testcase works with -O2, but
breaks when -Os is used.

$ avr-gcc -c -Os  -mmcu=atmega328p  test2.c -o /dev/null

        test2.c: In function 'getSlope':
        test2.c:22:1: error: unable to find a register to spill in class 'POINTER_REGS'
         }
         ^
        test2.c:22:1: error: this is the insn:
        (insn 40 38 42 3 (set (reg:SF 63 [ D.1613 ])
                (mem:SF (post_inc:HI (reg:HI 16 r16 [orig:73 ivtmp.13 ] [73])) [1 MEM[base: _27, offset: 0B]+0 S4 A8])) /home/matthijs/test.c:15 100 {*movsf}
             (expr_list:REG_INC (reg:HI 16 r16 [orig:73 ivtmp.13 ] [73])
                (nil)))
        test2.c:22: confused by earlier errors, bailing out

[1]: https://github.com/arduino/Arduino/issues/3972
Comment 9 Matthijs Kooijman 2015-10-13 12:56:23 UTC
Created attachment 36499 [details]
Second testcase, needs -Os to break
Comment 10 Ambroz Bizjak 2016-01-12 19:10:54 UTC
I've been getting this error on some complex code of mine (for atmga2560). I tried the attached patch on gcc 5.3. While it resolves the original compile error, I then get an error from the linker, an undefined reference to the same function that the original error was related to. So I think something is wrong with the patch.
Comment 11 Ambroz Bizjak 2016-01-12 20:04:31 UTC
Created attachment 37320 [details]
Modified patch which clears failure

I made a wild guess that the issue is that the "failure" is not cleared, so I modified the patch (by hand), to clear "failure" after an ignored failure. With this my code compiles and links.
Comment 12 Bernd Schmidt 2016-04-29 08:59:41 UTC
Author: bernds
Date: Fri Apr 29 08:59:09 2016
New Revision: 235625

URL: https://gcc.gnu.org/viewcvs?rev=235625&root=gcc&view=rev
Log:
avr-related reload fix from Senthil Kumar Selvaraj

	PR target/60040
	* reload1.c (reload): Call finish_spills before
	restarting reload loop. Skip select_reload_regs
	if update_eliminables_and_spill returns true.

testsuite/
	PR target/60040
	* gcc.target/avr/pr60040-1.c: New.
	* gcc.target/avr/pr60040-2.c: New.

Added:
    trunk/gcc/testsuite/gcc.target/avr/pr60040-1.c
    trunk/gcc/testsuite/gcc.target/avr/pr60040-2.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/reload1.c
    trunk/gcc/testsuite/ChangeLog
Comment 13 Senthil Kumar Selvaraj 2016-10-24 10:30:32 UTC
Fixed in trunk (7.0)