Hi,
this fixes a problem with the prologue optimization in machine
dependent reorg. For more details please see PR62662.
No regressions on s390 and s390x.
-Andreas-
2014-09-10 Andreas Krebbel
PR target/62662
* config/s390/s390.c (s390_emit_epilogue): When doing the return
address load optimization force s390_optimize_prologue to leave it
that way. Only do the optimization if we already decided to push
r14 into a stack slot.
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index f7a95dd..161efd9 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -9082,11 +9082,14 @@ s390_emit_epilogue (bool sibcall)
if (! sibcall)
{
/* Fetch return address from stack before load multiple,
-this will do good for scheduling. */
-
- if (cfun_frame_layout.save_return_addr_p
- || (cfun_frame_layout.first_restore_gpr < BASE_REGNUM
- && cfun_frame_layout.last_restore_gpr > RETURN_REGNUM))
+this will do good for scheduling.
+
+Only do this if we already decided that r14 needs to be
+saved to a stack slot. (And not just because r14 happens to
+be in between two GPRs which need saving.) Otherwise it
+would be difficult to take that decision back in
+s390_optimize_prologue. */
+ if (cfun_gpr_save_slot (RETURN_REGNUM) == -1)
{
int return_regnum = find_unused_clobbered_reg();
if (!return_regnum)
@@ -9101,6 +9104,13 @@ s390_emit_epilogue (bool sibcall)
addr = gen_rtx_MEM (Pmode, addr);
set_mem_alias_set (addr, get_frame_alias_set ());
emit_move_insn (return_reg, addr);
+
+ /* Once we did that optimization we have to make sure
+s390_optimize_prologue does not try to remove the
+store of r14 since we will not be able to find the
+load issued here. */
+ cfun_frame_layout.save_return_addr_p = true;
+ cfun_gpr_save_slot (RETURN_REGNUM) = -1;
}
}
--
1.7.11.4