From: jakub Date: Wed, 26 May 2010 06:00:44 +0000 (+0000) Subject: PR target/44199 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0e9ae12f6b92db0ed14a3f4ec6eee36b7d5d7db1;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159853 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ed93893cea4d..abcdeae510f0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-05-26 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. + 2010-05-25 Eric Botcazou * function.h (struct function): Add can_throw_non_call_exceptions bit. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 35be57bac9e4..eb8af6fea845 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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; diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 73eca1933405..34d619c38e74 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -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))]