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),
