https://gcc.gnu.org/g:b7f137e56867dd3aa1f05f3409f146391dec131c
commit r16-5499-gb7f137e56867dd3aa1f05f3409f146391dec131c 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. 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 82cf0a829bf1..d843226c8c86 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -4960,7 +4960,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); +}
