https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77605

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
                 CC|                            |spop at gcc dot gnu.org
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
And the reason is IMHO

/* Determines the overlapping elements due to accesses CHREC_A and
   CHREC_B, that are affine functions.  This function cannot handle
   symbolic evolution functions, ie. when initial conditions are
   parameters, because it uses lambda matrices of integers.  */

static void
analyze_subscript_affine_affine (tree chrec_a,
                                 tree chrec_b,
                                 conflict_function **overlaps_a,
                                 conflict_function **overlaps_b,
                                 tree *last_conflicts)
{
...
          if (i1 > 0 && j1 > 0)
            {
              HOST_WIDE_INT niter_a
                = max_stmt_executions_int (get_chrec_loop (chrec_a));
              HOST_WIDE_INT niter_b
                = max_stmt_executions_int (get_chrec_loop (chrec_b));
              HOST_WIDE_INT niter = MIN (niter_a, niter_b);
                                    ^^^
...
                  /* If the overlap occurs outside of the bounds of the
                     loop, there is no dependence.  */
                  if (x1 >= niter || y1 >= niter)

we compute the conflict iteration pair to 0, 6 but niter is two here
(minimum of two and eight).

Changing the above tests to use niter_a and niter_b fixes the issue but we have
other niter uses above that.  And the question is of course how to represent
"last_conflict" here -- it is supposed to be an iteration number which
hopefully is in-range for both loops (fixing the above code to properly
use niter_a/b makes it so for _this_ case).  "last_conflicts" is not very
well documented ("This field stores the information about the iteration domain
validity of the dependence relation.").

Patch that needs testing (and a 2nd eye):

Index: gcc/tree-data-ref.c
===================================================================
--- gcc/tree-data-ref.c (revision 240176)
+++ gcc/tree-data-ref.c (working copy)
@@ -2686,13 +2682,13 @@ analyze_subscript_affine_affine (tree ch

              if (niter > 0)
                {
-                 HOST_WIDE_INT tau2 = MIN (FLOOR_DIV (niter - i0, i1),
-                                           FLOOR_DIV (niter - j0, j1));
+                 HOST_WIDE_INT tau2 = MIN (FLOOR_DIV (niter_a - i0, i1),
+                                           FLOOR_DIV (niter_b - j0, j1));
                  HOST_WIDE_INT last_conflict = tau2 - (x1 - i0)/i1;

                  /* If the overlap occurs outside of the bounds of the
                     loop, there is no dependence.  */
-                 if (x1 >= niter || y1 >= niter)
+                 if (x1 >= niter_a || y1 >= niter_b)
                    {
                      *overlaps_a = conflict_fn_no_dependence ();
                      *overlaps_b = conflict_fn_no_dependence ();


with this patch we get

(compute_affine_dependence
  stmt_a: _2 = c[b.5_22][_1];
  stmt_b: c[b.5_22][a.7_23] = _3;
(analyze_overlapping_iterations
  (chrec_a = {6, +, 1}_2)
  (chrec_b = {0, +, 1}_1)
(analyze_miv_subscript
(analyze_subscript_affine_affine
  (overlaps_a = [0 + 1 * x_1])
  (overlaps_b = [6 + 1 * x_1]))
)
  (overlap_iterations_a = [0 + 1 * x_1])
  (overlap_iterations_b = [6 + 1 * x_1]))
(analyze_overlapping_iterations
  (chrec_a = {0, +, 1}_2)
  (chrec_b = {0, +, 1}_2)
  (overlap_iterations_a = [0])
  (overlap_iterations_b = [0]))
(Dependence relation cannot be represented by distance vector.)
)


The issue was likely introduced by r129797 (not sure if we vectorized the loop
immediately after that change).

Reply via email to