https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120165
--- Comment #18 from Mikael Pettersson <mikpelinux at gmail dot com> ---
I've been looking at LRA for several days. The problem is as I wrote before:
The output reload insn 106 from the push insn 47 doesn't reflect the stack
pointer change from the push, and subsequent eliminations will not do so
either, causing the final instruction to write off-by-4 and clobber the return
address instead of updating the intended "ap" parameter.
The eliminations are done over several rounds / passes. First static
elimination offsets (e.g. argptr -> sp) and local sp adjustments (e.g. from
pushes) are applied, then incremental sp adjustments, and finally base pointer
replacements (e.g. argptr -> sp). The offsets in the insns are updated at each
step, meaning the insns don't say what exactly has been done to them. External
state (first_p and final_p) control the interpretation. (All of this is "as far
as I can tell".)
The output reload above doesn't even enter elimination until after the initial
round, and that's why the insn's sp offset isn't applied.
I tried adding an elimination exactly where the output reload is generated:
47: [--%sp:SI]=[r53:SI++]
REG_INC r43:SI
REG_ARGS_SIZE 0x4
Inserting insn reload before:
105: r53:SI=[%argptr:SI+0x14]
Inserting insn reload after:
106: [%argptr:SI+0x14]=r53:SI
fixing up REG_SIZE_NOTE for:
47: [--%sp:SI]=[r53:SI++]
REG_INC r43:SI
fixed insns after:
106: [%argptr:SI+0x14]=r53:SI
--- ./gcc/lra.cc.~1~ 2026-07-04 21:44:42.549682701 +0200
+++ ./gcc/lra.cc 2026-07-05 16:51:42.989561303 +0200
@@ -1991,6 +1991,7 @@ lra_process_new_insns (rtx_insn *insn, r
setup_sp_offset (after, last);
if (fixup_reg_args_size)
{
+ eliminate_regs_in_insn (after, false, false,
-lra_get_insn_recog_data (after)->sp_offset);
rtx note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
if (note)
{
That fixed the test case for m68k, but broke bootstrap on x86_64 and aarch64.
At this point I don't know where or how to fix this bug.