127 lines
5.0 KiB
Diff
127 lines
5.0 KiB
Diff
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
|
|
|