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

openSUSE Build Service is sponsored by