tree-optimization/98516 - fix SLP permute opt materialization
authorRichard Biener <rguenther@suse.de>
Tue, 5 Jan 2021 15:17:15 +0000 (16:17 +0100)
committerRichard Biener <rguenther@suse.de>
Tue, 5 Jan 2021 16:40:51 +0000 (17:40 +0100)
When materializing on a VEC_PERM node we have to permute the
incoming vectors, not the outgoing one.

2021-01-05  Richard Biener  <rguenther@suse.de>

PR tree-optimization/98516
* tree-vect-slp.c (vect_optimize_slp): Permute the incoming
lanes when materializing on a VEC_PERM node.
(vectorizable_slp_permutation): Dump the permute properly.

* gcc.dg/vect/bb-slp-pr98516-1.c: New testcase.
* gcc.dg/vect/bb-slp-pr98516-2.c: Likewise.

gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-2.c [new file with mode: 0644]
gcc/tree-vect-slp.c

diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-1.c
new file mode 100644 (file)
index 0000000..c4c244c
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+
+double a[4], b[2];
+
+void __attribute__((noipa))
+foo ()
+{
+  double a0 = a[0];
+  double a1 = a[1];
+  double a2 = a[2];
+  double a3 = a[3];
+  b[0] = a1 - a3;
+  b[1] = a0 + a2;
+}
+
+int main()
+{
+  a[0] = 1.;
+  a[1] = 2.;
+  a[2] = 3.;
+  a[3] = 4.;
+  foo ();
+  if (b[0] != -2 || b[1] != 4)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-2.c
new file mode 100644 (file)
index 0000000..f1a9341
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+
+float a[8], b[4];
+
+void __attribute__((noipa))
+foo ()
+{
+  float a0 = a[0];
+  float a1 = a[1];
+  float a2 = a[2];
+  float a3 = a[3];
+  float a4 = a[4];
+  float a5 = a[5];
+  float a6 = a[6];
+  float a7 = a[7];
+  b[0] = a1 - a5;
+  b[1] = a0 + a4;
+  b[2] = a3 - a7;
+  b[3] = a2 + a6;
+}
+
+int main()
+{
+  a[0] = 1.;
+  a[1] = 2.;
+  a[2] = 3.;
+  a[3] = 4.;
+  a[4] = 5.;
+  a[5] = 6.;
+  a[6] = 7.;
+  a[7] = 8.;
+  foo ();
+  if (b[0] != -4 || b[1] != 6 || b[2] != -4 || b[3] != 10)
+    __builtin_abort ();
+  return 0;
+}
index 49cb635ee9215414c9fa2cba669816d534ef4bf7..c9da8457e5ef10294418c34c94e397797b777073 100644 (file)
@@ -3094,15 +3094,18 @@ vect_optimize_slp (vec_info *vinfo)
            ;
          else if (SLP_TREE_LANE_PERMUTATION (node).exists ())
            {
-             /* If the node if already a permute node we just need to apply
-                the permutation to the permute node itself.  */
+             /* If the node is already a permute node we can apply
+                the permutation to the lane selection, effectively
+                materializing it on the incoming vectors.  */
              if (dump_enabled_p ())
                dump_printf_loc (MSG_NOTE, vect_location,
                                 "simplifying permute node %p\n",
                                 node);
 
-             vect_slp_permute (perms[perm], SLP_TREE_LANE_PERMUTATION (node),
-                               true);
+             for (unsigned k = 0;
+                  k < SLP_TREE_LANE_PERMUTATION (node).length (); ++k)
+               SLP_TREE_LANE_PERMUTATION (node)[k].second
+                 = perms[perm][SLP_TREE_LANE_PERMUTATION (node)[k].second];
            }
          else
            {
@@ -5554,7 +5557,7 @@ vectorizable_slp_permutation (vec_info *vinfo, gimple_stmt_iterator *gsi,
            dump_printf (MSG_NOTE, ",");
          dump_printf (MSG_NOTE, " vops%u[%u][%u]",
                       vperm[i].first.first, vperm[i].first.second,
-                      vperm[i].first.second);
+                      vperm[i].second);
        }
       dump_printf (MSG_NOTE, "\n");
     }