[gcc r15-3092] RISC-V: Fix vector cfi notes for stack-clash protection

2024-08-22 Thread Raphael Zinsly via Gcc-cvs
https://gcc.gnu.org/g:a025081991cca1734fb642e6609772cfce8be4d1

commit r15-3092-ga025081991cca1734fb642e6609772cfce8be4d1
Author: Raphael Moreira Zinsly 
Date:   Wed Aug 21 18:08:54 2024 -0300

RISC-V: Fix vector cfi notes for stack-clash protection

The stack-clash code is generating wrong cfi directives in
riscv_v_adjust_scalable_frame because REG_CFA_DEF_CFA has a different
encoding than REG_FRAME_RELATED_EXPR, this patch fixes the offset sign
in prologue and starts using REG_CFA_DEF_CFA in the epilogue.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_v_adjust_scalable_frame): Add
epilogue code for stack-clash and fix prologue cfi note.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/stack-check-cfa-3.c: Fix the expected output.

Diff:
---
 gcc/config/riscv/riscv.cc  | 18 --
 gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c |  3 ++-
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f266c45ed4d9..8538d405f505 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -7974,8 +7974,22 @@ riscv_v_adjust_scalable_frame (rtx target, poly_int64 
offset, bool epilogue)
 
   /* If doing stack clash protection then we use a loop to allocate and probe
  the stack.  */
-  if (flag_stack_clash_protection && !epilogue)
+  if (flag_stack_clash_protection)
 {
+  if (epilogue)
+   {
+ insn = emit_insn (gen_add3_insn (target, target, adjust_size));
+
+ if (!frame_pointer_needed)
+   {
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+   plus_constant (Pmode, stack_pointer_rtx, -offset));
+ RTX_FRAME_RELATED_P (insn) = 1;
+   }
+
+ return;
+   }
+
   HOST_WIDE_INT min_probe_threshold
= (1 << param_stack_clash_protection_guard_size) - 
STACK_CLASH_CALLER_GUARD;
 
@@ -8008,7 +8022,7 @@ riscv_v_adjust_scalable_frame (rtx target, poly_int64 
offset, bool epilogue)
   if (!frame_pointer_needed)
{
  add_reg_note (insn, REG_CFA_DEF_CFA,
-   plus_constant (Pmode, stack_pointer_rtx, -offset));
+   plus_constant (Pmode, stack_pointer_rtx, offset));
  RTX_FRAME_RELATED_P (insn) = 1;
}
 
diff --git a/gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c 
b/gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c
index e45f7bb7df51..225dfae661d2 100644
--- a/gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c
+++ b/gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c
@@ -10,4 +10,5 @@
 
 /* { dg-final { scan-assembler-times {mv\tt3,sp} 1 } } */
 /* { dg-final { scan-assembler-times {\.cfi_def_cfa [0-9]+, 0} 1 } } */
-/* { dg-final { scan-assembler-times {\.cfi_escape 
0xf,0xa,0x72,0,0x92,0xa2,0x38,0,0x9,0xec,0x1e,0x22} 1 } } */
+/* { dg-final { scan-assembler-times {\.cfi_escape 
0xf,0x9,0x72,0,0x92,0xa2,0x38,0,0x3a,0x1e,0x22} 1 } } */
+/* { dg-final { scan-assembler-times {\.cfi_escape 
0xf,0xa,0x72,0,0x92,0xa2,0x38,0,0x9,0xf6,0x1e,0x22} 1 } } */


[gcc r15-2850] RISC-V: Small stack tie changes

2024-08-09 Thread Raphael Zinsly via Gcc-cvs
https://gcc.gnu.org/g:0e604d0ef6dcac8ee4cdc62902f2a2708ef7b040

commit r15-2850-g0e604d0ef6dcac8ee4cdc62902f2a2708ef7b040
Author: Raphael Moreira Zinsly 
Date:   Mon Jul 22 11:23:12 2024 -0300

RISC-V: Small stack tie changes

Enable the register used by riscv_emit_stack_tie () to be passed as
an argument so we can tie the stack with other registers besides
hard_frame_pointer_rtx.
Also don't allow operand 1 of stack_tie to be optimized to sp
in preparation for the stack clash protection support.

gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_emit_stack_tie): Pass the
register to be tied to the stack pointer as argument.
* config/riscv/riscv.md (stack_tie): Don't match equal
operands.

Diff:
---
 gcc/config/riscv/riscv.cc | 18 +-
 gcc/config/riscv/riscv.md |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 3d0a1d12b146..6981ec42af4e 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -7894,12 +7894,12 @@ riscv_adjust_multi_push_cfi_prologue (int saved_size)
 }
 
 static void
-riscv_emit_stack_tie (void)
+riscv_emit_stack_tie (rtx reg)
 {
   if (Pmode == SImode)
-emit_insn (gen_stack_tiesi (stack_pointer_rtx, hard_frame_pointer_rtx));
+emit_insn (gen_stack_tiesi (stack_pointer_rtx, reg));
   else
-emit_insn (gen_stack_tiedi (stack_pointer_rtx, hard_frame_pointer_rtx));
+emit_insn (gen_stack_tiedi (stack_pointer_rtx, reg));
 }
 
 /*zcmp multi push and pop code_for_push_pop function ptr array  */
@@ -8080,7 +8080,7 @@ riscv_expand_prologue (void)
GEN_INT ((frame->hard_frame_pointer_offset - 
remaining_size).to_constant ()));
   RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
 
-  riscv_emit_stack_tie ();
+  riscv_emit_stack_tie (hard_frame_pointer_rtx);
 }
 
   /* Save the V registers.  */
@@ -8111,7 +8111,7 @@ riscv_expand_prologue (void)
 allocation is ordered WRT fp setup and subsequent writes
 into the frame.  */
  if (frame_pointer_needed)
-   riscv_emit_stack_tie ();
+   riscv_emit_stack_tie (hard_frame_pointer_rtx);
  return;
}
 
@@ -8150,7 +8150,7 @@ riscv_expand_prologue (void)
 allocation is ordered WRT fp setup and subsequent writes
 into the frame.  */
   if (frame_pointer_needed)
-   riscv_emit_stack_tie ();
+   riscv_emit_stack_tie (hard_frame_pointer_rtx);
 }
 }
 
@@ -8285,7 +8285,7 @@ riscv_expand_epilogue (int style)
   if (cfun->calls_alloca)
 {
   /* Emit a barrier to prevent loads from a deallocated stack.  */
-  riscv_emit_stack_tie ();
+  riscv_emit_stack_tie (hard_frame_pointer_rtx);
   need_barrier_p = false;
 
   poly_int64 adjust_offset = -frame->hard_frame_pointer_offset;
@@ -8379,7 +8379,7 @@ riscv_expand_epilogue (int style)
   if (known_gt (step1, 0))
 {
   /* Emit a barrier to prevent loads from a deallocated stack.  */
-  riscv_emit_stack_tie ();
+  riscv_emit_stack_tie (hard_frame_pointer_rtx);
   need_barrier_p = false;
 
   /* Restore the scalable frame which is assigned in prologue.  */
@@ -8479,7 +8479,7 @@ riscv_expand_epilogue (int style)
 frame->mask = mask; /* Undo the above fib.  */
 
   if (need_barrier_p)
-riscv_emit_stack_tie ();
+riscv_emit_stack_tie (hard_frame_pointer_rtx);
 
   /* Deallocate the final bit of the frame.  */
   if (step2.to_constant () > 0)
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index f46851dd4717..5e3ef789e42e 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3969,7 +3969,7 @@
(unspec:BLK [(match_operand:X 0 "register_operand" "r")
 (match_operand:X 1 "register_operand" "r")]
UNSPEC_TIE))]
-  ""
+  "!rtx_equal_p (operands[0], operands[1])"
   ""
   [(set_attr "type" "ghost")
(set_attr "length" "0")]


[gcc r15-2851] RISC-V: Move riscv_v_adjust_scalable_frame

2024-08-09 Thread Raphael Zinsly via Gcc-cvs
https://gcc.gnu.org/g:5694fcf75b65bea5d3eb42e5d28d7f3e5ee7cfd7

commit r15-2851-g5694fcf75b65bea5d3eb42e5d28d7f3e5ee7cfd7
Author: Raphael Moreira Zinsly 
Date:   Mon Jul 22 11:23:17 2024 -0300

