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);
+}

Reply via email to