diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2005-05-25 20:19:26 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2005-05-25 20:19:26 +0000 |
commit | 9f938de17ca1aff1e5ea66e664159764fa1cc770 (patch) | |
tree | d0ac324c8518c7ea6960b902a9eaecfae51024b5 /gcc | |
parent | 0fd7e0f84b3a90262d0067b93f0eba5e03b454d1 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/reload1.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/20050524-1.c | 34 |
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 < ®_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; +} + |