RISC-V: Move riscv_v_adjust_scalable_frame

Move riscv_v_adjust_scalable_frame () in preparation for the stack clash
protection support.

gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_v_adjust_scalable_frame): Move
closer to riscv_expand_prologue.

Diff:
---
 gcc/config/riscv/riscv.cc | 62 +++
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 6981ec42af4e..eb32520b36cc 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3122,37 +3122,6 @@ riscv_legitimize_poly_move (machine_mode mode, rtx dest, 
rtx tmp, rtx src)
 }
 }
 
-/* Adjust scalable frame of vector for prologue && epilogue. */
-
-static void
-riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue)
-{
-  rtx tmp = RISCV_PROLOGUE_TEMP (Pmode);
-  rtx adjust_size = RISCV_PROLOGUE_TEMP2 (Pmode);
-  rtx insn, dwarf, adjust_frame_rtx;
-
-  riscv_legitimize_poly_move (Pmode, adjust_size, tmp,
- gen_int_mode (offset, Pmode));
-
-  if (epilogue)
-insn = gen_add3_insn (target, target, adjust_size);
-  else
-insn = gen_sub3_insn (target, target, adjust_size);
-
-  insn = emit_insn (insn);
-
-  RTX_FRAME_RELATED_P (insn) = 1;
-
-  adjust_frame_rtx
-= gen_rtx_SET (target,
-  plus_constant (Pmode, target, epilogue ? offset : -offset));
-
-  dwarf = alloc_reg_note (REG_FRAME_RELATED_EXPR, copy_rtx (adjust_frame_rtx),
- NULL_RTX);
-
-  REG_NOTES (insn) = dwarf;
-}
-
 /* Take care below subreg const_poly_int move:
 
1. (set (subreg:DI (reg:TI 237) 8)
@@ -7931,6 +7900,37 @@ static const code_for_push_pop_t 
code_for_push_pop[ZCMP_MAX_GRP_SLOTS][ZCMP_OP_N
   code_for_gpr_multi_popret_up_to_s11,
   code_for_gpr_multi_popretz_up_to_s11}};
 
+/* Adjust scalable frame of vector for prologue && epilogue. */
+
+static void
+riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue)
+{
+  rtx tmp = RISCV_PROLOGUE_TEMP (Pmode);
+  rtx adjust_size = RISCV_PROLOGUE_TEMP2 (Pmode);
+  rtx insn, dwarf, adjust_frame_rtx;
+
+  riscv_legitimize_poly_move (Pmode, adjust_size, tmp,
+ gen_int_mode (offset, Pmode));
+
+  if (epilogue)
+insn = gen_add3_insn (target, target, adjust_size);
+  else
+insn = gen_sub3_insn (target, target, adjust_size);
+
+  insn = emit_insn (insn);
+
+  RTX_FRAME_RELATED_P (insn) = 1;
+
+  adjust_frame_rtx
+= gen_rtx_SET (target,
+  plus_constant (Pmode, target, epilogue ? offset : -offset));
+
+  dwarf = alloc_reg_note (REG_FRAME_RELATED_EXPR, copy_rtx (adjust_frame_rtx),
+ NULL_RTX);
+
+  REG_NOTES (insn) = dwarf;
+}
+
 static rtx
 riscv_gen_multi_push_pop_insn (riscv_zcmp_op_t op, HOST_WIDE_INT adj_size,
   unsigned int regs_num)


[gcc r15-2852] RISC-V: Stack-clash protection implemention

2024-08-09 Thread Raphael Zinsly via Gcc-cvs
https://gcc.gnu.org/g:b82d173dac33d9e2f7d31bf84eb0d9f0c21d0240

commit r15-2852-gb82d173dac33d9e2f7d31bf84eb0d9f0c21d0240
Author: Raphael Moreira Zinsly 
Date:   Mon Jul 22 11:23:20 2024 -0300

RISC-V: Stack-clash protection implemention

This implements stack-clash protection for riscv, with
riscv_allocate_and_probe_stack_space being based of
aarch64_allocate_and_probe_stack_space from aarch64's implementation.
We enforce the probing interval and the guard size to always be equal, their
default value is 4Kb which is riscv page size.

