On Fri, 16 Oct 2026, Rohith Kapelli wrote: > 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.
I think this is a good fix. Note that build_classic_dist_vector still returns true when add_other_self_distances ended up punting with chrec_dont_know, it might be cleaner to arrange to return false in that case. This could be handled as followup, it is a pre-existing issue (add_other_self_distances could have a return value by its own). Thus, OK. Thanks, Richard. > 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]> > --- > gcc/testsuite/gcc.dg/torture/pr115869-4.c | 33 +++++++++++++++++++++++ > gcc/tree-data-ref.cc | 17 ++++++++---- > 2 files changed, 45 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr115869-4.c > > 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 d6da0fe58c37..31d324cb3abd 100644 > --- a/gcc/tree-data-ref.cc > +++ b/gcc/tree-data-ref.cc > @@ -5310,6 +5310,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; > } > > @@ -5360,6 +5362,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; > } > > @@ -5368,11 +5371,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; > } > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Stefan Gaiser, Jochen Jaser, Abhinav Puri; (HRB 36809, AG Nuernberg)
