Bug 54472 - ICE (spill_failure): unable to find a register to spill in class 'AREG' with -O -fschedule-insns -fselective-scheduling
Summary: ICE (spill_failure): unable to find a register to spill in class 'AREG' with ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Andrey Belevantsev
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2012-09-03 18:04 UTC by Zdenek Sojka
Modified: 2016-01-22 06:58 UTC (History)
2 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build:
Known to work:
Known to fail: 4.4.7, 4.5.4, 4.6.4, 4.7.2, 4.8.0
Last reconfirmed: 2012-10-04 00:00:00


Attachments
reduced testcase (82 bytes, text/x-csrc)
2012-09-03 18:04 UTC, Zdenek Sojka
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zdenek Sojka 2012-09-03 18:04:23 UTC
Created attachment 28125 [details]
reduced testcase

Compiler output:
$ gcc -O -fschedule-insns -fselective-scheduling testcase.c
testcase.c: In function 'main':
testcase.c:6:1: error: unable to find a register to spill in class 'AREG'
 }
 ^
testcase.c:6:1: error: this is the insn:
(insn 9 25 22 2 (parallel [
            (set (reg:DI 2 cx [63])
                (const_int 0 [0]))
            (set (reg/f:DI 5 di [61])
                (plus:DI (ashift:DI (reg:DI 2 cx [63])
                        (const_int 3 [0x3]))
                    (reg/f:DI 1 dx [60])))
            (set (mem/c:BLK (reg/f:DI 1 dx [60]) [0 MEM[(void *)&a]+0 S104 A64])
                (const_int 0 [0]))
            (use (reg:DI 4 si [62]))
            (use (reg:DI 2 cx [63]))
        ]) testcase.c:4 890 {*rep_stosdi_rex64}
     (expr_list:REG_DEAD (reg:DI 4 si [62])
        (expr_list:REG_DEAD (reg/f:DI 1 dx [60])
            (expr_list:REG_UNUSED (reg:DI 2 cx [63])
                (expr_list:REG_UNUSED (reg/f:DI 5 di [61])
                    (nil))))))
testcase.c:6:1: internal compiler error: in spill_failure, at reload1.c:2127
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

(gdb) bt
#0  0x0000000001130b50 in fancy_abort(char const*, int, char const*) ()
#1  0x000000000096d5fb in _fatal_insn(char const*, rtx_def const*, char const*, int, char const*) ()
#2  0x000000000096c6d0 in reload(rtx_def*, int) () at /mnt/svn/gcc-trunk/gcc/reload1.c:2127
#3  0x000000000087eba2 in rest_of_handle_reload() () at /mnt/svn/gcc-trunk/gcc/ira.c:4328
#4  0x000000000090092f in execute_one_pass(opt_pass*) () at /mnt/svn/gcc-trunk/gcc/passes.c:2157
#5  0x0000000000900ce5 in execute_pass_list(opt_pass*) () at /mnt/svn/gcc-trunk/gcc/passes.c:2212
#6  0x0000000000900cf7 in execute_pass_list(opt_pass*) () at /mnt/svn/gcc-trunk/gcc/passes.c:2213
#7  0x00000000006bdd88 in expand_function(cgraph_node*) () at /mnt/svn/gcc-trunk/gcc/cgraphunit.c:1609
#8  0x00000000006bfc2a in compile() () at /mnt/svn/gcc-trunk/gcc/cgraphunit.c:1714
#9  0x00000000006c0225 in finalize_compilation_unit() () at /mnt/svn/gcc-trunk/gcc/cgraphunit.c:2089
#10 0x00000000005a1dc0 in c_write_global_declarations() () at /mnt/svn/gcc-trunk/gcc/c/c-decl.c:10116
#11 0x00000000009e8475 in compile_file() () at /mnt/svn/gcc-trunk/gcc/toplev.c:560
#12 0x00000000009ea03a in toplev_main(int, char**) () at /mnt/svn/gcc-trunk/gcc/toplev.c:1863
#13 0x00007ffff6e784bd in __libc_start_main () from /lib64/libc.so.6
#14 0x0000000000584d01 in _start ()

Tested revisions:
r190830 - crash
4.7 r188682 - crash
4.6 r188682 - crash
4.5 r188682 - crash
4.4 r188682 - crash
Comment 1 Uroš Bizjak 2012-09-03 18:24:59 UTC
This is the problem with scheduler, where insns involving hard registers are moved around. This part should be fixed by the WIP patch at [1].

[1] http://gcc.gnu.org/ml/gcc-patches/2012-08/msg00810.html
Comment 2 Uroš Bizjak 2012-09-04 14:48:02 UTC
For some reason, -fselective-scheduling is moving

(insn 19 16 22 2 (use (reg/i:SI 0 ax)) testcase.c:6 -1
     (nil))

