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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rsandifo at gcc dot gnu.org

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
So the issue of this ICE is that we have

t.c:11:3: note:   Detected interleaving strided store of size 2
t.c:11:3: note:         replacements[i_20].where = _ifc__47;
t.c:11:3: note:         replacements[i_20].subreg_loc = _ifc__44;
t.c:11:3: note:   Detected interleaving strided store of size 1
t.c:11:3: note:         replacements[i_20].subreg_loc = _ifc__50;

that's sth we do not support.  Well, we kind-of do but support was
rotten because we'd never create such groups before cited refs.
We simply do

      /* Check that the size of the interleaving is equal to count for stores,
         i.e., that there are no gaps.  */
      if (groupsize != count
          && !DR_IS_READ (dr))
        {
          groupsize = count;
          STMT_VINFO_STRIDED_P (stmt_info) = true;
        }

not sure why we adjust groupsize here.  The intent was probably to allow
a gap at the end of the group but not inside?  Commenting the above
ICEs later in

  /* There can only be a gap at the end of the group if the stride is
     known at compile time.  */
  gcc_assert (!STMT_VINFO_STRIDED_P (first_stmt_info) || gap == 0);

and it's also !slp so

  /* Stores can't yet have gaps.  */
  gcc_assert (slp || vls_type == VLS_LOAD || gap == 0);

would also ICE.

Anyhow - that very assert in vect_update_misalignment_for_peel got quite some
updates and I wonder why it's not using DR_STEP.  Well, nobody thought of
groupsize not reflecting, well, group size...

For the assert I think multiplying by group-size or step is premature
anyhow.  Ah, I guess it might be to handle different sized accesses
at the same place with same stride.  But then since same-align refs
have dependence distance zero their DR_MISALIGNMENT should be the same...

The following survives preliminary testing.  Richard?  For strided
grouped stores you should be able to see bogus misalignment adjustments
with your change.  Of course misaligned is misaligned so it may not
really matter...

diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 9185b1bd1c0..5264ffffb9f 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -1015,15 +1015,8 @@ vect_update_misalignment_for_peel (dr_vec_info *dr_info,
   stmt_vec_info stmt_info = dr_info->stmt;
   stmt_vec_info peel_stmt_info = dr_peel_info->stmt;

- /* For interleaved data accesses the step in the loop must be multiplied by
-     the size of the interleaving group.  */
-  if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
-    dr_size *= DR_GROUP_SIZE (DR_GROUP_FIRST_ELEMENT (stmt_info));
-  if (STMT_VINFO_GROUPED_ACCESS (peel_stmt_info))
-    dr_peel_size *= DR_GROUP_SIZE (peel_stmt_info);
-
-  /* It can be assumed that the data refs with the same alignment as dr_peel
-     are aligned in the vector loop.  */
+  /* It can be assumed that if dr_info has the same alignment as dr_peel,
+     it is aligned in the vector loop.  */
   same_aligned_drs = STMT_VINFO_SAME_ALIGN_REFS (peel_stmt_info);
   FOR_EACH_VEC_ELT (same_aligned_drs, i, current_dr)
     {
@@ -1031,12 +1024,19 @@ vect_update_misalignment_for_peel (dr_vec_info
*dr_info,
         continue;
       gcc_assert (!known_alignment_for_access_p (dr_info)
                  || !known_alignment_for_access_p (dr_peel_info)
-                 || (DR_MISALIGNMENT (dr_info) / dr_size
-                     == DR_MISALIGNMENT (dr_peel_info) / dr_peel_size));
+                 || (DR_MISALIGNMENT (dr_info)
+                     == DR_MISALIGNMENT (dr_peel_info)));
       SET_DR_MISALIGNMENT (dr_info, 0);
       return;
     }

+ /* For interleaved data accesses the step in the loop must be multiplied by
+    the size of the interleaving group.  */
+  if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
+    dr_size *= TREE_INT_CST_LOW (DR_STEP (dr_info->dr));
+  if (STMT_VINFO_GROUPED_ACCESS (peel_stmt_info))
+    dr_peel_size *= TREE_INT_CST_LOW (DR_STEP (dr_peel_info->dr));
+
   if (known_alignment_for_access_p (dr_info)
       && known_alignment_for_access_p (dr_peel_info))
     {

Reply via email to