https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125049
Bug ID: 125049
Summary: [loongarch] SSP fallback leaves __stack_chk_guard live
in $r12 at `jr $r1`
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: 220245569 at seu dot edu.cn
Target Milestone: ---
Created attachment 64296
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64296&action=edit
Use Loongarch64 cross-compiler to compile trigger.c with `-O2
-fstack-protector-all -S -o trigger-loongarch64.s`
Summary
-------
Child of meta-bug PR 125045. The LoongArch backend in gcc-16.1 provides
no `stack_protect_set` / `stack_protect_test` pattern, so SSP lowering
falls through to the generic `emit_move_insn` / `emit_cmp_and_jump_insns`
path in `gcc/cfgexpand.cc::stack_protect_prologue` and
`gcc/function.cc::stack_protect_epilogue`.
The resulting epilogue
leaves the register that held `__stack_chk_guard` live across the
function return.
Reproducer
----------
Files attached: `trigger.c`, `build.sh`, `trigger-loongarch64.s`.
Build:
loongarch64-linux-gnu-gcc -O2 -fstack-protector-all -S -o
trigger-loongarch64.s trigger.c
Observed (gcc-16.1.0-RC-20260424 `loongarch64-linux-gnu`
cross compiler, epilogue of `f`):
la.global $r23,__stack_chk_guard
ldptr.d $r12,$r23,0 ; load expected canary -> $r12
...
st.d $r12,$r3,72 ; save frame canary copy
...
ld.d $r13,$r3,72 ; reload frame canary
ldptr.d $r12,$r23,0 ; reload expected canary -> $r12
bne $r13,$r12,.L5 ; branch to __stack_chk_fail
ld.d $r1,$r3,88
ld.d $r23,$r3,80
addi.d $r3,$r3,96
jr $r1 ; returns with $r12 == __stack_chk_guard
No `or $r12,$r0,$r0`, `move $r12,$zero`, or equivalent zero-write to
`$r12` appears between `bne` and `jr $r1`.