We also probe up by 1024 bytes in the general case when a probe is required.

gcc/ChangeLog:
* config/riscv/riscv.cc
(riscv_option_override): Enforce that interval is the same size as
guard size.
(riscv_allocate_and_probe_stack_space): New function.
(riscv_expand_prologue): Call riscv_allocate_and_probe_stack_space
to the final allocation of the stack and add stack-clash dump
information.
* config/riscv/riscv.h: Define STACK_CLASH_CALLER_GUARD and
STACK_CLASH_MAX_UNROLL_PAGES.

gcc/testsuite/ChangeLog:
* gcc.dg/params/blocksort-part.c: Skip riscv for
stack-clash protection intervals.
* gcc.dg/pr82788.c: Skip riscv.
* gcc.dg/stack-check-6.c: Skip residual check for riscv.
* gcc.dg/stack-check-6a.c: Skip riscv.
* gcc.target/riscv/stack-check-12.c: New test.
* gcc.target/riscv/stack-check-13.c: New test.
* gcc.target/riscv/stack-check-cfa-1.c: New test.
* gcc.target/riscv/stack-check-cfa-2.c: New test.
* gcc.target/riscv/stack-check-prologue-1.c: New test.
* gcc.target/riscv/stack-check-prologue-10.c: New test.
* gcc.target/riscv/stack-check-prologue-11.c: New test.
* gcc.target/riscv/stack-check-prologue-12.c: New test.
* gcc.target/riscv/stack-check-prologue-13.c: New test.
* gcc.target/riscv/stack-check-prologue-14.c: New test.
* gcc.target/riscv/stack-check-prologue-15.c: New test.
* gcc.target/riscv/stack-check-prologue-2.c: New test.
* gcc.target/riscv/stack-check-prologue-3.c: New test.
* gcc.target/riscv/stack-check-prologue-4.c: New test.
* gcc.target/riscv/stack-check-prologue-5.c: New test.
* gcc.target/riscv/stack-check-prologue-6.c: New test.
* gcc.target/riscv/stack-check-prologue-7.c: New test.
* gcc.target/riscv/stack-check-prologue-8.c: New test.
* gcc.target/riscv/stack-check-prologue-9.c: New test.
* gcc.target/riscv/stack-check-prologue.h: New file.
* lib/target-supports.exp
(check_effective_target_supports_stack_clash_protection):
Add riscv.
(check_effective_target_caller_implicit_probes): Likewise.

Diff:
---
 gcc/config/riscv/riscv.cc  | 244 ++---
 gcc/config/riscv/riscv.h   |   8 +
 gcc/testsuite/gcc.dg/params/blocksort-part.c   |   2 +-
 gcc/testsuite/gcc.dg/pr82788.c |   2 +-
 gcc/testsuite/gcc.dg/stack-check-6.c   |   2 +-
 gcc/testsuite/gcc.dg/stack-check-6a.c  |   2 +-
 gcc/testsuite/gcc.target/riscv/stack-check-12.c|  23 ++
 gcc/testsuite/gcc.target/riscv/stack-check-13.c|  26 +++
 gcc/testsuite/gcc.target/riscv/stack-check-cfa-1.c |  12 +
 gcc/testsuite/gcc.target/riscv/stack-check-cfa-2.c |  13 ++
 .../gcc.target/riscv/stack-check-prologue-1.c  |   9 +
 .../gcc.target/riscv/stack-check-prologue-10.c |  11 +
 .../gcc.target/riscv/stack-check-prologue-11.c |  11 +
 .../gcc.target/riscv/stack-check-prologue-12.c |  15 ++
 .../gcc.target/riscv/stack-check-prologue-13.c |  20 ++
 .../gcc.target/riscv/stack-check-prologue-14.c |  24 ++
 .../gcc.target/riscv/stack-check-prologue-15.c |  23 ++
 .../gcc.target/riscv/stack-check-prologue-2.c  |  10 +
 .../gcc.target/riscv/stack-check-prologue-3.c  |  11 +
 .../gcc.target/riscv/stack-check-prologue-4.c  |  11 +
 .../gcc.target/riscv/stack-check-prologue-5.c  |  11 +
 .../gcc.target/riscv/stack-check-prologue-6.c  |  11 +
 .../gcc.target/riscv/stack-check-prologue-7.c  |  11 +
 .../gcc.target/riscv/stack-check-prologue-8.c  |  10 +
 .../gcc.target/riscv/stack-check-prologue-9.c  |  11 +
 .../gcc.target/riscv/stack-check-prologue.h|   5 +
 gcc/testsuite/lib/target-supports.exp  |   6 +-
 27 files changed, 504 insertions(+), 40 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index eb32520b36cc..63139afd3e36 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -7953,6 +7953,191 @@ get_multi_push_fpr_mask (unsigned max_fprs_push)
   return mask_fprs_push;
 }
 
