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