+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.
/* 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.
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;
/* 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.
(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
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)
+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
--- /dev/null
+/* 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) ();
+}