https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128036
--- Comment #1 from JingYao Zhang <220245569 at seu dot edu.cn> ---
Gentle ping on this issue (and thank you @rguenth for tagging `wrong-code`).
Adding concrete context on the exact fix in `gcc/config/loongarch/loongarch.cc`
and its interaction with the existing LoongArch stack-clash testsuite:
### Fix Location in `gcc/config/loongarch/loongarch.cc`
In `loongarch_emit_probe_stack_range`
(`gcc/config/loongarch/loongarch.cc:1229-1245`), Step 4 adjusts `$r3`
(`stack_pointer_rtx`) for the residual `size - rounded_size`, under the
comment:
```c
/* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
that SIZE is equal to ROUNDED_SIZE. */
if (size != rounded_size)
{
if (size - rounded_size >= 2048)
{
emit_move_insn (r14, GEN_INT (size - rounded_size));
emit_insn (gen_rtx_SET (stack_pointer_rtx,
gen_rtx_MINUS (Pmode, stack_pointer_rtx,
r14)));
}
else
emit_insn (gen_rtx_SET (stack_pointer_rtx,
gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT
(rounded_size - size))));
}
```
However, neither branch emits `emit_stack_probe (stack_pointer_rtx)` (nor a
stack tie) after lowering `$r3`. When `size - rounded_size` is large (up to
`PROBE_INTERVAL - 1`, e.g. 4064 bytes with a 4 KiB guard) and `caller` invokes
a `leaf` function whose frame is `< PROBE_INTERVAL` (which also skips probing
under `NO_PROBE_SMALL_FRAME`), the combined unprobed span across the call
boundary reaches `8144` bytes (`> 1.99` guard pages), completely jumping over a
4 KiB guard page.
Emitting `emit_stack_probe (stack_pointer_rtx)` when the residual exceeds
`STACK_CLASH_CALLER_GUARD` (or unconditionally at `FIRST + SIZE` as the Step 4
comment states) closes this cross-call gap. Note that
`gcc/testsuite/gcc.target/loongarch/stack-check-prologue-{2,5,7}.c` currently
expect the unprobed Step-4 residual count and would need their
`scan-assembler-times` updated accordingly.