File pr124439.patch of Package gcc16
From 5a16651495171d8e6f60df29757f2b396e30a2d5 Mon Sep 17 00:00:00 2001
From: "Vladimir N. Makarov" <vmakarov@redhat.com>
Date: Wed, 18 Mar 2026 15:12:00 -0400
Subject: [PATCH] [PR124041, PR124439, LRA]: Check hard_regno_mode_ok for hard
reg subreg to satisfy reg constraint
Patch for PR124041 resulted in wrong code generation and in new
PR124439 as the patch prevented equivalence substitution when
equivalence initialization insn was removed.
This patch implements another fix for PR124041 and this fixes
PR124439.
gcc/ChangeLog:
PR rtl-optimization/124041
PR rtl-optimization/124439
* lra-constraints.cc (process_alt_operands): Check hard reg subreg
mode by hard_regno_mode_ok.
(curr_insn_transform): Always subsitute equivalence for hard reg
subreg.
---
gcc/lra-constraints.cc | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 77b221f136d..e24b56675eb 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -2741,7 +2741,14 @@ process_alt_operands (int only_alternative)
winreg = true;
if (REG_P (op))
{
+ rtx orig_op = *curr_id->operand_loc[nop];
+ if (GET_CODE (orig_op) == SUBREG && HARD_REGISTER_P (op)
+ && !targetm.hard_regno_mode_ok (REGNO (op),
+ GET_MODE(orig_op)))
+ break;
+
tree decl;
+
if (hard_regno[nop] >= 0
&& in_hard_reg_set_p (this_alternative_set,
mode, hard_regno[nop])
@@ -4402,23 +4409,12 @@ curr_insn_transform (bool check_only_p)
continue;
old = op = *curr_id->operand_loc[i];
- machine_mode outer_mode = GET_MODE (old);
- bool subreg_p = false;
if (GET_CODE (old) == SUBREG)
- {
- old = SUBREG_REG (old);
- subreg_p = true;
- }
+ old = SUBREG_REG (old);
subst = get_equiv_with_elimination (old, curr_insn);
original_subreg_reg_mode[i] = VOIDmode;
equiv_substition_p[i] = false;
- /* If we are about to replace a register inside a subreg, check if
- the target can handle that. */
- if (subreg_p && REG_P (subst) && HARD_REGISTER_P (subst)
- && !targetm.hard_regno_mode_ok (REGNO (subst), outer_mode))
- continue;
-
if (subst != old
/* We don't want to change an out operand by constant or invariant
which will require additional reloads, e.g. by putting a constant
--
2.53.0