On Wed, Jul 15, 2026 at 8:27 PM John Paul Adrian Glaubitz <[email protected]> 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.
I'm not sure the rationale is sound, but then I'd say if you add a proper testcase then Vlad can pick up from here. Richard. > 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. > > Adrian > > -- > .''`. John Paul Adrian Glaubitz > : :' : Debian Developer > `. `' Physicist > `- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
