diff options
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r-- | gcc/reload1.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index 06df026d81a..a1974dfa3b6 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. */ |