Hi!

My recent patch which adds REG_ARGS_SIZE note to all
!ACCUMULATE_OUTGOING_ARGS noreturn calls introduced a regression,
the checking code in distribute_notes can ICE if something
is combned with the noreturn call and the noreturn call has
the same REG_ARGS_SIZE value as before.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk?

2012-01-10  Jakub Jelinek  <ja...@redhat.com>

        PR bootstrap/51796
        * combine.c (distribute_notes): If i3 is a noreturn call,
        allow old_size to be equal to args_size.

--- gcc/combine.c       2011-12-09 15:21:20.548649331 +0100
+++ gcc/combine.c       2012-01-10 00:10:59.303836653 +0100
@@ -13282,7 +13282,21 @@ distribute_notes (rtx notes, rtx from_in
            {
              int old_size, args_size = INTVAL (XEXP (note, 0));
              old_size = fixup_args_size_notes (PREV_INSN (i3), i3, args_size);
-             gcc_assert (old_size != args_size);
+             if (old_size == args_size)
+               {
+                 /* emit_call_1 adds for !ACCUMULATE_OUTGOING_ARGS
+                    REG_ARGS_SIZE note to all noreturn calls, so allow those
+                    here.  */
+                 gcc_assert (CALL_P (i3) && !ACCUMULATE_OUTGOING_ARGS);
+                 if (find_reg_note (i3, REG_NORETURN, NULL_RTX) == NULL_RTX)
+                   {
+                     rtx n;
+                     for (n = next_note; n; n = XEXP (n, 1))
+                       if (REG_NOTE_KIND (n) == REG_NORETURN)
+                         break;
+                     gcc_assert (n);
+                   }
+               }
            }
          break;
 
--- gcc/testsuite/gcc.dg/pr51796.c.jj   2012-01-10 16:35:53.917661308 +0100
+++ gcc/testsuite/gcc.dg/pr51796.c      2012-01-10 16:36:36.000880045 +0100
@@ -0,0 +1,16 @@
+/* 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) ();
+}
+

        Jakub

Reply via email to