To avoid stack realignment, use SCRATCH_SSE_REG to copy data from one memory location to another.
gcc/ * config/i386/i386-expand.c (ix86_expand_vector_move): Use SCRATCH_SSE_REG to copy data from one memory location to another. gcc/testsuite/ * gcc.target/i386/eh_return-1.c: New test. --- gcc/config/i386/i386-expand.c | 16 ++++++++++++- gcc/testsuite/gcc.target/i386/eh_return-1.c | 26 +++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/eh_return-1.c diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index 7f1dff6337c..09d5e5d88af 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -431,7 +431,21 @@ ix86_expand_vector_move (machine_mode mode, rtx operands[]) && !register_operand (op0, mode) && !register_operand (op1, mode)) { - emit_move_insn (op0, force_reg (GET_MODE (op0), op1)); + rtx tmp; + mode = GET_MODE (op0); + if (TARGET_SSE + && (GET_MODE_ALIGNMENT (mode) + > ix86_minimum_incoming_stack_boundary (false, true))) + { + /* NB: Don't increase stack alignment requirement by using + a scratch SSE register to copy data from one memory + location to another since it doesn't require a spill. */ + tmp = gen_rtx_REG (mode, SCRATCH_SSE_REG); + emit_move_insn (tmp, op1); + } + else + tmp = force_reg (mode, op1); + emit_move_insn (op0, tmp); return; } diff --git a/gcc/testsuite/gcc.target/i386/eh_return-1.c b/gcc/testsuite/gcc.target/i386/eh_return-1.c new file mode 100644 index 00000000000..671ba635e88 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/eh_return-1.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=haswell -mno-avx512f" } */ + +struct _Unwind_Context +{ + void *ra; + char array[48]; +}; + +extern long uw_install_context_1 (struct _Unwind_Context *); + +void +_Unwind_RaiseException (void) +{ + struct _Unwind_Context this_context, cur_context; + long offset = uw_install_context_1 (&this_context); + __builtin_memcpy (&this_context, &cur_context, + sizeof (struct _Unwind_Context)); + void *handler = __builtin_frob_return_addr ((&cur_context)->ra); + uw_install_context_1 (&cur_context); + __builtin_eh_return (offset, handler); +} + +/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\n\]*%ymm" 4 } } */ +/* No need to dynamically realign the stack here. */ +/* { dg-final { scan-assembler-not "and\[^\n\r]*%\[re\]sp" } } */ -- 2.31.1