The following makes the attempt at code-generating a constant/external SLP node twice well-formed as that can happen when partitioning BB vectorization attempts where we keep constants/externals unpartitioned.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/112793 * tree-vect-slp.cc (vect_schedule_slp_node): Already code-generated constant/external nodes are OK. * g++.dg/vect/pr112793.cc: New testcase. --- gcc/testsuite/g++.dg/vect/pr112793.cc | 32 +++++++++++++++++++++++++++ gcc/tree-vect-slp.cc | 17 +++++++------- 2 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/vect/pr112793.cc diff --git a/gcc/testsuite/g++.dg/vect/pr112793.cc b/gcc/testsuite/g++.dg/vect/pr112793.cc new file mode 100644 index 00000000000..258d7c1b111 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr112793.cc @@ -0,0 +1,32 @@ +// { dg-do compile } +// { dg-require-effective-target c++11 } +// { dg-additional-options "-march=znver2" { target x86_64-*-* i?86-*-* } } + +typedef double T; +T c, s; +T a[16]; +struct Matrix4 { + Matrix4(){} + Matrix4(T e, T f, T i, T j) { + r[1] = r[4] = e; + r[5] = f; + r[8] = i; + r[9] = j; + } + Matrix4 operator*(Matrix4 a) { + return Matrix4( + r[0] * a.r[4] + r[4] + r[15] + r[6], + r[1] * a.r[4] + 1 + 2 + 3, r[0] * r[8] + 1 + 2 + 3, + r[1] * r[8] + r[1] + r[14] + r[2] * r[3]); + } + T r[16] = {}; +}; +Matrix4 t1, t2; +Matrix4 tt; +Matrix4 getRotAltAzToEquatorial() +{ + t2.r[4] = 0; + t1.r[1] = -s; + t1.r[8] = 0; + return t1 * t2; +} diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index b412ec38802..a82fca45161 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -9062,13 +9062,6 @@ vect_schedule_slp_node (vec_info *vinfo, int i; slp_tree child; - /* For existing vectors there's nothing to do. */ - if (SLP_TREE_DEF_TYPE (node) == vect_external_def - && SLP_TREE_VEC_DEFS (node).exists ()) - return; - - gcc_assert (SLP_TREE_VEC_DEFS (node).is_empty ()); - /* Vectorize externals and constants. */ if (SLP_TREE_DEF_TYPE (node) == vect_constant_def || SLP_TREE_DEF_TYPE (node) == vect_external_def) @@ -9079,10 +9072,18 @@ vect_schedule_slp_node (vec_info *vinfo, if (!SLP_TREE_VECTYPE (node)) return; - vect_create_constant_vectors (vinfo, node); + /* There are two reasons vector defs might already exist. The first + is that we are vectorizing an existing vector def. The second is + when performing BB vectorization shared constant/external nodes + are not split apart during partitioning so during the code-gen + DFS walk we can end up visiting them twice. */ + if (! SLP_TREE_VEC_DEFS (node).exists ()) + vect_create_constant_vectors (vinfo, node); return; } + gcc_assert (SLP_TREE_VEC_DEFS (node).is_empty ()); + stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node); gcc_assert (SLP_TREE_NUMBER_OF_VEC_STMTS (node) != 0); -- 2.35.3