On Thu, 2026-06-18 at 06:41 +0800, Xi Ruoyao wrote:
> I completely forgot ILP32 when I wrote those routines.
>
> gcc/
>
> * config/loongarch/loongarch.md
> (@stack_protect_combined_set_normal_<mode>): Replace `st.d'
> with `st.<d>', reject stptr.d on LA32 with enabled attribute.
> (@stack_protect_combined_test_internal_<mode>): Replace
> `ld.d'
> with `ld.<d>', reject ldptr.d on LA32 with enabled attribute.
> (@stack_protect_combined_set_extreme_<mode>): Rename to ...
> (stack_protect_combined_set_extreme): ... here. Force
> DImode.
> Add TARGET_ABI_LP64 as the condition.
> (stack_protect_combined_set): Adapt for the change of
> stack_protect_combined_set_extreme.
>
> gcc/testsuite/
>
> * gcc.target/loongarch/ssp-ilp32.c: New test.
> ---
>
> Change since v1: disable the alternatives using ldptr/stptr for LA32.
>
> I originally intended to add a new constrant for ldptr/stptr, but to
> make the differential really useful we need to tell the compiler some
> memory operands are legitimate for atomic operations but not for other
> memory operations. Doing so will need to massively change the
> target-independent code. Considering we need a fix that we can easily
> backport to GCC 16, just disable the alternatives ad-hoc.
>
> Bootstrapped and regtested on loongarch64-linux-gnu. Ok for trunk?
Ping.
>
> gcc/config/loongarch/loongarch.md | 44 ++++++++++++------
> -
> .../gcc.target/loongarch/ssp-ilp32.c | 9 ++++
> 2 files changed, 37 insertions(+), 16 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/loongarch/ssp-ilp32.c
>
> diff --git a/gcc/config/loongarch/loongarch.md
> b/gcc/config/loongarch/loongarch.md
> index 5c4f8dfb5b5..37ae5a2223e 100644
> --- a/gcc/config/loongarch/loongarch.md
> +++ b/gcc/config/loongarch/loongarch.md
> @@ -5057,19 +5057,25 @@ (define_insn
> "@stack_protect_combined_set_normal_<mode>"
> ""
> {
> loongarch_output_asm_load_canary (operands[2], operands[1],
> NULL_RTX);
> - output_asm_insn (which_alternative ? "stptr.d\t%2,%0" :
> "st.d\t%2,%0",
> + output_asm_insn (which_alternative ? "stptr.d\t%2,%0"
> + : "st.<d>\t%2,%0",
> operands);
> return "ori\t%2,$r0,0";
> }
> [(set_attr "type" "store")
> - (set_attr "length" "20")])
> -
> -(define_insn "@stack_protect_combined_set_extreme_<mode>"
> - [(set (match_operand:P 0 "memory_operand" "=m,ZC")
> - (unspec:P [(mem:P (match_operand:P 1 "ssp_operand"))]
> UNSPEC_SSP))
> - (set (match_scratch:P 2 "=&r,&r") (const_int 0))
> - (set (match_scratch:P 3 "=&r,&r") (const_int 0))]
> - ""
> + (set_attr "length" "20")
> + (set (attr "enabled")
> + (if_then_else
> + (match_test "!which_alternative || TARGET_64BIT")
> + (const_string "yes")
> + (const_string "no")))])
> +
> +(define_insn "stack_protect_combined_set_extreme"
> + [(set (match_operand:DI 0 "memory_operand" "=m,ZC")
> + (unspec:DI [(mem:DI (match_operand:DI 1 "ssp_operand"))]
> UNSPEC_SSP))
> + (set (match_scratch:DI 2 "=&r,&r") (const_int 0))
> + (set (match_scratch:DI 3 "=&r,&r") (const_int 0))]
> + "TARGET_ABI_LP64"
> {
> loongarch_output_asm_load_canary (operands[2], operands[1],
> operands[3]);
> output_asm_insn (which_alternative ? "stptr.d\t%2,%0" :
> "st.d\t%2,%0",
> @@ -5092,12 +5098,17 @@ (define_insn
> "@stack_protect_combined_test_internal_<mode>"
> rtx t = (which_alternative >= 2 ? operands[0] : NULL_RTX);
> loongarch_output_asm_load_canary (operands[3], operands[2], t);
> output_asm_insn ((which_alternative & 1) ? "ldptr.d\t%0,%1"
> - : "ld.d\t%0,%1",
> + : "ld.<d>\t%0,%1",
> operands);
> return "xor\t%0,%0,%3\n\tori\t%3,$r0,0";
> }
> [(set_attr "type" "load,load,load,load")
> - (set_attr "length" "24,24,36,36")])
> + (set_attr "length" "24,24,36,36")
> + (set (attr "enabled")
> + (if_then_else
> + (match_test "!(which_alternative & 1) || TARGET_64BIT")
> + (const_string "yes")
> + (const_string "no")))])
>
> (define_expand "stack_protect_combined_set"
> [(match_operand 0 "memory_operand")
> @@ -5105,11 +5116,12 @@ (define_expand "stack_protect_combined_set"
> ""
> {
> rtx canary = XEXP (operands[1], 0);
> - auto fn = (ssp_normal_operand (canary, VOIDmode)
> - ? gen_stack_protect_combined_set_normal
> - : gen_stack_protect_combined_set_extreme);
> -
> - emit_insn (fn (Pmode, operands[0], canary));
> + if (ssp_normal_operand (canary, VOIDmode))
> + emit_insn (gen_stack_protect_combined_set_normal (Pmode,
> operands[0],
> + canary));
> + else
> + emit_insn (gen_stack_protect_combined_set_extreme (operands[0],
> + canary));
> DONE;
> })
>
> diff --git a/gcc/testsuite/gcc.target/loongarch/ssp-ilp32.c
> b/gcc/testsuite/gcc.target/loongarch/ssp-ilp32.c
> new file mode 100644
> index 00000000000..1bdb61bfc72
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/loongarch/ssp-ilp32.c
> @@ -0,0 +1,9 @@
> +/* { dg-options "-march=la32v1.0 -mabi=ilp32s -fstack-protector-
> strong" } */
> +/* { dg-final { scan-assembler-not "ld\\\.d" } } */
> +/* { dg-final { scan-assembler-not "st\\\.d" } } */
> +
> +void test()
> +{
> + int x;
> + asm("":"+m"(x));
> +}
--
Xi Ruoyao <[email protected]>