From 33a63257701c8d94ee375e32ff1837c989d8ded6 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 5 Jan 2021 16:17:15 +0100 Subject: [PATCH] tree-optimization/98516 - fix SLP permute opt materialization When materializing on a VEC_PERM node we have to permute the incoming vectors, not the outgoing one. 2021-01-05 Richard Biener 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 | 26 ++++++++++++++ gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-2.c | 36 ++++++++++++++++++++ gcc/tree-vect-slp.c | 13 ++++--- 3 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-1.c create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-2.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 index 00000000000..c4c244c6f8a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-1.c @@ -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 index 00000000000..f1a9341e224 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr98516-2.c @@ -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; +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 49cb635ee92..c9da8457e5e 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -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"); } -- 2.30.2