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