From: Vladimir N. Makarov Date: Fri, 13 Feb 2026 18:58:41 +0000 (-0500) Subject: [PR124079, LRA]: Fix broken s390 SPEC2017 benchmarks X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=498983d96193517a4854deb2775dc4478063199c;p=thirdparty%2Fgcc.git [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); +}