The following patch fixes

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124079

The patch was successfully tested on sparc64 and bootstrapped and tested on x86-64, aarch64, ppc64be.

commit 498983d96193517a4854deb2775dc4478063199c
Author: Vladimir N. Makarov <[email protected]>
Date:   Fri Feb 13 13:58:41 2026 -0500

    [PR124079, LRA]: Fix broken s390 SPEC2017 benchmarks
    
    Recent patch for PR121191 broke compilation of s390 SPEC benchmarks.
    This patch fixes it.  The patch uses existing lra_constraint_offset to
    calculate offsets.  The same function is used to find invalid matching
    reloads.
    
    gcc/ChangeLog:
    
            PR rtl-optimization/124079
            * lra-constraints.cc (get_matching_reload_reg_subreg): Add new arg
            rclass.  Use another condition to use lowpart_subreg.  Use lra_constraint_offset
            to calculate the subreg offset.
            (get_reload_reg, match_reload): Pass the new arg.
    
    gcc/testsuite/ChangeLog:
    
            PR rtl-optimization/124079
            * gcc.target/s390/pr124079.c: New.

diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 8c8c9d69a96..2b5b4ba1bbd 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -682,16 +682,25 @@ canonicalize_reload_addr (rtx addr)
   return addr;
 }
 
-/* Return rtx accessing reload REG matching another reload reg in MODE.  */
+/* Return rtx accessing reload REG of RCLASS matching another reload reg in
+   MODE.  */
 static rtx
-get_matching_reload_reg_subreg (machine_mode mode, rtx reg)
+get_matching_reload_reg_subreg (machine_mode mode, rtx reg,
+				enum reg_class rclass)
 {
-  if (SCALAR_INT_MODE_P (mode) && SCALAR_INT_MODE_P (GET_MODE (reg)))
+  int hard_regno = ira_class_hard_regs[rclass][0];
+  if (subreg_regno_offset (hard_regno,
+			   GET_MODE (reg),
+			   subreg_lowpart_offset (mode, GET_MODE (reg)),
+			   mode) == 0)
     /* 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 gen_rtx_SUBREG (mode, reg, 0);
+  int offset = (lra_constraint_offset (hard_regno, GET_MODE (reg))
+		- lra_constraint_offset (hard_regno, mode)) * UNITS_PER_WORD;
+  lra_assert (offset >= 0);
+  return gen_rtx_SUBREG (mode, reg, offset);
 }
 
 /* Create a new pseudo using MODE, RCLASS, EXCLUDE_START_HARD_REGS, ORIGINAL or
@@ -778,7 +787,7 @@ get_reload_reg (enum op_type type, machine_mode mode, rtx original,
 		if (maybe_lt (GET_MODE_SIZE (GET_MODE (reg)),
 			      GET_MODE_SIZE (mode)))
 		  continue;
-		reg = get_matching_reload_reg_subreg (mode, reg);
+		reg = get_matching_reload_reg_subreg (mode, reg, new_class);
 		if (reg == NULL_RTX || GET_CODE (reg) != SUBREG)
 		  continue;
 	      }
@@ -1146,7 +1155,7 @@ match_reload (signed char out, signed char *ins, signed char *outs,
 	    = lra_create_new_reg_with_unique_value (inmode, in_rtx, goal_class,
 						    exclude_start_hard_regs,
 						    "");
-	  new_out_reg = get_matching_reload_reg_subreg (outmode, reg);
+	  new_out_reg = get_matching_reload_reg_subreg (outmode, reg, goal_class);
 	  LRA_SUBREG_P (new_out_reg) = 1;
 	  /* If the input reg is dying here, we can use the same hard
 	     register for REG and IN_RTX.  We do it only for original
@@ -1165,7 +1174,7 @@ match_reload (signed char out, signed char *ins, signed char *outs,
 						    goal_class,
 						    exclude_start_hard_regs,
 						    "");
-	  new_in_reg = get_matching_reload_reg_subreg (inmode, reg);
+	  new_in_reg = get_matching_reload_reg_subreg (inmode, reg, goal_class);
 	  /* NEW_IN_REG is non-paradoxical subreg.  We don't want
 	     NEW_OUT_REG living above.  We add clobber clause for
 	     this.  This is just a temporary clobber.  We can remove
diff --git a/gcc/testsuite/gcc.target/s390/pr124079.c b/gcc/testsuite/gcc.target/s390/pr124079.c
new file mode 100644
index 00000000000..6b5ad0caa6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr124079.c
@@ -0,0 +1,8 @@
+/* PR rtl-optimization/124079 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z13" } */
+
+int foo (const char *a, const char *b)
+{
+  return __builtin_strcmp (a, b);
+}

Reply via email to