https://gcc.gnu.org/g:1eb25bef88c58f5192042b9db45dc6ab6538ac52
commit 1eb25bef88c58f5192042b9db45dc6ab6538ac52 Author: Vladimir N. Makarov <[email protected]> Date: Fri Nov 21 11:49:31 2025 -0500 [PR118358, LRA]: Decrease pressure after issuing input reload insns LRA can generate sequence of reload insns for one input operand using intermediate pseudos. Register pressure when reload insn for another input operand is placed before the sequence is more than when the reload insn is placed after the sequence. The problem report reveals a case when several such sequences increase the pressure for input reload insns beyond available registers and as a consequence this results in LRA cycling. gcc/ChangeLog: PR target/118358 * lra-constraints.cc (curr_insn_transform): Move insn reloading constant into a register right before insn using it. gcc/testsuite/ChangeLog: PR target/118358 * gcc.target/xstormy16/pr118358.c: New. (cherry picked from commit b7f137e56867dd3aa1f05f3409f146391dec131c) Diff: --- gcc/lra-constraints.cc | 40 ++++++++++++ gcc/testsuite/gcc.target/xstormy16/pr118358.c | 90 +++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 2c477d1688eb..4cea5a609521 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -4954,7 +4954,47 @@ curr_insn_transform (bool check_only_p) } lra_assert (done_p); } + int const_regno = -1; + rtx set; + rtx_insn *prev, *const_insn = NULL; + if (before != NULL_RTX && (prev = PREV_INSN (curr_insn)) != NULL_RTX + && (set = single_set (prev)) != NULL_RTX && CONSTANT_P (SET_SRC (set))) + { + rtx reg = SET_DEST (set); + if (GET_CODE (reg) == SUBREG) + reg = SUBREG_REG (reg); + /* Consider only reload insns as we don't want to change the order + created by previous optimizations. */ + if (REG_P (reg) && (int) REGNO (reg) >= lra_new_regno_start + && bitmap_bit_p (&lra_reg_info[REGNO (reg)].insn_bitmap, + INSN_UID (curr_insn))) + { + const_regno = REGNO (reg); + const_insn = prev; + } + } lra_process_new_insns (curr_insn, before, after, "Inserting insn reload"); + if (const_regno >= 0) { + bool move_p = true; + for (rtx_insn *insn = before; insn != curr_insn; insn = NEXT_INSN (insn)) + if (bitmap_bit_p (&lra_reg_info[const_regno].insn_bitmap, + INSN_UID (insn))) + { + move_p = false; + break; + } + if (move_p) + { + reorder_insns_nobb (const_insn, const_insn, PREV_INSN (curr_insn)); + if (lra_dump_file != NULL) + { + dump_insn_slim (lra_dump_file, const_insn); + fprintf (lra_dump_file, + " to decrease reg pressure, it is moved before:\n"); + dump_insn_slim (lra_dump_file, curr_insn); + } + } + } return change_p; } diff --git a/gcc/testsuite/gcc.target/xstormy16/pr118358.c b/gcc/testsuite/gcc.target/xstormy16/pr118358.c new file mode 100644 index 000000000000..0743a023586d --- /dev/null +++ b/gcc/testsuite/gcc.target/xstormy16/pr118358.c @@ -0,0 +1,90 @@ +/* PR target/118358. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern void exit (int); + +typedef struct +{ + union + { + struct + { + unsigned char a3; + unsigned char a4; + } a2; + unsigned int a5; + } a0; + unsigned int a1; +} A; + +static int +foo (unsigned int *b, unsigned int n, unsigned int s, const unsigned int *d, + const unsigned int *e, A **t, unsigned int *m, A *hp, unsigned int *hn, + unsigned int *v) +{ + unsigned int a, c[15 + 1], f; + int g, h; + unsigned int i, j, k; + int l; + unsigned int ee; + unsigned int *p; + A *q, r, *u[15]; + int w; + unsigned int x[15 + 1], *xx; + int y; + unsigned int z; + for (j = 1; j <= 15; j++) + if (c[j]) + break; + if ((unsigned int) l < j) + l = j; + for (i = 15; i; i--) + if (c[i]) + break; + g = i; + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return -3; + h = -1; + z = 0; + for (; k <= g; k++) + { + while (k > w + l) + { + h++; + w += l; + if ((f = 1 << (j = k - w)) > a + 1) + ; + z = 1 << j; + if (*hn + z > 1440) + return -3; + u[h] = q = hp + *hn; + r.a0.a2.a4 = (unsigned char) l; + r.a1 = (unsigned int) (q - u[h - 1] - j); + } + for (j = i >> w; j < z; j += f) + q[j] = r; + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + while ((i & ee) != x[h]) + { + h--; + w -= l; + } + } + return y != 0 && g != 1 ? (-5) : 0; +} + +unsigned int a[19] = { 3, 4, 0, 2, 2, [17] = 3, 3 }; +unsigned int d[19]; +A h[1440]; + +int +main (void) +{ + unsigned int b = 0, c = 0; + A *e = 0; + foo (a, 19, 19, 0, 0, &e, &b, h, &c, d); + exit (0); +}
