]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[committed][PR rtl-optimization/116544] Fix test for promoted subregs
authorJeff Law <jlaw@ventanamicro.com>
Mon, 2 Sep 2024 04:16:04 +0000 (22:16 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Mon, 2 Sep 2024 04:18:29 +0000 (22:18 -0600)
This is a small bug in the ext-dce code's handling of promoted subregs.

Essentially when we see a promoted subreg we need to make additional bit groups
live as various parts of the RTL path know that an extension of a suitably
promoted subreg can be trivially eliminated.

When I added support for dealing with this quirk I failed to account for the
larger modes properly and it ignored the case when the size of the inner object
was > 32 bits.  Opps.

This does _not_ fix the outstanding x86 issue.  That's caused by something
completely different and more concerning ;(

Bootstrapped and regression tested on x86.  Obviously fixes the testcase on
riscv as well.

Pushing to the trunk.

PR rtl-optimization/116544
gcc/
* ext-dce.cc (ext_dce_process_uses): Fix thinko in promoted subreg
handling.

gcc/testsuite/
* gcc.dg/torture/pr116544.c: New test.

gcc/ext-dce.cc
gcc/testsuite/gcc.dg/torture/pr116544.c [new file with mode: 0644]

index 4a2503f18313d95ee0c6611878bb535b77c5fff9..2f3514ae797654eae78fd695282e042b371fa226 100644 (file)
@@ -846,7 +846,7 @@ ext_dce_process_uses (rtx_insn *insn, rtx obj,
            bitmap_set_bit (livenow, rn + 1);
          if (size > 16)
            bitmap_set_bit (livenow, rn + 2);
-         if (size == 32)
+         if (size >= 32)
            bitmap_set_bit (livenow, rn + 3);
          iter.skip_subrtxes ();
        }
diff --git a/gcc/testsuite/gcc.dg/torture/pr116544.c b/gcc/testsuite/gcc.dg/torture/pr116544.c
new file mode 100644 (file)
index 0000000..15f52fe
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-options "-fno-strict-aliasing -fwrapv" }
+/* { dg-do run { target longlong64 } } */
+
+extern void abort (void);
+long long a;
+signed char b[60];
+signed char c;
+long long d[60];
+int e[30];
+long long *f = d;
+static void g(long long *j, long k) { *j = k; }
+int main() {
+  d[5] = 0x100000000;
+  for (int h = 2; h < 7; h += 3)
+    for (int i = 0; i < (c || b[h]) + 10; i += 11)
+      e[2] = f[h];
+  g(&a, e[2]);
+  if (a != 0)
+    abort ();
+  return 0;
+}
+