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]>

Reply via email to