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)

Reply via email to