]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR116587][LRA]: Fix last chance reload pseudo allocation
authorVladimir N. Makarov <vmakarov@redhat.com>
Wed, 20 Nov 2024 19:25:41 +0000 (14:25 -0500)
committerVladimir N. Makarov <vmakarov@redhat.com>
Wed, 20 Nov 2024 19:30:33 +0000 (14:30 -0500)
On i686 PR116587 test compilation resulted in LRA failure to find
registers for a reload insn pseudo.  The insn requires 6 regs for 4
reload insn pseudos where two of them require 2 regs each.  But we
have only 5 free regs as sp is a fixed reg, bp is fixed because of
-fno-omit-frame-pointer, bx is assigned to pic_offset_table_pseudo
because of -fPIC.  LRA spills pic_offset_table_pseudo as the last
chance approach to allocate registers to the reload pseudo.  Although
it makes 2 free registers for the unallocated reload pseudo requiring
also 2 regs, the pseudo still can not be allocated as the 2 free regs
are disjoint.  The patch spills all pseudos conflicting with the
unallocated reload pseudo including already allocated reload insn
pseudos, then standard LRA code allocates spilled pseudos requiring
more one register first and avoid situation of the disjoint regs for
reload pseudos requiring more one reg.

gcc/ChangeLog:

PR target/116587
* lra-assigns.cc (find_all_spills_for): Consider all pseudos whose
classes intersect given pseudo class.

gcc/testsuite/ChangeLog:

PR target/116587
* gcc.target/i386/pr116587.c: New test.

gcc/lra-assigns.cc
gcc/testsuite/gcc.target/i386/pr116587.c [new file with mode: 0644]

index bcd7967ec7d999e0016b16466195ac70b41cee48..0a14bde5e743c54673bd7f89db3047ce31ac822e 100644 (file)
@@ -1362,14 +1362,7 @@ find_all_spills_for (int regno)
            {
              if (live_pseudos_reg_renumber[r2->regno] >= 0
                  && ! sparseset_bit_p (live_range_hard_reg_pseudos, r2->regno)
-                 && rclass_intersect_p[regno_allocno_class_array[r2->regno]]
-                 && ((int) r2->regno < lra_constraint_new_regno_start
-                     || bitmap_bit_p (&lra_inheritance_pseudos, r2->regno)
-                     || bitmap_bit_p (&lra_split_regs, r2->regno)
-                     || bitmap_bit_p (&lra_optional_reload_pseudos, r2->regno)
-                     /* There is no sense to consider another reload
-                        pseudo if it has the same class.  */
-                     || regno_allocno_class_array[r2->regno] != rclass))
+                 && rclass_intersect_p[regno_allocno_class_array[r2->regno]])
                sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno);
            }
        }
diff --git a/gcc/testsuite/gcc.target/i386/pr116587.c b/gcc/testsuite/gcc.target/i386/pr116587.c
new file mode 100644 (file)
index 0000000..0928300
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC -mstackrealign -mavx512f -fharden-control-flow-redundancy -fno-omit-frame-pointer -mbmi -fkeep-gc-roots-live" } */
+
+typedef __UINT64_TYPE__ a;
+int b;
+struct c {
+  a d;
+};
+extern char e[];
+int f;
+void g();
+char *h(struct c *i, a d) {
+  while (b) {
+    if ((i->d & d) == i->d) {
+      if (f)
+        g();
+      g();
+      d &= ~i->d;
+    }
+    ++i;
+  }
+  if (d)
+    g();
+  if (f)
+    return "";
+  return e;
+}