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.


Reply via email to