summaryrefslogtreecommitdiff
path: root/0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch
diff options
context:
space:
mode:
Diffstat (limited to '0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch')
-rw-r--r--0187-Backport-SME-aarch64-Robustify-stack-tie-handling.patch126
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
+