https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128395
Bug ID: 128395
Summary: [sparc] load from the function's own frame placed in
the delay slot of return
Product: gcc
Version: 16.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: stian at itx dot no
Target Milestone: ---
Target: sparc64-unknown-linux-gnu
Created attachment 66076
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=66076&action=edit
rdc4.c
On sparc64 with -O2 -fno-stack-protector, returning an element of a local array
indexed by
an argument gives
return %i7+8
ldx [%o0+1999], %o0
The delay slot runs after the window restore, so this reads the dead frame
below the new
%sp. A signal or trap taken on that instruction overwrites it and the load
returns garbage.
rds4.c (compile with -O2 -fno-stack-protector, see cpu_clock_sample_group in
the -S output)
reproduces it at runtime with SIGALRM at 10 kHz (about 150
wrong results in 60 million calls on an M7). The Linux sparc64 kernel is built
this way and
cpu_clock_sample_group() in kernel/time/posix-cpu-timers.c gets exactly this
sequence, so
clock_gettime(CLOCK_PROCESS_CPUTIME_ID) returns a trap's TSTATE about once a
second. A
kernel built with the patched compiler does not.
eligible_for_restore_insn() accepts any insn without local or output registers
in the return
case, including a load through an incoming register that now holds a frame
address. The
patch allows a memory reference there only when every address register is an
unmodified
incoming argument register, which keeps "return p->field". Tested on
sparc64-unknown-linux-gnu, new test gcc.target/sparc/return-delay-mem.c, no
change in
sparc.exp.