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
This commit is contained in:
Ulrich Weigand 2005-05-25 20:19:26 +00:00 committed by Ulrich Weigand
parent 0fd7e0f84b
commit 9f938de17c
4 changed files with 64 additions and 6 deletions

View 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

View 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. */

View 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.

View File

@ -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;
}