Xi Ruoyao <[email protected]> writes:

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

LGTM, please apply and backport to gcc16.

>
>> 
>>  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));
>> +}

Reply via email to