around. This insn marks function return, so IMO should be at the function exit all the time. -fschedule-insns (without -fselective-scheduling) leaves the insn at the function exit. Is it OK to move this marker around?
Comment 3 Andrey Belevantsev 2012-09-04 17:47:24 UTC
(In reply to comment #2)
> For some reason, -fselective-scheduling is moving
> 
> (insn 19 16 22 2 (use (reg/i:SI 0 ax)) testcase.c:6 -1
>      (nil))
> 
> around. This insn marks function return, so IMO should be at the function exit
> all the time. -fschedule-insns (without -fselective-scheduling) leaves the insn
> at the function exit. Is it OK to move this marker around?

I will take a look but I'm out of office until Friday at least (maybe Monday).
Comment 4 Uroš Bizjak 2012-10-04 09:29:15 UTC
(In reply to comment #3)
> > For some reason, -fselective-scheduling is moving
> > 
> > (insn 19 16 22 2 (use (reg/i:SI 0 ax)) testcase.c:6 -1
> >      (nil))
> > 
> > around. This insn marks function return, so IMO should be at the function exit
> > all the time. -fschedule-insns (without -fselective-scheduling) leaves the insn
> > at the function exit. Is it OK to move this marker around?
> 
> I will take a look but I'm out of office until Friday at least (maybe Monday).

Any progress on this?
Comment 5 Andrey Belevantsev 2012-10-04 12:43:36 UTC
(In reply to comment #4)
> (In reply to comment #3)
> > > For some reason, -fselective-scheduling is moving
> > > 
> > > (insn 19 16 22 2 (use (reg/i:SI 0 ax)) testcase.c:6 -1
> > >      (nil))
> > > 
> > > around. This insn marks function return, so IMO should be at the function exit
> > > all the time. -fschedule-insns (without -fselective-scheduling) leaves the insn
> > > at the function exit. Is it OK to move this marker around?
> > 
> > I will take a look but I'm out of office until Friday at least (maybe Monday).
> 
> Any progress on this?

Sorry Uros, I forgot about this.  I took a look, the reason is actually in selective scheduler not handling implicit_sets (we miss dependencies between implicit_sets register sets and other sets/clobbers).  In this example, we miss a dependency between insns 9 and 16 and thus schedule insn #16 earlier than insn #9 and then its dependent insn #19 earlier than insn #9.  Thus we are moving the return mark before the actual function code.

The below patch fixes the test case for me.  I need to double-check whether I have caught all cases of implicit_sets generating dependencies in sched-deps.c and then I will submit the patch for review.

diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index e7ca3f1..0fbfdbe 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -3185,7 +3185,7 @@ has_dependence_note_reg_set (int regno)
          || reg_last->clobbers != NULL)
        *dsp = (*dsp & ~SPECULATIVE) | DEP_OUTPUT;

-      if (reg_last->uses)
+      if (reg_last->uses || reg_last->implicit_sets)
        *dsp = (*dsp & ~SPECULATIVE) | DEP_ANTI;
     }
 }
@@ -3205,7 +3205,7 @@ has_dependence_note_reg_clobber (int regno)
       if (reg_last->sets)
        *dsp = (*dsp & ~SPECULATIVE) | DEP_OUTPUT;

-      if (reg_last->uses)
+      if (reg_last->uses || reg_last->implicit_sets)
        *dsp = (*dsp & ~SPECULATIVE) | DEP_ANTI;
     }
 }
Comment 6 Igor Zamyatin 2012-10-24 11:09:49 UTC
Have you managed to check the patch?
Comment 7 Andrey Belevantsev 2012-10-26 14:04:03 UTC
(In reply to comment #6)
> Have you managed to check the patch?

The patch does the right thing for sets and clobbers, but the uses case should be amended, too, judging from the sched-deps.c code.   Sorry, I was too busy to send the patch, now, I'll try doing this on the next week.
Comment 8 Andrey Belevantsev 2012-11-09 12:28:30 UTC
Author: abel
Date: Fri Nov  9 12:28:21 2012
New Revision: 193358

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=193358
Log:
	PR rtl-optimization/54472

	* sel-sched-ir.c (has_dependence_note_reg_set): Handle implicit sets.
	(has_dependence_note_reg_clobber,
	has_dependence_note_reg_use): Likewise.
    
	* gcc.dg/pr54472.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr54472.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/sel-sched-ir.c
    trunk/gcc/testsuite/ChangeLog
Comment 9 Andrey Belevantsev 2012-11-09 12:33:33 UTC
Fixed on trunk, backports to 4.7/4.6 are needed.
Comment 10 Marek Polacek 2013-04-03 14:53:36 UTC
So are we going to backport this one?
Comment 11 Andrey Belevantsev 2013-04-03 15:51:50 UTC
(In reply to comment #10)
> So are we going to backport this one?

Sorry, I've missed this one when backporting other stuff. I can do this tomorrow, the patch is safe. However, the branch is frozen now, we need to ask Richi for approval to squeeze it into the next 4.7 release.
Comment 12 Andrey Belevantsev 2016-01-22 06:58:34 UTC
4.7 is not maintained anymore.