+/* A

[gcc r15-2853] RISC-V: Add support to vector stack-clash protection

2024-08-09 Thread Raphael Zinsly via Gcc-cvs
https://gcc.gnu.org/g:2862d99bfdae96a1d4b275fa3f3daad6206ff761

commit r15-2853-g2862d99bfdae96a1d4b275fa3f3daad6206ff761
Author: Raphael Moreira Zinsly 
Date:   Mon Jul 22 11:23:23 2024 -0300

RISC-V: Add support to vector stack-clash protection

Adds basic support to vector stack-clash protection using a loop to do
the probing and stack adjustments.

gcc/ChangeLog:
* config/riscv/riscv.cc
(riscv_allocate_and_probe_stack_loop): New function.
(riscv_v_adjust_scalable_frame): Add stack-clash protection
support.
(riscv_allocate_and_probe_stack_space): Move the probe loop
implementation to riscv_allocate_and_probe_stack_loop.
* config/riscv/riscv.h: Define RISCV_STACK_CLASH_VECTOR_CFA_REGNUM.

gcc/testsuite/ChangeLog:
* gcc.target/riscv/stack-check-cfa-3.c: New test.
* gcc.target/riscv/stack-check-prologue-16.c: New test.
* gcc.target/riscv/struct_vect_24.c: New test.

Diff:
---
 gcc/config/riscv/riscv.cc  | 99 +-
 gcc/config/riscv/riscv.h   |  5 ++
 gcc/testsuite/gcc.target/riscv/stack-check-cfa-3.c | 13 +++
 .../gcc.target/riscv/stack-check-prologue-16.c | 30 +++
 gcc/testsuite/gcc.target/riscv/struct_vect_24.c| 47 ++
 5 files changed, 173 insertions(+), 21 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 63139afd3e36..034290617624 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -7900,6 +7900,35 @@ static const code_for_push_pop_t 
code_for_push_pop[ZCMP_MAX_GRP_SLOTS][ZCMP_OP_N
   code_for_gpr_multi_popret_up_to_s11,
   code_for_gpr_multi_popretz_up_to_s11}};
 
+/*  Set a probe loop for stack clash protection.  */
+static void
+riscv_allocate_and_probe_stack_loop (rtx tmp, enum rtx_code code,
+rtx op0, rtx op1, bool vector,
+HOST_WIDE_INT offset)
+{
+  tmp = riscv_force_temporary (tmp, gen_int_mode (offset, Pmode));
+
+  /* Loop.  */
+  rtx label = gen_label_rtx ();
+  emit_label (label);
+
+  /* Allocate and probe stack.  */
+  emit_insn (gen_sub3_insn (stack_pointer_rtx, stack_pointer_rtx, tmp));
+  emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
+   STACK_CLASH_CALLER_GUARD));
+  emit_insn (gen_blockage ());
+
+  /* Adjust the remaining vector length.  */
+  if (vector)
+emit_insn (gen_sub3_insn (op0, op0, tmp));
+
+  /* Branch if there's still more bytes to probe.  */
+  riscv_expand_conditional_branch (label, code, op0, op1);
+  JUMP_LABEL (get_last_insn ()) = label;
+
+  emit_insn (gen_blockage ());
+}
+
 /* Adjust scalable frame of vector for prologue && epilogue. */
 
 static void
@@ -7912,6 +7941,49 @@ riscv_v_adjust_scalable_frame (rtx target, poly_int64 
offset, bool epilogue)
   riscv_legitimize_poly_move (Pmode, adjust_size, tmp,
  gen_int_mode (offset, Pmode));
 
