OSDN Git Service

PR bootstrap/51796
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 11 Jan 2012 22:59:12 +0000 (22:59 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 11 Jan 2012 22:59:12 +0000 (22:59 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183111 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/combine.c
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr51796.c [new file with mode: 0644]

index 28624d1..4d6d129 100644 (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.
index 105e778..4178870 100644 (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;
 
index 9825d12..c516269 100644 (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)
index 0d5b596..970e4e0 100644 (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
diff --git a/gcc/testsuite/gcc.dg/pr51796.c b/gcc/testsuite/gcc.dg/pr51796.c
new file mode 100644 (file)
index 0000000..c07ad10
--- /dev/null
@@ -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) ();
+}