re PR bootstrap/51796 (internal compiler error: in distribute_notes, at combine.c:13285 for libgomp/alloc.c on m68k-linux)

PR bootstrap/51796
	* combine.c (distribute_notes): If i3 is a noreturn call,
	allow old_size to be equal to args_size and make sure the
	noreturn call gets REG_ARGS_SIZE note.
	* expr.c (fixup_args_size_notes): Put REG_ARGS_SIZE notes
	on noreturn calls even when the delta is 0.

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

From-SVN: r183111
This commit is contained in:
Jakub Jelinek 2012-01-11 23:59:12 +01:00 committed by Jakub Jelinek
parent 11d8e1a4cb
commit 319638ed5c
5 changed files with 63 additions and 7 deletions

View File

@ -1,3 +1,12 @@
2012-01-11 Jakub Jelinek <jakub@redhat.com>
PR bootstrap/51796
* combine.c (distribute_notes): If i3 is a noreturn call,
allow old_size to be equal to args_size and make sure the
noreturn call gets REG_ARGS_SIZE note.
* expr.c (fixup_args_size_notes): Put REG_ARGS_SIZE notes
on noreturn calls even when the delta is 0.
2012-01-11 Nathan Sidwell <nathan@acm.org>
* gcov.c (STRING_SIZE): Remove.

View File

@ -1,7 +1,7 @@
/* Optimize by combining instructions for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011 Free Software Foundation, Inc.
2011, 2012 Free Software Foundation, Inc.
This file is part of GCC.
@ -13281,8 +13281,28 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
if (!noop_move_p (i3))
{
int old_size, args_size = INTVAL (XEXP (note, 0));
/* fixup_args_size_notes looks at REG_NORETURN note,
so ensure the note is placed there first. */
if (CALL_P (i3))
{
rtx *np;
for (np = &next_note; *np; np = &XEXP (*np, 1))
if (REG_NOTE_KIND (*np) == REG_NORETURN)
{
rtx n = *np;
*np = XEXP (n, 1);
XEXP (n, 1) = REG_NOTES (i3);
REG_NOTES (i3) = n;
break;
}
}
old_size = fixup_args_size_notes (PREV_INSN (i3), i3, args_size);
gcc_assert (old_size != args_size);
/* emit_call_1 adds for !ACCUMULATE_OUTGOING_ARGS
REG_ARGS_SIZE note to all noreturn calls, allow that here. */
gcc_assert (old_size != args_size
|| (CALL_P (i3)
&& !ACCUMULATE_OUTGOING_ARGS
&& find_reg_note (i3, REG_NORETURN, NULL_RTX)));
}
break;

View File

@ -1,7 +1,7 @@
/* Convert tree expression to rtl instructions, for GNU compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
2012 Free Software Foundation, Inc.
This file is part of GCC.
@ -3642,9 +3642,11 @@ mem_autoinc_base (rtx mem)
(1) One or more auto-inc style memory references (aka pushes),
(2) One or more addition/subtraction with the SP as destination,
(3) A single move insn with the SP as destination,
(4) A call_pop insn.
(4) A call_pop insn,
(5) Noreturn call insns if !ACCUMULATE_OUTGOING_ARGS.
Insns in the sequence that do not modify the SP are ignored.
Insns in the sequence that do not modify the SP are ignored,
except for noreturn calls.
The return value is the amount of adjustment that can be trivially
verified, via immediate operand or auto-inc. If the adjustment
@ -3789,7 +3791,12 @@ fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
this_delta = find_args_size_adjust (insn);
if (this_delta == 0)
continue;
{
if (!CALL_P (insn)
|| ACCUMULATE_OUTGOING_ARGS
|| find_reg_note (insn, REG_NORETURN, NULL_RTX) == NULL_RTX)
continue;
}
gcc_assert (!saw_unknown);
if (this_delta == HOST_WIDE_INT_MIN)

View File

@ -1,3 +1,8 @@
2012-01-11 Jakub Jelinek <jakub@redhat.com>
PR bootstrap/51796
* gcc.dg/pr51796.c: New test.
2012-01-11 Jason Merrill <jason@redhat.com>
PR c++/51818

View File

@ -0,0 +1,15 @@
/* PR bootstrap/51796 */
/* { dg-do compile } */
/* { dg-options "-Os -fno-omit-frame-pointer -fno-tree-dominator-opts -fno-tree-fre -fno-tree-pre" } */
typedef void (*entry_func) (void) __attribute__ ((noreturn));
extern entry_func entry_addr;
static void bsd_boot_entry (void)
{
stop ();
}
void bsd_boot (void)
{
entry_addr = (entry_func) bsd_boot_entry;
(*entry_addr) ();
}