This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
sparc inlining-sibcall crash (regression from 2.95.2)
- To: gcc at gcc dot gnu dot org
- Subject: sparc inlining-sibcall crash (regression from 2.95.2)
- From: Dan Nicolaescu <dann at godzilla dot ICS dot UCI dot EDU>
- Date: Tue, 01 May 2001 12:00:20 -0700
Hi!
The following small program crashes the compiler (both mainline and
branch) when compiled with -O3
(or with less optimizations turned one: -O1 -foptimize-sibling-calls -finline-functions)
on sun-sparc-solaris2.7
It works just fine with 2.95.2
(A more complex version of this can be found in GNATS c/2675)
void f1 (double);
void f2 (int);
static void
foo (double xx, int type)
{
f1 (xx);
f2 (type);
}
void
bar (void)
{
foo (1.0, 1);
}
gcc -O1 -foptimize-sibling-calls -finline-functions -S range.i
range.i: In function `bar':
range.i:16: Unrecognizable insn:
(insn/i 24 21 25 (set (reg:DF 24 %i0)
(reg/v:SI 109)) -1 (insn_list 13 (nil))
(expr_list:REG_DEAD (reg/v:SI 109)
(expr_list:REG_EQUAL (const_int 1 [0x1])
(nil))))
range.i:16: Internal compiler error in extract_insn, at recog.c:2275
Please submit a full bug report, with preprocessed source if appropriate.
See <URL:http://www.gnu.org/software/gcc/bugs.html> for instructions.
Sparc doesn't have an insn to set a floating point register from an
integer one, so this seems legit.
The insn gets created in optimize_sibling_and_tail_recursive_calls
Here is a gdb session showing that:
(gdb) r
Breakpoint 4, optimize_sibling_and_tail_recursive_calls ()
at ../../gcc/gcc/sibcall.c:501
501 insns = get_insns ();
(gdb) c
Continuing.
Breakpoint 5, replace_call_placeholder (insn=0x38cf40, use=sibcall_use_normal)
at ../../gcc/gcc/sibcall.c:461
461 if (use == sibcall_use_tail_recursion)
This first call to replace_call_placeholder deals with the "f1" call.
(gdb) c
Continuing.
Breakpoint 5, replace_call_placeholder (insn=0x38d000, use=sibcall_use_sibcall)
at ../../gcc/gcc/sibcall.c:461
461 if (use == sibcall_use_tail_recursion)
(gdb) n
463 else if (use == sibcall_use_sibcall)
(gdb) n
464 emit_insns_before (XEXP (PATTERN (insn), 1), insn);
(gdb) step
emit_insns_before (insn=0x3d46c0, before=0x38d000)
at ../../gcc/gcc/emit-rtl.c:3285
3285 emit_block_insn_after (pattern, after, block)
(gdb) p insn
$105 = 0x3d46c0
(gdb) pr
(insn/i 24 0 25 (set (reg:DF 24 %i0)
(reg/v:SI 109)) -1 (nil)
(nil))
(gdb) p before
$106 = 0x38d000
(gdb) pr
(call_insn/i 27 21 29 (call_placeholder 22 24 0 0 (call_insn/i 23 22 0 (parallel[
(call (mem:SI (symbol_ref:SI ("f2")) 0)
(const_int 0 [0x0]))
(clobber (reg:SI 15 %o7))
] ) -1 (nil)
(nil)
(expr_list (use (reg:SI 8 %o0))
(nil)))) -1 (nil)
(nil)
(nil))
So the bad insn is created by
emit_insns_before (XEXP (PATTERN (insn), 1), insn);
and it's XEXP (PATTERN (insn), 1)
Is the "call_placeholder" dump complete? Should this insn appear
there? Even setting debug_call_placeholder_verbose to 1 (in
print_rtl) does not show it.
It seems that that call_placeholder for "f2" is not constructed
correctly. That's about how far I could go... Can somebody that
understands more about inlining and sibcalls take a look at it?
Thanks.
--dan