When channel.i from stress-1.17 is compiled with options: -O2 -m4 -fnew-ra the following error occurs: /home/tm/stress-1.17/channel.i: In function `find_channel': /home/tm/stress-1.17/channel.i:8226: internal compiler error: in pur 22 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. Program exited with code 01.
Created attachment 4205 [details] testcase
GDB dump of basic blocks at abort point: (gdb) print *bb $2 = {head = 0x404aa898, end = 0x404aaa7c, head_tree = 0x0, end_tree succ = 0x0, local_set = 0x0, cond_local_set = 0x0, global_live_at_ global_live_at_end = 0x843ca40, aux = 0x2, index = 0, prev_bb = 0x next_bb = 0x838a870, loop_depth = 0, loop_father = 0x8496dd8, coun flags = 5} (gdb) print bb->succ $3 = 0x0 (gdb) call debug_bb(bb) ;; Basic block 0, loop depth 0, count 0 ;; Registers live at start: 4 [r4] 5 [r5] 14 [r14] 15 [r15] 145 [ap] (note:HI 38 2 46 0 [bb 0] NOTE_INSN_BASIC_BLOCK) (insn/f 46 38 47 0 (set (mem:SI (pre_dec:SI (reg/f:SI 15 r15)) [0 S4 (reg/f:SI 14 r14)) -1 (nil) (expr_list:REG_INC (reg/f:SI 15 r15) (nil))) (insn/f 47 46 48 0 (set (reg/f:SI 14 r14) (reg/f:SI 15 r15)) -1 (nil) (nil)) (note 48 47 3 0 NOTE_INSN_PROLOGUE_END) (note:HI 3 48 4 0 NOTE_INSN_DELETED) (note:HI 4 3 5 0 NOTE_INSN_DELETED) (note:HI 5 4 12 0 NOTE_INSN_FUNCTION_BEG) (note:HI 12 5 13 0 NOTE_INSN_DELETED) (note:HI 13 12 16 0 NOTE_INSN_DELETED) (insn:HI 16 13 17 0 (set (reg:SI 1 r1 [165]) (symbol_ref:SI ("hash_find_channel") [flags 0x41] <function_ nnel>)) 123 {movsi_ie} (nil) (nil)) (call_insn/j:HI 17 16 44 0 (parallel [ (call (mem:SI (reg:SI 1 r1 [165]) [0 S4 A32]) (const_int 0 [0x0])) (use (reg:PSI 151 fpscr)) (return) ]) 177 {sibcalli} (insn_list 16 (nil)) (nil) (expr_list (use (reg:SI 5 r5 [ chptr ])) (expr_list (use (reg:SI 4 r4 [ chname ])) (nil)))) (insn 44 17 18 0 (use (reg/i:SI 0 r0 [ <result> ])) -1 (insn_list 17 (nil)) ;; Registers live at end: 0 [r0] 14 [r14] 15 [r15] 145 [ap] 151 [] ;; Successors: (gdb)
The CFG code gets confused by the addition of a USE insn after a sibcall. Sibcalls are supposed to end the block (and the function!), so the fact that we have an instruction following one (even if its fake) is confusing. Moreover, I can't figure out why the USE is being added at all. There is a non-explanation in ra.c, but if I change like so, the test case passes. r~ Index: ra.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/ra.c,v retrieving revision 1.8 diff -c -p -d -u -r1.8 ra.c --- ra.c 7 Mar 2003 22:06:16 -0000 1.8 +++ ra.c 11 Jun 2003 22:43:10 -0000 @@ -677,7 +677,7 @@ reg_alloc () /* We currently rely on the existence of the return value USE as one of the last insns. Add it if it's not there anymore. */ - if (last) + if (0 && last) { edge e; for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
Subject: Re: new-ra bug On 11 Jun 2003, rth@gcc.gnu.org wrote: > Moreover, I can't figure out why the USE is being added at all. Crappy obsolete design ;-) I didn't use mark_regs_live_at_end() to force the return register live at the end, partly because I can basically only deal with real register references (the flow.c code simply sets some bits in the liveness bitmaps). But it needs to be made live somehow, hence I simply added such fake uses. In the new-ra branch I added code to delete these instructions after allocation again. (Or rather I would have had, had I committed ;( ). Like the below patch. It also fixes the testcase. Somewhen I need to go over this again, to use something similar to the mark_regs_live_at_end() function, because this method is bound to break (for instance I only add the return value use, but not all the other regs which that function might add). Index: ra.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/ra.c,v retrieving revision 1.8 diff -u -p -r1.8 ra.c --- ra.c 7 Mar 2003 22:06:16 -0000 1.8 +++ ra.c 12 Jun 2003 06:06:03 -0000 @@ -669,6 +669,7 @@ reg_alloc () int changed; FILE *ra_dump_file = rtl_dump_file; rtx last = get_last_insn (); + bitmap use_insns = BITMAP_XMALLOC (); if (! INSN_P (last)) last = prev_real_insn (last); @@ -686,11 +687,13 @@ reg_alloc () last = bb->end; if (!INSN_P (last) || GET_CODE (PATTERN (last)) != USE) { - rtx insns; + rtx insn, insns; start_sequence (); use_return_register (); insns = get_insns (); end_sequence (); + for (insn = insns; insn; insn = NEXT_INSN (insn)) + bitmap_set_bit (use_insns, INSN_UID (insn)); emit_insn_after (insns, last); } } @@ -868,6 +871,22 @@ reg_alloc () no_new_pseudos = 1; rtl_dump_file = ra_dump_file; + { + edge e; + for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next) + { + basic_block bb = e->src; + last = bb->end; + for (last = bb->end; last; last = PREV_INSN (last)) + { + if (last == bb->head) + break; + if (bitmap_bit_p (use_insns, INSN_UID (last))) + delete_insn (last); + } + } + } + BITMAP_XFREE (use_insns); /* Some spill insns could've been inserted after trapping calls, i.e. at the end of a basic block, which really ends at that call. Fixup that breakages by adjusting basic block boundaries. */
Here's a simpler testcase: int foo(char *p1) { return bar(p1); } I swear to god that's what it boiled down to. This fails with /usr/gcc-3.4-20030903-glibc-2.3.2/bin/sh4-unknown-linux-gnu-gcc -O2 -m4 -fnew-ra z.c z.c: In function `foo': z.c:4: error: Abnormal edges for no purpose in bb 0 z.c:4: internal compiler error: verify_flow_info failed
For completeness, here's a log using the original testcase: /usr/gcc-3.4-20030903-glibc-2.3.2/bin/sh4-unknown-linux-gnu-gcc -m4 -O2 -fnew-ra channel.i channel.i: In function `find_channel': channel.i:8226: error: Abnormal edges for no purpose in bb 0 channel.i:8226: internal compiler error: verify_flow_info failed This appears to be a dup of bug 9900
*** Bug 9900 has been marked as a duplicate of this bug. ***
This ICE seemed to go away when I apply the fix for bug 11587. Can someone else verify this?
I've prepared a patch to add a testcase for this PR to the testsuite; see http://www.kegel.com/crosstool/current/patches/gcc-3.3.1/pr11162-1-test.patch I'll submit it to gcc-patches in a couple days if nobody squawks.
Daniel, can you verify if this is now fixed?
I just verified it's not fixed in gcc-3.3-20040119 (didn't expect it to be). I'll verify against a current gcc-3.4 snapshot next...
Dang, lost my hardware before I could verify it. I can't test on sh4 anymore.
new-ra bug, so SUSPENDING.
Closing as wiill not fix as new-ra was removed from the mainline.