This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RS6000] Fix pr33812, ICE from epilogue vrsave code
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 20 Oct 2007 22:41:26 +0930
- Subject: [RS6000] Fix pr33812, ICE from epilogue vrsave code
Registers are saved near the top of a stack frame. If we try to
restore vrsave before the frame adjust then the offset from the frame
reg to the vrsave location may exceed 32k in large stack frames.
Since the epilogue is generated after reload, a simple
plus ((reg) (const_int)) won't do.
Applying as obvious after bootstrap and regression test.
PR target/33812
* config/rs6000/rs6000.c (rs6000_emit_epilogue): Revert 2007-05-16
change for vrsave, ie. restore vrsave after frame pop.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 129504)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -16082,21 +16082,6 @@ rs6000_emit_epilogue (int sibcall)
}
}
- /* Restore VRSAVE if needed. */
- if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
- && info->vrsave_mask != 0)
- {
- rtx addr, mem, reg;
-
- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
- GEN_INT (info->vrsave_save_offset + sp_offset));
- mem = gen_frame_mem (SImode, addr);
- reg = gen_rtx_REG (SImode, 12);
- emit_move_insn (reg, mem);
-
- emit_insn (generate_set_vrsave (reg, info, 1));
- }
-
/* If we have a frame pointer, a call to alloca, or a large stack
frame, restore the old stack pointer using the backchain. Otherwise,
we know what size to update it with. */
@@ -16123,6 +16108,21 @@ rs6000_emit_epilogue (int sibcall)
sp_offset = 0;
}
+ /* Restore VRSAVE if needed. */
+ if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
+ && info->vrsave_mask != 0)
+ {
+ rtx addr, mem, reg;
+
+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (info->vrsave_save_offset + sp_offset));
+ mem = gen_frame_mem (SImode, addr);
+ reg = gen_rtx_REG (SImode, 12);
+ emit_move_insn (reg, mem);
+
+ emit_insn (generate_set_vrsave (reg, info, 1));
+ }
+
/* Get the old lr if we saved it. */
if (info->lr_save_p)
{
--
Alan Modra
Australia Development Lab, IBM