https://gcc.gnu.org/g:9bad5cf9ae446b367f666176537eb76e94cc4448

commit r12-10452-g9bad5cf9ae446b367f666176537eb76e94cc4448
Author: Richard Biener <rguent...@suse.de>
Date:   Wed Dec 13 14:23:31 2023 +0100

    tree-optimization/112793 - SLP of constant/external code-generated twice
    
    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.
    
            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.
    
    (cherry picked from commit d782ec8362eadc3169286eb1e39c631effd02323)

Diff:
---
 gcc/testsuite/g++.dg/vect/pr112793.cc | 32 ++++++++++++++++++++++++++++++++
 gcc/tree-vect-slp.cc                  | 16 +++++++++-------
 2 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/gcc/testsuite/g++.dg/vect/pr112793.cc 
b/gcc/testsuite/g++.dg/vect/pr112793.cc
new file mode 100644
index 000000000000..258d7c1b1119
--- /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 26c989cbff9a..54e6a9e4224f 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -7240,12 +7240,6 @@ vect_schedule_slp_node (vec_info *vinfo,
   int i;
   slp_tree child;
 
-  /* For existing vectors there's nothing to do.  */
-  if (SLP_TREE_VEC_DEFS (node).exists ())
-    return;
-
-  gcc_assert (SLP_TREE_VEC_STMTS (node).is_empty ());
-
   /* Vectorize externals and constants.  */
   if (SLP_TREE_DEF_TYPE (node) == vect_constant_def
       || SLP_TREE_DEF_TYPE (node) == vect_external_def)
@@ -7256,10 +7250,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);

Reply via email to