+  /* If doing stack clash protection then we use a loop to allocate and probe
+ the stack.  */
+  if (flag_stack_clash_protection && !epilogue)
+{
+  HOST_WIDE_INT min_probe_threshold
+   = (1 << param_stack_clash_protection_guard_size) - 
STACK_CLASH_CALLER_GUARD;
+
+  if (!frame_pointer_needed)
+   {
+ /* This is done to provide unwinding information for the stack
+adjustments we're about to do, however to prevent the optimizers
+from removing the T3 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.  */
+ insn = get_last_insn ();
+ rtx stack_ptr_copy = gen_rtx_REG (Pmode, 
RISCV_STACK_CLASH_VECTOR_CFA_REGNUM);
+ emit_move_insn (stack_ptr_copy, stack_pointer_rtx);
+ riscv_emit_stack_tie (stack_ptr_copy);
+
+ /* 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;
+   }
+
+  riscv_allocate_and_probe_stack_loop (tmp, GE, adjust_size, tmp, true,
+  min_probe_threshold);
+
+  /* Allocate the residual.  */
+  insn = emit_insn (gen_sub3_insn (target, target, adjust_size));
+
+  /* Now reset the CFA register if needed.  */
+  if (!frame_pointer_needed)
+   {
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+   plus_constant (Pmode, stack_pointer_rtx, -offset));
+ RTX_FRAME_RELATED_P (insn) = 1;
+   }
+
+  return;
+}
+
   if (epilogue)
 insn = gen_add3_insn (target, target, adjust_size);
   else
@@ -8059,8 +8131,9 @@ riscv_allocate_and_probe_stack_space (rtx temp1, 
HOST_WIDE_INT size

[gcc r15-2854] RISC-V: Enable stack clash in alloca

2024-08-09 Thread Raphael Zinsly via Gcc-cvs
https://gcc.gnu.org/g:180ede3543e98ade8f809afe8be5af0eeaeff7bb

commit r15-2854-g180ede3543e98ade8f809afe8be5af0eeaeff7bb
Author: Raphael Moreira Zinsly 
Date:   Mon Jul 22 11:23:27 2024 -0300

RISC-V: Enable stack clash in alloca

Add the TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE to riscv in
order to enable stack clash protection when using alloca.
The code and tests are the same used by aarch64.

gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_compute_frame_info): Update
outgoing args size.
(riscv_stack_clash_protection_alloca_probe_range): New.
(TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE): New.
* config/riscv/riscv.h
(STACK_CLASH_MIN_BYTES_OUTGOING_ARGS): New.
(STACK_DYNAMIC_OFFSET): New.

gcc/testsuite/ChangeLog:
* gcc.target/riscv/stack-check-14.c: New test.
* gcc.target/riscv/stack-check-15.c: New test.
* gcc.target/riscv/stack-check-alloca-1.c: New test.
* gcc.target/riscv/stack-check-alloca-2.c: New test.
* gcc.target/riscv/stack-check-alloca-3.c: New test.
* gcc.target/riscv/stack-check-alloca-4.c: New test.
* gcc.target/riscv/stack-check-alloca-5.c: New test.
* gcc.target/riscv/stack-check-alloca-6.c: New test.
* gcc.target/riscv/stack-check-alloca-7.c: New test.
* gcc.target/riscv/stack-check-alloca-8.c: New test.
* gcc.target/riscv/stack-check-alloca-9.c: New test.
* gcc.target/riscv/stack-check-alloca-10.c: New test.
* gcc.target/riscv/stack-check-alloca.h: New.

Diff:
---
 gcc/config/riscv/riscv.cc  | 17 +++
 gcc/config/riscv/riscv.h   | 17 +++
 gcc/testsuite/gcc.target/riscv/stack-check-14.c| 24 ++
 gcc/testsuite/gcc.target/riscv/stack-check-15.c| 21 +++
 .../gcc.target/riscv/stack-check-alloca-1.c| 15 ++
 .../gcc.target/riscv/stack-check-alloca-10.c   | 13 
 .../gcc.target/riscv/stack-check-alloca-2.c| 11 ++
 .../gcc.target/riscv/stack-check-alloca-3.c| 11 ++
 .../gcc.target/riscv/stack-check-alloca-4.c| 12 +++
 .../gcc.target/riscv/stack-check-alloca-5.c| 12 +++
 .../gcc.target/riscv/stack-check-alloca-6.c| 12 +++
 .../gcc.target/riscv/stack-check-alloca-7.c| 12 +++
 .../gcc.target/riscv/stack-check-alloca-8.c| 14 +
 .../gcc.target/riscv/stack-check-alloca-9.c| 13 
 .../gcc.target/riscv/stack-check-alloca.h  | 15 ++
 15 files changed, 219 insertions(+)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 034290617624..a1b09e865ea7 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -7248,6 +7248,10 @@ riscv_compute_frame_info (void)
 
   frame = &cfun->machine->frame;
 
