diff options
Diffstat (limited to '0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch')
-rw-r--r-- | 0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch b/0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch new file mode 100644 index 0000000..cc9f87c --- /dev/null +++ b/0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch @@ -0,0 +1,126 @@ +From 4dc3e578d958ceb73f973483f42247c3d33210dc Mon Sep 17 00:00:00 2001 +From: Richard Sandiford <richard.sandiford@arm.com> +Date: Tue, 20 Jun 2023 21:48:38 +0100 +Subject: [PATCH 088/157] [Backport][SME] aarch64: Robustify stack tie handling + +Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=580b74a79146e51268dd11192d3870645adb0bbb + +The SVE handling of stack clash protection copied the stack +pointer to X11 before the probe and set up X11 as the CFA +for unwind purposes: + + /* This is done to provide unwinding information for the stack + adjustments we're about to do, however to prevent the optimizers + from removing the R11 move and leaving the CFA note (which would be + very wrong) we tie the old and new stack pointer together. + The tie will expand to nothing but the optimizers will not touch + the instruction. */ + rtx stack_ptr_copy = gen_rtx_REG (Pmode, STACK_CLASH_SVE_CFA_REGNUM); + emit_move_insn (stack_ptr_copy, stack_pointer_rtx); + emit_insn (gen_stack_tie (stack_ptr_copy, stack_pointer_rtx)); + + /* We want the CFA independent of the stack pointer for the + duration of the loop. */ + add_reg_note (insn, REG_CFA_DEF_CFA, stack_ptr_copy); + RTX_FRAME_RELATED_P (insn) = 1; + +-fcprop-registers is now smart enough to realise that X11 = SP, +replace X11 with SP in the stack tie, and delete the instruction +created above. + +This patch tries to prevent that by making stack_tie fussy about +the register numbers. It fixes failures in +gcc.target/aarch64/sve/pcs/stack_clash*.c. + +gcc/ + * config/aarch64/aarch64.md (stack_tie): Hard-code the first + register operand to the stack pointer. Require the second register + operand to have the number specified in a separate const_int operand. + * config/aarch64/aarch64.cc (aarch64_emit_stack_tie): New function. + (aarch64_allocate_and_probe_stack_space): Use it. + (aarch64_expand_prologue, aarch64_expand_epilogue): Likewise. + (aarch64_expand_epilogue): Likewise. +--- + gcc/config/aarch64/aarch64.cc | 18 ++++++++++++++---- + gcc/config/aarch64/aarch64.md | 7 ++++--- + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 2bb49b9b0..4d505c6fc 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -9917,6 +9917,16 @@ aarch64_stack_clash_protection_alloca_probe_range (void) + return STACK_CLASH_CALLER_GUARD; + } + ++/* Emit a stack tie that acts as a scheduling barrier for all previous and ++ subsequent memory accesses and that requires the stack pointer and REG ++ to have their current values. REG can be stack_pointer_rtx if no ++ other register's value needs to be fixed. */ ++ ++static void ++aarch64_emit_stack_tie (rtx reg) ++{ ++ emit_insn (gen_stack_tie (reg, gen_int_mode (REGNO (reg), DImode))); ++} + + /* Allocate POLY_SIZE bytes of stack space using TEMP1 and TEMP2 as scratch + registers. If POLY_SIZE is not large enough to require a probe this function +@@ -10030,7 +10040,7 @@ aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, + the instruction. */ + rtx stack_ptr_copy = gen_rtx_REG (Pmode, STACK_CLASH_SVE_CFA_REGNUM); + emit_move_insn (stack_ptr_copy, stack_pointer_rtx); +- emit_insn (gen_stack_tie (stack_ptr_copy, stack_pointer_rtx)); ++ aarch64_emit_stack_tie (stack_ptr_copy); + + /* We want the CFA independent of the stack pointer for the + duration of the loop. */ +@@ -10398,7 +10408,7 @@ aarch64_expand_prologue (void) + aarch64_add_cfa_expression (insn, regno_reg_rtx[reg1], + hard_frame_pointer_rtx, 0); + } +- emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx)); ++ aarch64_emit_stack_tie (hard_frame_pointer_rtx); + } + + aarch64_save_callee_saves (saved_regs_offset, R0_REGNUM, R30_REGNUM, +@@ -10501,7 +10511,7 @@ aarch64_expand_epilogue (rtx_call_insn *sibcall) + || cfun->calls_alloca + || crtl->calls_eh_return) + { +- emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx)); ++ aarch64_emit_stack_tie (stack_pointer_rtx); + need_barrier_p = false; + } + +@@ -10540,7 +10550,7 @@ aarch64_expand_epilogue (rtx_call_insn *sibcall) + callee_adjust != 0, &cfi_ops); + + if (need_barrier_p) +- emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx)); ++ aarch64_emit_stack_tie (stack_pointer_rtx); + + if (callee_adjust != 0) + aarch64_pop_regs (reg1, reg2, callee_adjust, &cfi_ops); +diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md +index 2becc888e..2ce123255 100644 +--- a/gcc/config/aarch64/aarch64.md ++++ b/gcc/config/aarch64/aarch64.md +@@ -7088,10 +7088,11 @@ + + (define_insn "stack_tie" + [(set (mem:BLK (scratch)) +- (unspec:BLK [(match_operand:DI 0 "register_operand" "rk") +- (match_operand:DI 1 "register_operand" "rk")] ++ (unspec:BLK [(reg:DI SP_REGNUM) ++ (match_operand:DI 0 "register_operand" "rk") ++ (match_operand:DI 1 "const_int_operand")] + UNSPEC_PRLG_STK))] +- "" ++ "REGNO (operands[0]) == INTVAL (operands[1])" + "" + [(set_attr "length" "0")] + ) +-- +2.33.0 + |