* [pushed] aarch64: Robustify stack tie handling
@ 2023-06-20 20:49 Richard Sandiford
2023-06-21 4:29 ` Jeff Law
0 siblings, 1 reply; 2+ messages in thread
From: Richard Sandiford @ 2023-06-20 20:49 UTC (permalink / raw)
To: gcc-patches
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.
Tested on aarch64-linux-gnu & pushed.
Richard
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 ee37ceaa255..b99f12c99e9 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -9664,6 +9664,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
@@ -9776,7 +9786,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. */
@@ -10145,7 +10155,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,
@@ -10248,7 +10258,7 @@ aarch64_expand_epilogue (bool for_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;
}
@@ -10287,7 +10297,7 @@ aarch64_expand_epilogue (bool for_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 25f7905c6a0..01cf989641f 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -7325,10 +7325,11 @@ (define_insn "tlsdesc_small_sve_<mode>"
(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.25.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [pushed] aarch64: Robustify stack tie handling
2023-06-20 20:49 [pushed] aarch64: Robustify stack tie handling Richard Sandiford
@ 2023-06-21 4:29 ` Jeff Law
0 siblings, 0 replies; 2+ messages in thread
From: Jeff Law @ 2023-06-21 4:29 UTC (permalink / raw)
To: gcc-patches, richard.sandiford
On 6/20/23 14:49, Richard Sandiford via Gcc-patches wrote:
> 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.
>
> Tested on aarch64-linux-gnu & pushed.
Thanks for taking care of this. It was a bit surprising that we ran
into these problems given that we were allowing regcprop to propagate
sp->gpr copies a few years back and we're just re-enabling that
capability in the safe cases. Presumably this stack tie went in after
we'd disabled propagating away sp->gpr copies.
Jeff
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-06-21 4:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-20 20:49 [pushed] aarch64: Robustify stack tie handling Richard Sandiford
2023-06-21 4:29 ` Jeff Law
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).