tree-optimization/93428 - avoid load permutation vector clobbering
authorRichard Biener <rguenther@suse.de>
Wed, 29 Jan 2020 08:05:05 +0000 (09:05 +0100)
committerRichard Biener <rguenther@suse.de>
Wed, 29 Jan 2020 08:06:08 +0000 (09:06 +0100)
With SLP now being a graph with shared nodes across instances we have
to make sure to compute the load permutation of nodes once, not
overwriting the result of earlier analysis.

2020-01-28  Richard Biener  <rguenther@suse.de>

PR tree-optimization/93428
* tree-vect-slp.c (vect_build_slp_tree_2): Compute the load
permutation when the load node is created.
(vect_analyze_slp_instance): Re-use it here.

* gcc.dg/torture/pr93428.c: New testcase.

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr93428.c [new file with mode: 0644]
gcc/tree-vect-slp.c

index fd298b9a8b15b9f4a057785001bae755fb29ce6f..f6959ef6ebfe44f59d94ee6dbb1c3e6a368cd67b 100644 (file)
@@ -1,3 +1,10 @@
+2020-01-29  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/93428
+       * tree-vect-slp.c (vect_build_slp_tree_2): Compute the load
+       permutation when the load node is created.
+       (vect_analyze_slp_instance): Re-use it here.
+
 2020-01-28  Jan Hubicka  <hubicka@ucw.cz>
 
        * ipa-prop.c (update_indirect_edges_after_inlining): Fix warning.
index 279ab644f6e117a5af8c3da4990e82c9ad857264..a4a775d35560e33c172fc39e043e2cbcfc5d42b6 100644 (file)
@@ -1,3 +1,8 @@
+2020-01-29  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/93428
+       * gcc.dg/torture/pr93428.c: New testcase.
+
 2020-01-28  Martin Sebor  <msebor@redhat.com>
 
        PR middle-end/93437
diff --git a/gcc/testsuite/gcc.dg/torture/pr93428.c b/gcc/testsuite/gcc.dg/torture/pr93428.c
new file mode 100644 (file)
index 0000000..b24f651
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-slp-vectorize" } */
+
+int ai[2][8];
+void bar (int *);
+void
+br (void)
+{
+  int qp[9];
+  bar (qp);
+  ai[0][0] = qp[0] + qp[1] + 1 >> 1;
+  ai[0][1] = qp[1] + qp[2] + 1 >> 1;
+  ai[0][2] = qp[2] + qp[3] + 1 >> 1;
+  ai[0][3] = qp[3] + qp[4] + 1 >> 1;
+  ai[0][4] = qp[4] + qp[5] + 1 >> 1;
+  ai[0][5] = qp[5] + qp[6] + 1 >> 1;
+  ai[0][6] = qp[6] + qp[7] + 1 >> 1;
+  ai[0][7] = qp[7] + qp[8] + 1 >> 1;
+  ai[1][0] = qp[0] + qp[1] + 2 * qp[0] + 1 >> 2;
+  ai[1][1] = qp[0] + qp[2] + 2 * qp[1] + 1 >> 2;
+  ai[1][2] = qp[1] + qp[3] + 2 * qp[2] + 1 >> 2;
+  ai[1][3] = qp[2] + qp[4] + 2 * qp[3] + 1 >> 2;
+  ai[1][4] = qp[3] + qp[5] + 2 * qp[4] + 1 >> 2;
+  ai[1][5] = qp[4] + qp[6] + 2 * qp[5] + 1 >> 2;
+  ai[1][6] = qp[5] + qp[7] + 2 * qp[6] + 1 >> 2;
+  ai[1][7] = qp[6] + qp[8] + 2 * qp[7] + 1 >> 2;
+}
index b13beeb3689ffe811349b81f3269eeeec094c96d..71a24b78cf4f152fe61efaea6676f819f2e5f80c 100644 (file)
@@ -1353,6 +1353,23 @@ vect_build_slp_tree_2 (vec_info *vinfo,
          *max_nunits = this_max_nunits;
          (*tree_size)++;
          node = vect_create_new_slp_node (stmts);
+         /* And compute the load permutation.  Whether it is actually
+            a permutation depends on the unrolling factor which is
+            decided later.  */
+         vec<unsigned> load_permutation;
+         int j;
+         stmt_vec_info load_info;
+         load_permutation.create (group_size);
+         stmt_vec_info first_stmt_info
+           = DR_GROUP_FIRST_ELEMENT (SLP_TREE_SCALAR_STMTS (node)[0]);
+         FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), j, load_info)
+           {
+             int load_place = vect_get_place_in_interleaving_chain
+                 (load_info, first_stmt_info);
+             gcc_assert (load_place != -1);
+             load_permutation.safe_push (load_place);
+           }
+         SLP_TREE_LOAD_PERMUTATION (node) = load_permutation;
          return node;
        }
     }
@@ -2254,22 +2271,19 @@ vect_analyze_slp_instance (vec_info *vinfo,
          bool loads_permuted = false;
          FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (new_instance), i, load_node)
            {
-             vec<unsigned> load_permutation;
-             int j;
+             if (!SLP_TREE_LOAD_PERMUTATION (load_node).exists ())
+               continue;
+             unsigned j;
              stmt_vec_info load_info;
              bool this_load_permuted = false;
-             load_permutation.create (group_size);
              stmt_vec_info first_stmt_info = DR_GROUP_FIRST_ELEMENT
                  (SLP_TREE_SCALAR_STMTS (load_node)[0]);
              FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (load_node), j, load_info)
-               {
-                 int load_place = vect_get_place_in_interleaving_chain
-                     (load_info, first_stmt_info);
-                 gcc_assert (load_place != -1);
-                 if (load_place != j)
+               if (SLP_TREE_LOAD_PERMUTATION (load_node)[j] != j)
+                 {
                    this_load_permuted = true;
-                 load_permutation.safe_push (load_place);
-               }
+                   break;
+                 }
              if (!this_load_permuted
                  /* The load requires permutation when unrolling exposes
                     a gap either because the group is larger than the SLP
@@ -2278,10 +2292,9 @@ vect_analyze_slp_instance (vec_info *vinfo,
                      || (group_size == DR_GROUP_SIZE (first_stmt_info)
                          && DR_GROUP_GAP (first_stmt_info) == 0)))
                {
-                 load_permutation.release ();
+                 SLP_TREE_LOAD_PERMUTATION (load_node).release ();
                  continue;
                }
-             SLP_TREE_LOAD_PERMUTATION (load_node) = load_permutation;
              loads_permuted = true;
            }