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
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
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?
(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).
(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?
(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; } }
Have you managed to check the patch?
(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.
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
Fixed on trunk, backports to 4.7/4.6 are needed.
So are we going to backport this one?
(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.
4.7 is not maintained anymore.