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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
                 CC|                            |rsandifo at gcc dot gnu.org
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2020-07-06

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
So we end up calling get_negative_load_store_type for this group which seems
to only handle contiguous accesses but this one is single element interleaving
aka contiguous with gap.

vect_supportable_dr_alignment returns dr_aligned which is seemingly OK for

#(Data Ref: 
#  bb: 3 
#  stmt: _4 = y[_2];
#  ref: y[_2];
#  base_object: y;
#  Access function 0: {1022, +, -2}_1

but then as said the vls type is computed as VMAT_CONTIGUOUS_REVERSE where
we eventually do

  if (memory_access_type == VMAT_CONTIGUOUS_DOWN
      || memory_access_type == VMAT_CONTIGUOUS_REVERSE)
    offset = size_int (-TYPE_VECTOR_SUBPARTS (vectype) + 1);

invalidating that alignment...

  /* If this is a backward running DR then first access in the larger
     vectype actually is N-1 elements before the address in the DR.
     Adjust misalign accordingly.  */
  if (tree_int_cst_sgn (drb->step) < 0)
    /* PLUS because STEP is negative.  */
    misalignment += ((TYPE_VECTOR_SUBPARTS (vectype) - 1)
                     * TREE_INT_CST_LOW (drb->step));

looks a bit odd since this does not offset by N-1 elements but N-1
"steps" (where a step is two elements in this case).  Here's probably
where the problem resides.  On the GCC 7 branch we see

  /* If this is a backward running DR then first access in the larger
     vectype actually is N-1 elements before the address in the DR.
     Adjust misalign accordingly.  */
  if (tree_int_cst_sgn (step) < 0)
    { 
      tree offset = ssize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
      /* DR_STEP(dr) is the same as -TYPE_SIZE of the scalar type,
         otherwise we wouldn't be here.  */
      offset = fold_build2 (MULT_EXPR, ssizetype, offset, step);
      /* PLUS because STEP was negative.  */
      misalign = size_binop (PLUS_EXPR, misalign, offset);
    }

and mind that comment about DR_STEP isn't true ...

diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 2462276e7c2..959c2d3378f 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -1109,7 +1109,7 @@ vect_compute_data_ref_alignment (vec_info *vinfo,
dr_vec_info *dr_info)
   if (tree_int_cst_sgn (drb->step) < 0)
     /* PLUS because STEP is negative.  */
     misalignment += ((TYPE_VECTOR_SUBPARTS (vectype) - 1)
-                    * TREE_INT_CST_LOW (drb->step));
+                    * -TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE
(vectype))));

   unsigned int const_misalignment;
   if (!known_misalignment (misalignment, vect_align_c, &const_misalignment))

fixes that.

Reply via email to