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

Reply via email to