]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
regcprop: Return early in maybe_mode_change for unorder modes [PR124649]
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Thu, 26 Mar 2026 20:21:01 +0000 (13:21 -0700)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Fri, 27 Mar 2026 16:35:19 +0000 (09:35 -0700)
Like r16-727-g2ec5082dd24cef but the call to partial_subreg_p happens
in a later place, maybe_mode_change.
For this example we have VNx4QImode and DImode which are not ordered.

Bootstrapped and tested on aarch64-linux-gnu.

PR rtl-optimization/124649

gcc/ChangeLog:

* regcprop.cc (maybe_mode_change): Return early
for unordered modes.

gcc/testsuite/ChangeLog:

* gcc.dg/torture/pr124649-1.c: New test.

Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
gcc/regcprop.cc
gcc/testsuite/gcc.dg/torture/pr124649-1.c [new file with mode: 0644]

index b1f00ca0435c51aa160f1e83f5f3e58b834ca4fa..2a9956353cc60d55a3aa1554d9dff151803b8018 100644 (file)
@@ -431,6 +431,14 @@ maybe_mode_change (machine_mode orig_mode, machine_mode copy_mode,
                   machine_mode new_mode, unsigned int regno,
                   unsigned int copy_regno ATTRIBUTE_UNUSED)
 {
+  /* All three modes precision have to be ordered to each other,
+     otherwise partial_subreg_p won't work.  */
+  if (!ordered_p (GET_MODE_PRECISION (orig_mode),
+                 GET_MODE_PRECISION (copy_mode))
+      || !ordered_p (GET_MODE_PRECISION (copy_mode),
+                    GET_MODE_PRECISION (new_mode)))
+    return NULL_RTX;
+
   if (partial_subreg_p (copy_mode, orig_mode)
       && partial_subreg_p (copy_mode, new_mode))
     return NULL_RTX;
diff --git a/gcc/testsuite/gcc.dg/torture/pr124649-1.c b/gcc/testsuite/gcc.dg/torture/pr124649-1.c
new file mode 100644 (file)
index 0000000..4cd84d7
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/124649 */
+/* { dg-do compile } */
+/* { dg-additional-options "-mcpu=neoverse-v1" { target aarch64*-*-* } } */
+
+void f(char *g, int b) {
+  int k = b & 4 + 1;
+  int c[b];
+  if (k == 1)
+    b >>= 3;
+  b &= 1;
+  c[0] = b;
+  for (int i = 0; i < k; i++)
+    g[i] = c[i];
+}
+