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

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
ICK.  Data-ref analysis issue with respect to how we handle pointer IVs
in dr_analyze_indices.  This results in

(compute_affine_dependence
  stmt_a: MEM[(int *)vectp_in.21_137] = vect__12.23_139;
  stmt_b: vect__16.26_145 = MEM[(int *)vectp_in.24_143];
(analyze_overlapping_iterations
  (chrec_a = {204B(OVF), +, 18446744073709551600}_1)
  (chrec_b = {216B(OVF), +, 18446744073709551600}_1)
(analyze_siv_subscript
(analyze_subscript_affine_affine
  (overlaps_a = no dependence)
  (overlaps_b = no dependence))
)
  (overlap_iterations_a = no dependence)
  (overlap_iterations_b = no dependence))
) -> no dependence

but this is only because 216 + n * (-16) never aliases index-wise.  That is,
data-ref analysis doesn't know about access sizes and in this case we have
partly overlapping vector accesses (it would treat exact overlaps correctly).
Unfortunately with partial overlaps being possible there is no way to
reduce a [ offset, size ] range down to a single index (even if all sizes
are equal).  In this special case we may see that the initial condition
is a constant and thus somehow gracefully "fail" (and for non-constant
initial condition hope we can't compute the dependence distance).

The pragmatic solution is to simply make possibly overlapping accesses
have distinct bases by adjusting CHREC_LEFT to be a multiple of the
access size.

Index: gcc/tree-data-ref.c
===================================================================
--- gcc/tree-data-ref.c (revision 219592)
+++ gcc/tree-data-ref.c (working copy)
@@ -883,6 +883,8 @@ dr_analyze_innermost (struct data_refere
@@ -970,7 +972,8 @@ dr_analyze_indices (struct data_referenc

   /* If the address operand of a MEM_REF base has an evolution in the
      analyzed nest, add it as an additional independent access-function.  */
-  if (TREE_CODE (ref) == MEM_REF)
+  if (TREE_CODE (ref) == MEM_REF
+      && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (ref))) == INTEGER_CST)
     {
       op = TREE_OPERAND (ref, 0);
       access_fn = analyze_scalar_evolution (loop, op);
@@ -992,6 +995,15 @@ dr_analyze_indices (struct data_referenc
                                fold_convert (ssizetype, memoff));
              memoff = build_int_cst (TREE_TYPE (memoff), 0);
            }
+         /* Adjust the offset so it is a multiple of the access type
+            size and thus we separate bases that can possibly be used
+            to produce partial overlaps (which the access_fn machinery
+            cannot handle).  */
+         wide_int rem
+           = wi::mod_trunc (off, TYPE_SIZE_UNIT (TREE_TYPE (ref)), SIGNED);
+         off = wide_int_to_tree (ssizetype, wi::sub (off, rem));
+         memoff = wide_int_to_tree (TREE_TYPE (memoff), rem);
+         /* And finally replace the initial condition.  */
          access_fn = chrec_replace_initial_condition
              (access_fn, fold_convert (orig_type, off));
          /* ???  This is still not a suitable base object for

Reply via email to