Commit 0d65bdbb by Jakub Jelinek Committed by Jakub Jelinek

re PR target/44199 (ppc64 glibc miscompilation)

	PR target/44199
	* config/rs6000/rs6000.c (rs6000_emit_epilogue): If cfun->calls_alloca
	or total_size is larger than red zone size for non-V4 ABI, emit a
	stack_tie resp. frame_tie insn before stack pointer restore.
	* config/rs6000/rs6000.md (frame_tie): New insn.

From-SVN: r159853
parent cc9a4ca9
2010-05-26 Jakub Jelinek <jakub@redhat.com>
PR target/44199
* config/rs6000/rs6000.c (rs6000_emit_epilogue): If cfun->calls_alloca
or total_size is larger than red zone size for non-V4 ABI, emit a
stack_tie resp. frame_tie insn before stack pointer restore.
* config/rs6000/rs6000.md (frame_tie): New insn.
2010-05-25 Eric Botcazou <ebotcazou@adacore.com>
* function.h (struct function): Add can_throw_non_call_exceptions bit.
......
......@@ -19796,6 +19796,16 @@ rs6000_emit_epilogue (int sibcall)
frame_reg_rtx = sp_reg_rtx;
if (DEFAULT_ABI == ABI_V4)
frame_reg_rtx = gen_rtx_REG (Pmode, 11);
/* Prevent reordering memory accesses against stack pointer restore. */
else if (cfun->calls_alloca
|| offset_below_red_zone_p (-info->total_size))
{
rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
MEM_NOTRAP_P (mem1) = 1;
MEM_NOTRAP_P (mem2) = 1;
emit_insn (gen_frame_tie (mem1, mem2));
}
insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
GEN_INT (info->total_size)));
......@@ -19805,6 +19815,14 @@ rs6000_emit_epilogue (int sibcall)
&& DEFAULT_ABI != ABI_V4
&& !crtl->calls_eh_return)
{
/* Prevent reordering memory accesses against stack pointer restore. */
if (cfun->calls_alloca
|| offset_below_red_zone_p (-info->total_size))
{
rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
MEM_NOTRAP_P (mem) = 1;
emit_insn (gen_stack_tie (mem));
}
insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
GEN_INT (info->total_size)));
sp_offset = 0;
......
......@@ -15286,6 +15286,15 @@
""
[(set_attr "length" "0")])
; Like stack_tie, but depend on both fp and sp based memory.
(define_insn "frame_tie"
[(set (match_operand:BLK 0 "memory_operand" "+m")
(unspec:BLK [(match_dup 0)
(match_operand:BLK 1 "memory_operand" "m")] UNSPEC_TIE))]
""
""
[(set_attr "length" "0")])
(define_expand "epilogue"
[(use (const_int 0))]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment