reload1.c (verify_initial_elim_offsets): Return boolean status instead of aborting.
authorUlrich Weigand <uweigand@de.ibm.com>
Wed, 25 May 2005 20:19:26 +0000 (20:19 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Wed, 25 May 2005 20:19:26 +0000 (20:19 +0000)
ChangeLog:

* reload1.c (verify_initial_elim_offsets): Return boolean status
instead of aborting.
(reload): Adapt verify_initial_elim_offsets call site.  Restart
main loop if some initial elimination offsets changed.

testsuite/ChangeLog:

* gcc.dg/20050524-1.c: New test.

From-SVN: r100159

gcc/ChangeLog
gcc/reload1.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20050524-1.c [new file with mode: 0644]

index cfe926ad4e58e544b231991ff32568e83f767f45..a4bf7200bb6154e6bf4579b92e8233907044795b 100644 (file)
@@ -1,3 +1,10 @@
+2005-05-25  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * reload1.c (verify_initial_elim_offsets): Return boolean status
+       instead of aborting.
+       (reload): Adapt verify_initial_elim_offsets call site.  Restart
+       main loop if some initial elimination offsets changed.
+
 2005-05-25  Adam Nemet  <anemet@lnxw.com>
 
        * config/rs6000/lynx.h (CC1_SPEC): Use -maix-struct-return instead
index 06df026d81a1e6318d5321a6ffb2e6484f7b7f11..a1974dfa3b60ca084d511cf5cbfa8a8b1d0a3cc1 100644 (file)
@@ -383,7 +383,7 @@ static int eliminate_regs_in_insn (rtx, int);
 static void update_eliminable_offsets (void);
 static void mark_not_eliminable (rtx, rtx, void *);
 static void set_initial_elim_offsets (void);
-static void verify_initial_elim_offsets (void);
+static bool verify_initial_elim_offsets (void);
 static void set_initial_label_offsets (void);
 static void set_offsets_for_label (rtx);
 static void init_elim_table (void);
@@ -984,6 +984,13 @@ reload (rtx first, int global)
       if (starting_frame_size != get_frame_size ())
        something_changed = 1;
 
+      /* Even if the frame size remained the same, we might still have
+        changed elimination offsets, e.g. if find_reloads called 
+        force_const_mem requiring the back end to allocate a constant
+        pool base register that needs to be saved on the stack.  */
+      else if (!verify_initial_elim_offsets ())
+       something_changed = 1;
+
       {
        HARD_REG_SET to_spill;
        CLEAR_HARD_REG_SET (to_spill);
@@ -1075,8 +1082,7 @@ reload (rtx first, int global)
 
       gcc_assert (old_frame_size == get_frame_size ());
 
-      if (num_eliminable)
-       verify_initial_elim_offsets ();
+      gcc_assert (verify_initial_elim_offsets ());
     }
 
   /* If we were able to eliminate the frame pointer, show that it is no
@@ -3300,23 +3306,30 @@ mark_not_eliminable (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
    where something illegal happened during reload_as_needed that could
    cause incorrect code to be generated if we did not check for it.  */
 
-static void
+static bool
 verify_initial_elim_offsets (void)
 {
   HOST_WIDE_INT t;
 
+  if (!num_eliminable)
+    return true;
+
 #ifdef ELIMINABLE_REGS
   struct elim_table *ep;
 
   for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
     {
       INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, t);
-      gcc_assert (t == ep->initial_offset);
+      if (t != ep->initial_offset)
+       return false;
     }
 #else
   INITIAL_FRAME_POINTER_OFFSET (t);
-  gcc_assert (t == reg_eliminate[0].initial_offset);
+  if (t != reg_eliminate[0].initial_offset)
+    return false;
 #endif
+
+  return true;
 }
 
 /* Reset all offsets on eliminable registers to their initial values.  */
index 7e4b7a2bd13e735455861f9a24b24eef03ecf94c..d060b55ee9475d602d0fcda0a7624a75a543c403 100644 (file)
@@ -1,3 +1,7 @@
+2005-05-25  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * gcc.dg/20050524-1.c: New test.
+
 2005-05-25  Jan Hubicka  <jh@suse.cz>
 
        * gcc.dg/tree-prof/inliner-1.c: New.
diff --git a/gcc/testsuite/gcc.dg/20050524-1.c b/gcc/testsuite/gcc.dg/20050524-1.c
new file mode 100644 (file)
index 0000000..f15c51d
--- /dev/null
@@ -0,0 +1,34 @@
+/* This test case used to abort due to a reload bug with
+   elimination offsets.  */
+
+/* { dg-do run { target s390*-*-* } } */
+/* { dg-options "-O2 -mpacked-stack" } */
+
+extern void abort (void);
+
+double bar (double) __attribute__ ((noinline));
+double bar (double x) { return x; }
+
+double
+foo (int j, double f0, double f2, double f4, double f6, double x) __attribute__ ((noinline));
+
+double
+foo (int j, double f0, double f2, double f4, double f6, double x)
+{
+  if (j)
+    return bar (x) + 4.0;
+  else
+    return bar (x);
+}
+
+int
+main (void)
+{
+  if (foo (0, 0, 0, 0, 0, 10) != 10)
+    abort ();
+  if (foo (1, 0, 0, 0, 0, 10) != 14)
+    abort ();
+
+  return 0;
+}
+