+  /* Adjust the outgoing arguments size if required.  Keep it in sync with what
+ the mid-end is doing.  */
+  crtl->outgoing_args_size = STACK_DYNAMIC_OFFSET (cfun);
+
   /* In an interrupt function, there are two cases in which t0 needs to be 
used:
  1, If we have a large frame, then we need to save/restore t0.  We check 
for
  this before clearing the frame struct.
@@ -11939,6 +11943,15 @@ riscv_c_mode_for_floating_type (enum tree_index ti)
   return default_mode_for_floating_type (ti);
 }
 
+/* On riscv we have an ABI defined safe buffer.  This constant is used to
+   determining the probe offset for alloca.  */
+
+static HOST_WIDE_INT
+riscv_stack_clash_protection_alloca_probe_range (void)
+{
+  return STACK_CLASH_CALLER_GUARD;
+}
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -12247,6 +12260,10 @@ riscv_c_mode_for_floating_type (enum tree_index ti)
 #define TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT \
   riscv_vectorize_preferred_vector_alignment
 
+#undef TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE
+#define TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE \
+  riscv_stack_clash_protection_alloca_probe_range
+
 /* Mode switching hooks.  */
 
 #undef TARGET_MODE_EMIT
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 58e17178212b..ead97867eb8e 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -1271,4 +1271,21 @@ extern void riscv_remove_unneeded_save_restore_calls 
(void);
generating stack clash probes.  */
 #define STACK_CLASH_MAX_UNROLL_PAGES 4
 
+/* This value represents the minimum amount of bytes we expect the function's
+   outgoing arguments to be when stack-clash is enabled.  */
+#define STACK_CLASH_MIN_BYTES_OUTGOING_ARGS 8
+
+/* Allocate a minimum of STACK_CLASH_MIN_BYTES_OUTGOING_ARGS bytes for the
+   outgoing arguments if stack clash p

[gcc r16-2028] sh: Recognize >> 31 in treg_set_expr_not_const01

2025-07-04 Thread Raphael Zinsly via Gcc-cvs
https://gcc.gnu.org/g:eda5a15909c315f0a4a7e76ad083f5f16cf1aef9

commit r16-2028-geda5a15909c315f0a4a7e76ad083f5f16cf1aef9
Author: Raphael Moreira Zinsly 
Date:   Mon Jun 23 10:40:50 2025 -0300

sh: Recognize >> 31 in treg_set_expr_not_const01

A right shift of 31 will become 0 or 1, this can be checked for
treg_set_expr_not_const01 to avoid matching addc_t_r as this
can expand to a 3 insn sequence instead.
This improves tests 023 to 026 from gcc.target/sh/pr54236-2.c, e.g.:
test_023:
shllr5
mov #0,r1
mov r4,r0
rts
addcr1,r0

With this change:
test_023:
shllr5
movtr0
rts
add r4,r0

We noticed this while evaluating a patch to improve how we handle
selecting between two constants based on the output of a LT/GE 0
test.

gcc/ChangeLog:
* config/sh/predicates.md
(treg_set_expr_not_const01): call sh_recog_treg_set_expr_not_01
* config/sh/sh-protos.h
(sh_recog_treg_set_expr_not_01): New function
* config/sh/sh.cc (sh_recog_treg_set_expr_not_01): Likewise

gcc/testsuite/ChangeLog:
* gcc.target/sh/pr54236-2.c: Fix comments and expected output

Diff:
---
 gcc/config/sh/predicates.md |  4 +---
 gcc/config/sh/sh-protos.h   |  1 +
 gcc/config/sh/sh.cc | 17 +
 gcc/testsuite/gcc.target/sh/pr54236-2.c | 14 +++---
 4 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index 7349c97a2b56..e67ec8a23202 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -630,9 +630,7 @@
 ;; Same as treg_set_expr but disallow constants 0 and 1 which can be loaded
 ;; into the T bit.
 (define_predicate "treg_set_expr_not_const01"
-  (and (match_test "op != const0_rtx")
-   (match_test "op != const1_rtx")
-   (match_operand 0 "treg_set_expr")))
+  (match_test "sh_recog_treg_set_expr_not_01 (op, mode)"))
 
 ;; A predicate describing the T bit register in any form.
 (define_predicate "t_reg_operand"
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index c8cc19f4dc75..e78b6697a2b1 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -261,6 +261,7 @@ extern rtx_insn* sh_peephole_emit_move_insn (rtx dst, rtx 
src);
 
 extern bool sh_in_recog_treg_set_expr (void);
 extern bool sh_recog_treg_set_expr (rtx op, machine_mode mode);
+extern bool sh_recog_treg_set_expr_not_01 (rtx op, machine_mode mode);
 
 /* Result value of sh_split_treg_set_expr.  Contains the first insn emitted
and the optional trailing nott insn.  */
diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc
index 1bc34e0a3e39..09e4ff77c207 100644
--- a/gcc/config/sh/sh.cc
+++ b/gcc/config/sh/sh.cc
@@ -12348,6 +12348,23 @@ sh_recog_treg_set_expr (rtx op, machine_mode mode)
   return result >= 0;
 }
 
