aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2005-05-25 20:19:26 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2005-05-25 20:19:26 +0000
commit9f938de17ca1aff1e5ea66e664159764fa1cc770 (patch)
treed0ac324c8518c7ea6960b902a9eaecfae51024b5 /gcc
parent0fd7e0f84b3a90262d0067b93f0eba5e03b454d1 (diff)
downloadgcc-9f938de17ca1aff1e5ea66e664159764fa1cc770.zip
gcc-9f938de17ca1aff1e5ea66e664159764fa1cc770.tar.gz
gcc-9f938de17ca1aff1e5ea66e664159764fa1cc770.tar.bz2
reload1.c (verify_initial_elim_offsets): Return boolean status instead of aborting.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/reload1.c25
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/20050524-1.c34
4 files changed, 64 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cfe926a..a4bf720 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 06df026..a1974df 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7e4b7a2..d060b55 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..f15c51d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20050524-1.c
@@ -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;
+}
+