This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

sparc inlining-sibcall crash (regression from 2.95.2)


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);

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])
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:> 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

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

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)
(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)
        (expr_list (use (reg:SI 8 %o0))
            (nil)))) -1 (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? 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]