[gcc r15-3092] RISC-V: Fix vector cfi notes for stack-clash protection
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
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
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
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
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
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
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