Commit 206604dc by Jakub Jelinek Committed by Jakub Jelinek

re PR debug/55094 (ICE in maybe_record_trace_start, at dwarf2cfi.c:2224)

	PR middle-end/55094
	* builtins.c (expand_builtin_trap): Add REG_ARGS_SIZE note
	on the trap insn for !ACCUMULATE_OUTGOING_ARGS.
	* cfgcleanup.c (outgoing_edges_match): Don't look at debug insns
	on the first old_insns_match_p call.  For !ACCUMULATE_OUTGOING_ARGS
	fail if the last real insn doesn't have REG_ARGS_SIZE note.

	* gcc.dg/pr55094.c: New test.

From-SVN: r193649
parent 1b845c6e
2012-11-20 Jakub Jelinek <jakub@redhat.com>
PR middle-end/55094
* builtins.c (expand_builtin_trap): Add REG_ARGS_SIZE note
on the trap insn for !ACCUMULATE_OUTGOING_ARGS.
* cfgcleanup.c (outgoing_edges_match): Don't look at debug insns
on the first old_insns_match_p call. For !ACCUMULATE_OUTGOING_ARGS
fail if the last real insn doesn't have REG_ARGS_SIZE note.
PR rtl-optimization/54921
* cselib.h (fp_setter_insn): New prototype.
* cselib.c (fp_setter_insn): New function.
......@@ -4666,7 +4666,14 @@ expand_builtin_trap (void)
{
#ifdef HAVE_trap
if (HAVE_trap)
emit_insn (gen_trap ());
{
rtx insn = emit_insn (gen_trap ());
/* For trap insns when not accumulating outgoing args force
REG_ARGS_SIZE note to prevent crossjumping of calls with
different args sizes. */
if (!ACCUMULATE_OUTGOING_ARGS)
add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
}
else
#endif
emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
......
/* Control flow optimization code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011,
2012 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -1702,9 +1702,15 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
}
}
rtx last1 = BB_END (bb1);
rtx last2 = BB_END (bb2);
if (DEBUG_INSN_P (last1))
last1 = prev_nondebug_insn (last1);
if (DEBUG_INSN_P (last2))
last2 = prev_nondebug_insn (last2);
/* First ensure that the instructions match. There may be many outgoing
edges so this test is generally cheaper. */
if (old_insns_match_p (mode, BB_END (bb1), BB_END (bb2)) != dir_both)
if (old_insns_match_p (mode, last1, last2) != dir_both)
return false;
/* Search the outgoing edges, ensure that the counts do match, find possible
......@@ -1713,10 +1719,14 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
if (EDGE_COUNT (bb1->succs) != EDGE_COUNT (bb2->succs))
return false;
bool nonfakeedges = false;
FOR_EACH_EDGE (e1, ei, bb1->succs)
{
e2 = EDGE_SUCC (bb2, ei.index);
if ((e1->flags & EDGE_FAKE) == 0)
nonfakeedges = true;
if (e1->flags & EDGE_EH)
nehedges1++;
......@@ -1734,6 +1744,18 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
|| (fallthru1 != 0) != (fallthru2 != 0))
return false;
/* If !ACCUMULATE_OUTGOING_ARGS, bb1 (and bb2) have no successors
and the last real insn doesn't have REG_ARGS_SIZE note, don't
attempt to optimize, as the two basic blocks might have different
REG_ARGS_SIZE depths. For noreturn calls and unconditional
traps there should be REG_ARG_SIZE notes, they could be missing
for __builtin_unreachable () uses though. */
if (!nonfakeedges
&& !ACCUMULATE_OUTGOING_ARGS
&& (!INSN_P (last1)
|| !find_reg_note (last1, REG_ARGS_SIZE, NULL)))
return false;
/* fallthru edges must be forwarded to the same destination. */
if (fallthru1)
{
......
2012-11-20 Jakub Jelinek <jakub@redhat.com>
PR middle-end/55094
* gcc.dg/pr55094.c: New test.
PR rtl-optimization/54921
* gcc.dg/pr54921.c: New test.
......
/* PR middle-end/55094 */
/* { dg-do compile } */
/* { dg-options "-fcompare-debug -Os" } */
/* { dg-additional-options "-fomit-frame-pointer -fno-asynchronous-unwind-tables -mpreferred-stack-boundary=2" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
extern int fn (long);
int v;
int
foo (int x, long *y)
{
if (x)
{
fn (y[0]);
__builtin_trap ();
}
__builtin_trap ();
}
int
bar (int x, long *y)
{
if (x)
{
fn (y[0]);
v = 1;
__builtin_unreachable ();
}
v = 1;
__builtin_unreachable ();
}
int
baz (int x, long *y)
{
if (x)
{
fn (y[0]);
v = 1;
__builtin_unreachable ();
}
v = 1;
int w = 1;
__builtin_unreachable ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment