https://gcc.gnu.org/g:644ffc679dbbb061a1269dada78f2015bc961074

commit r17-5482-g644ffc679dbbb061a1269dada78f2015bc961074
Author: Robin Dapp <[email protected]>
Date:   Tue Oct 13 21:25:19 2026 +0200

    lra: Handle subregs in get_dependent_filter.
    
    Before, we would just look through subregs without adjusting the regno
    but still pass the outer mode to the evaluation function of a dependent
    filter.  This obviously causes problems that we cannot work around in
    the filters themselves.
    
    Therefore, this patch uses simplify_subreg_regno to get the actual hard
    regno the subreg refers to and passes that to lra_get_dependent_filter.
    I was struggling a bit with what to do if we cannot find simplify the
    subreg down to a hard regno, so the patch just asserts that we can.
    
    This doesn't have a test yet but will be exercised by Pan Li's posted
    patch set in pr112431-60.c.
    
    gcc/ChangeLog:
    
            * lra-constraints.cc (get_dependent_filter): Handle subregs
            properly.
            * ira-lives.cc (process_dependent_filters): Don't look through
            subregs.

Diff:
---
 gcc/ira-lives.cc       |  4 ----
 gcc/lra-constraints.cc | 28 +++++++++++++++++++++-------
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/gcc/ira-lives.cc b/gcc/ira-lives.cc
index 7b9c03e91ad6..98279bec6f11 100644
--- a/gcc/ira-lives.cc
+++ b/gcc/ira-lives.cc
@@ -1196,8 +1196,6 @@ process_dependent_filters ()
   for (int opno = 0; opno < recog_data.n_operands; ++opno)
     {
       rtx op = recog_data.operand[opno];
-      if (SUBREG_P (op))
-       op = SUBREG_REG (op);
       if (!REG_P (op) || HARD_REGISTER_P (op))
        continue;
 
@@ -1226,8 +1224,6 @@ process_dependent_filters ()
              if (ref_opno < 0 || ref_opno >= recog_data.n_operands)
                continue;
              rtx ref_op = recog_data.operand[ref_opno];
-             if (SUBREG_P (ref_op))
-               ref_op = SUBREG_REG (ref_op);
              if (!REG_P (ref_op))
                continue;
 
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 60321b7a458a..2aa3b296f49d 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -2364,23 +2364,37 @@ get_dependent_filter (constraint_num cn, machine_mode 
mode)
   gcc_assert (ref_opno >= 0 && ref_opno < curr_static_id->n_operands);
 
   rtx ref_op = *curr_id->operand_loc[ref_opno];
-  if (SUBREG_P (ref_op))
-     ref_op = SUBREG_REG (ref_op);
-  if (!REG_P (ref_op))
+
+  rtx inner = SUBREG_P (ref_op) ? SUBREG_REG (ref_op) : ref_op;
+
+  if (!REG_P (inner))
     return nullptr;
-  unsigned int ref_regno = REGNO (ref_op);
+
+  int ref_regno = REGNO (inner);
+
   if (ref_regno >= FIRST_PSEUDO_REGISTER)
     {
-      int ref_hard_regno = reg_renumber[ref_regno];
+      ref_regno = reg_renumber[ref_regno];
       /* Even with a pseudo reference op, the filter can still reject
         based on the partner.  We call it with INVALID_REGNUM
         to give it a chance to do so.  Otherwise we'd introduce
         an "all choices legal" filter that might later
         "change its mind" once there is a fixed reference.  */
-      if (ref_hard_regno < 0)
+      if (ref_regno < 0)
        return lra_get_dependent_filter (id, mode, INVALID_REGNUM,
                                         GET_MODE (ref_op), false);
-      ref_regno = (unsigned int) ref_hard_regno;
+    }
+
+  /* For a subreg, get the actual regno.  */
+  if (SUBREG_P (ref_op))
+    {
+      int subreg_regno = simplify_subreg_regno
+       (ref_regno, GET_MODE (inner), SUBREG_BYTE (ref_op),
+        GET_MODE (ref_op), true);
+      /* The subreg should always map to a hard regno here.  */
+      gcc_assert (subreg_regno >= 0);
+
+      ref_regno = subreg_regno;
     }
 
   return lra_get_dependent_filter (id, mode, ref_regno, GET_MODE (ref_op),

Reply via email to