+/* Return TRUE if OP is an expression for which there is a pattern to
+   set the T bit unless the expression is trivially loadable into
+   the T bit, FALSE otherwise.  */
+bool
+sh_recog_treg_set_expr_not_01 (rtx op, machine_mode mode)
+{
+  if (op == const0_rtx || op == const1_rtx)
+return false;
+
+  /* A right shift of 31 will return 0 or 1.  */
+  if ((GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFTRT)
+  && INTVAL (XEXP (op, 1)) == 31)
+return false;
+
+  return sh_recog_treg_set_expr (op, mode);
+}
+
 /* Returns true when recog of a 'treg_set_expr' is currently in progress.
This can be used as a condition for insn/split patterns to allow certain
T bit setting patters only to be matched as sub expressions of other
diff --git a/gcc/testsuite/gcc.target/sh/pr54236-2.c 
b/gcc/testsuite/gcc.target/sh/pr54236-2.c
index 1e2f3bbcb56c..78befe437701 100644
--- a/gcc/testsuite/gcc.target/sh/pr54236-2.c
+++ b/gcc/testsuite/gcc.target/sh/pr54236-2.c
@@ -4,10 +4,10 @@
 /* { dg-do compile }  */
 /* { dg-options "-O1" } */
 
-/* { dg-final { scan-assembler-times "addc" 36 } } */
+/* { dg-final { scan-assembler-times "addc" 32 } } */
 /* { dg-final { scan-assembler-times "shll" 14 } } */
-/* { dg-final { scan-assembler-times "add\tr" 12 } } */
-/* { dg-final { scan-assembler-not "movt" } } */
+/* { dg-final { scan-assembler-times "add\tr" 16 } } */
+/* { dg-final { scan-assembler-times "movt" 4 } } */
 
 /* { dg-final { scan-assembler-times "add\t#1" 1 } } */
 
@@ -184,28 +184,28 @@ test_022 (int a, int b, int c, int d)
 int
 test_023 (int a, int b, int c, int d)
 {
-  // 1x shll, 1x addc
+  // 1x shll, 1x add
   return a + ((b >> 31) & 1);
 }
 
 int
 test_024 (int a, int b, int c, int d)
 {
-  // 1x shll, 1x addc
+  // 1x shll, 1x add
   return ((b >> 31) & 1) + a;
 }
 
 int
 test_025 (int a, int b, int c, int d)
 {
-  // 1x shll, 1x addc
+  // 1x shll, 1x add
   return ((a >> 31) & 1) + a;
 }
 
 int
 test_026 (int a, int b, int c, int d)
 {
-  // 1x shll, 1x ad