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

--- Comment #12 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok, we SLP the first block

node
        stmt 0 b[_17] = _24;

        stmt 1 b[_3] = _50;

        stmt 2 b[_93] = _99;

        stmt 3 b[_104] = _110;

node
        stmt 0 _24 = (unsigned char) _23;

        stmt 1 _50 = (unsigned char) _63;

        stmt 2 _99 = (unsigned char) _98;

        stmt 3 _110 = (unsigned char) _109;

node
        stmt 0 _23 = a[_21];

        stmt 1 _63 = a[_64];

        stmt 2 _98 = a[_97];

        stmt 3 _109 = a[_108];

and for all other instances claim the load permutation is not supported.

For the stmts visble above the load permutation _is_ 1:1, but as we need
to gobble up more loads due to the truncation the effective SLP group
we deal with has gaps (bah, the gaps code...)

Thus the underlying issue is that we have

t.c:13:3: note: Detected interleaving of size 16
t.c:13:3: note: Detected interleaving of size 4
t.c:13:3: note: Detected interleaving of size 4
t.c:13:3: note: Detected interleaving of size 4
t.c:13:3: note: Detected interleaving of size 4

with the group-size of the stores (4) determining the SLP group size but
the analysis code being confused by the non-matching group size of the
loads.

In the end we should probably split up the groups if a single group ends up
being refered to in different SLP instances (thus also postpone most of
the dependence-kind tests until after SLP discovery).  Let's see if a simple
workaround doesn't regress anything.

Index: gcc/tree-vect-slp.c
===================================================================
--- gcc/tree-vect-slp.c (revision 219581)
+++ gcc/tree-vect-slp.c (working copy)
@@ -729,8 +729,11 @@ vect_build_slp_tree_1 (loop_vec_info loo
                 ???  We should enhance this to only disallow gaps
                 inside vectors.  */
               if ((unrolling_factor > 1
-                  && GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
-                  && GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
+                  && ((GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
+                       && GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
+                      /* If the group is split up then GROUP_GAP
+                         isn't correct here, nor is GROUP_FIRST_ELEMENT.  */
+                      || GROUP_SIZE (vinfo_for_stmt (stmt)) > group_size))
                  || (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) != stmt
                      && GROUP_GAP (vinfo_for_stmt (stmt)) != 1))
                 {

Reply via email to