2010-05-20 Jakub Jelinek 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. --- gcc/config/rs6000/rs6000.c.jj 2010-05-17 07:52:06.000000000 +0200 +++ gcc/config/rs6000/rs6000.c 2010-05-19 22:15:53.000000000 +0200 @@ -19775,6 +19775,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))); @@ -19784,6 +19794,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; --- gcc/config/rs6000/rs6000.md.jj 2010-03-26 17:13:37.000000000 +0100 +++ gcc/config/rs6000/rs6000.md 2010-05-19 22:15:19.000000000 +0200 @@ -15286,6 +15286,15 @@ (define_insn "stack_tie" "" [(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))]