https://gcc.gnu.org/g:09c66632baa6ebf1bf18abc1b99b8f78dce16256

commit r17-5773-g09c66632baa6ebf1bf18abc1b99b8f78dce16256
Author: Rohith Kapelli <[email protected]>
Date:   Fri Oct 16 00:58:40 2026 +0530

    tree-optimization/115869 - give up on self dependences without distance 
vectors
    
    add_multivariate_self_dist and add_other_self_distances detect a self
    dependence that distance vectors cannot describe, with more than two
    varying loops or an initial value or step that is not constant, but they
    only clear DDR_AFFINE_P.  The relation stays dependent with the zero
    vector saved before, and the users of the vectors take it as exact, so
    for example the outer-loop vectorizer can miscompile.  Mark such a
    relation as unknown and release its vectors.  Also release them at the
    existing early-out for several subscripts, as unroll-and-jam reads the
    vectors of a relation without checking for chrec_dont_know.
    
            PR tree-optimization/115869
    
    gcc/ChangeLog:
    
            * tree-data-ref.cc (add_multivariate_self_dist): Set
            DDR_ARE_DEPENDENT to chrec_dont_know and release the distance
            vectors when the dependence cannot be represented.
            (add_other_self_distances): Likewise.  Release the distance
            vectors when giving up on several subscripts.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/torture/pr115869-4.c: New test.
    
    Signed-off-by: Rohith Kapelli <[email protected]>

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr115869-4.c | 33 +++++++++++++++++++++++++++++++
 gcc/tree-data-ref.cc                      | 17 +++++++++++-----
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr115869-4.c 
b/gcc/testsuite/gcc.dg/torture/pr115869-4.c
new file mode 100644
index 000000000000..eebb1af4ce64
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr115869-4.c
@@ -0,0 +1,33 @@
+/* PR tree-optimization/115869 */
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+unsigned A0[16];
+unsigned B[6][1024];
+
+void __attribute__((noipa))
+foo (int n0, int n1, int n2, int n3)
+{
+  for (int i0 = 0; i0 < n0; i0++)
+    for (int i1 = 0; i1 < n1; i1++)
+      for (int i2 = 0; i2 < n2; i2++)
+       for (int i3 = 0; i3 < n3; i3++)
+         A0[i1 + i2 + i3]
+           = A0[i1 + i2 + i3] * 3u + B[i0][i1] + (unsigned) i3;
+}
+
+int
+main ()
+{
+  for (unsigned x = 0; x < 6 * 1024; x++)
+    ((unsigned *) B)[x] = x * 40503u + 117u;
+  for (unsigned x = 0; x < 16; x++)
+    A0[x] = x * 2654435761u + 117u;
+  foo (1, 1, 4, 2);
+  unsigned s = 0;
+  for (int x = 0; x < 16; x++)
+    s = s * 31 + A0[x];
+  if (s != 638080400u)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc
index 9358023c4ad7..c1614420c87d 100644
--- a/gcc/tree-data-ref.cc
+++ b/gcc/tree-data-ref.cc
@@ -5356,6 +5356,8 @@ add_multivariate_self_dist (struct 
data_dependence_relation *ddr, tree c_2)
       || TREE_CODE (CHREC_RIGHT (c_2)) != INTEGER_CST)
     {
       DDR_AFFINE_P (ddr) = false;
+      DDR_ARE_DEPENDENT (ddr) = chrec_dont_know;
+      DDR_DIST_VECTS (ddr).release ();
       return;
     }
 
@@ -5406,6 +5408,7 @@ add_other_self_distances (struct data_dependence_relation 
*ddr)
              if (DDR_NUM_SUBSCRIPTS (ddr) != 1)
                {
                  DDR_ARE_DEPENDENT (ddr) = chrec_dont_know;
+                 DDR_DIST_VECTS (ddr).release ();
                  return;
                }
 
@@ -5414,11 +5417,15 @@ add_other_self_distances (struct 
data_dependence_relation *ddr)
              if (TREE_CODE (CHREC_LEFT (access_fun)) == POLYNOMIAL_CHREC)
                add_multivariate_self_dist (ddr, access_fun);
              else
-               /* The evolution step is not constant: it varies in
-                  the outer loop, so this cannot be represented by a
-                  distance vector.  For example in pr34635.c the
-                  evolution is {0, +, {0, +, 4}_1}_2.  */
-               DDR_AFFINE_P (ddr) = false;
+               {
+                 /* The evolution step is not constant: it varies in
+                    the outer loop, so this cannot be represented by a
+                    distance vector.  For example in pr34635.c the
+                    evolution is {0, +, {0, +, 4}_1}_2.  */
+                 DDR_AFFINE_P (ddr) = false;
+                 DDR_ARE_DEPENDENT (ddr) = chrec_dont_know;
+                 DDR_DIST_VECTS (ddr).release ();
+               }
 
              return;
            }

Reply via email to