On 7/15/26 2:27 PM, John Paul Adrian Glaubitz wrote:
Hi Richard,
On Wed, 2026-07-15 at 09:07 +0200, Richard Biener wrote:
I have had a go with Google Gemini at PR target/121847 [1] and it came
up with a working fix on first attempt. The fix is trivial and requires
patching just a few lines in the function get_matching_reload_reg_subreg()
in gcc/lra-constraints.cc.
I don't want to share the patch at the moment as LLM contributions aren't
in GCC at the moment from my understanding, so I would like to ask what
kind of input is allowed.
Can I share a description of the bug and the solution without posting the
actual patch?
I think you can share the actual patch as well, just don't expect it to be
merged unless you can explain it yourself at least.
The actual patch is rather simple:
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -694,14 +694,16 @@ get_matching_reload_reg_subreg (machine_mode mode, rtx
reg,
enum reg_class rclass)
{
int hard_regno = ira_class_hard_regs[rclass][0];
+ rtx res;
if (subreg_regno_offset (hard_regno,
GET_MODE (reg),
subreg_lowpart_offset (mode, GET_MODE (reg)),
- mode) == 0)
+ mode) == 0
+ && (res = lowpart_subreg (mode, reg, GET_MODE (reg))) != NULL_RTX)
/* For matching scalar int modes generate the right subreg byte offset for
BE targets -- see call of reload.cc:operands_match_p in
recog.cc:constrain_operands. */
- return lowpart_subreg (mode, reg, GET_MODE (reg));
+ return res;
int offset = (lra_constraint_offset (hard_regno, GET_MODE (reg))
- lra_constraint_offset (hard_regno, mode)) * UNITS_PER_WORD;
lra_assert (offset >= 0);
The explanation for the crash as provided by the LLM is:
===================================================================================
The root cause of this crash is a clash between LRA's reload subreg
generation and
the strict RTL validation rules in emit-rtl.cc:validate_subreg, specifically
regarding
alignment requirements for mismatched floating-point modes on big-endian
targets.
The Mechanism of the Failure:
1. In s_cexp.i, the inline assembly forces a DFmode (8 bytes) input and an
XFmode
(12 bytes) output to match and share the same hardware floating-point
register.
2. During constraint matching (lra-constraints.cc:match_reload), LRA
attempts to
generate a matching reload subreg via get_matching_reload_reg_subreg.
3. For m68k FP registers, m68k_hard_regno_nregs returns 1 for both DFmode
and XFmode.
Because both modes occupy exactly 1 hard register, subreg_regno_offset
evaluates to 0.
4. Seeing a regno offset of 0, get_matching_reload_reg_subreg attempts to
create a
mathematical lowpart subreg by calling lowpart_subreg(DFmode,
reg(XFmode), XFmode).
5. On a big-endian target, the mathematical lowpart byte offset for
extracting 8 bytes
from a 12-byte mode is 4 (12 - 8 = 4).
6. The RTL validator (validate_subreg) strictly rejects (subreg:DF (reg:XF)
4). Specifically,
it enforces that the subreg byte offset must be a multiple of the outer
mode's size (offset
% osize == 0). Since 4 % 8 != 0, validation fails.
The Crash:
* In older revisions (as seen in the original stack trace),
gen_lowpart_SUBREG was used,
which blindly passed the invalid offset 4 into gen_rtx_SUBREG,
immediately tripping the
gcc_assert(validate_subreg(...)) and causing the ICE.
* In the current trunk (after the PR124079 refactor), lowpart_subreg safely
returns NULL_RTX
when validation fails. However, get_matching_reload_reg_subreg returns
this NULL_RTX directly
to match_reload, where the LRA_SUBREG_P (new_out_reg) = 1 macro
dereferences the null pointer,
causing a segmentation fault.
The Solution:
The logic in get_matching_reload_reg_subreg needs to gracefully handle the
case where lowpart_subreg
returns NULL_RTX due to RTL alignment validation failures.
If lowpart_subreg returns NULL_RTX, the function should fall back to the
standard lra_constraint_offset
path at the bottom of the function. For floating-point registers,
lra_constraint_offset yields an offset
of 0.
===================================================================================
Since all I did was pass the bug description to the LLM as well instructing it
to find
a solution, I don't claim authorship to that patch and also cannot say whether
the patch
is correct as my current GCC knowledge is still rather limited, although I'm
trying to
improve it.
Either way, I hope that the proposed patch will help find a proper solution so
we can
switch m68k over to using LRA by default.
The LLM explanation is too verbose. The patch is OK and trivial (I
probably would do the same). So I'd not worry that it is LLM generated.
You can just write own ChangeLog and submit me for approval (after
regular testing/bootstrapping on some major targets). I'll approve the
final variant.