The following avoids using vect_get_num_copies on the SLP input
from vectorizable_lane_reducing which is in this case used
for costing.  The transform phase will simply look at the actual
number of vector inputs code generated, but for costing we
can use vect_get_num_copies_for_invariant which is exported with
the patch.  It must be possible to compute the number from
the number of vector outputs, the number of SLP lanes and the
width of the elements involved, but given what the transform
phase does this matches it exactly.

Bootstrapped and tested on x86_64-unknown-linux-gnu and aarch64-linux-gnu,
pushed.

        PR tree-optimization/126998
        * tree-vectorizer.h (vect_get_num_copies_for_invariant):
        Declare.
        * tree-vect-slp.cc (vect_get_num_copies_for_invariant): Export.
        * tree-vect-loop.cc (vectorizable_lane_reducing): Use
        vect_get_num_copies_for_invariant on the SLP input.

        * gcc.dg/vect/vect-reduc-dot-pr126998.c: New testcase.
---
 .../gcc.dg/vect/vect-reduc-dot-pr126998.c     | 36 +++++++++++++++++++
 gcc/tree-vect-loop.cc                         |  9 +++--
 gcc/tree-vect-slp.cc                          |  2 +-
 gcc/tree-vectorizer.h                         |  2 ++
 4 files changed, 45 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-reduc-dot-pr126998.c

diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-pr126998.c 
b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-pr126998.c
new file mode 100644
index 00000000000..958ac5dbcc6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-pr126998.c
@@ -0,0 +1,36 @@
+/* { dg-additional-options "-O3" } */
+
+#include "tree-vect.h"
+
+unsigned a, c;
+int b, d;
+signed char e;
+  
+void __attribute__((noipa))
+f (void)
+{ 
+  for (; b; ++b)
+    {
+      c = 0;
+      for (; c < 10; c++)
+        {
+          d = 0;
+          for (; d < c; d++)
+            a += e;
+        }
+    }
+}
+
+int
+main ()
+{
+  check_vect ();
+
+  b = -3;
+  e = 2;
+  f ();
+  if (a != 3 * 45 * 2)
+    __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 9e3894b12bf..e2636c5b767 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -6852,9 +6852,12 @@ vectorizable_lane_reducing (loop_vec_info loop_vinfo, 
stmt_vec_info stmt_info,
   tree vectype_in = SLP_TREE_VECTYPE (node_in);
   gcc_assert (vectype_in);
 
-  /* Compute number of effective vector statements for costing.  */
-  unsigned int ncopies_for_cost = vect_get_num_copies (loop_vinfo, node_in);
-  gcc_assert (ncopies_for_cost >= 1);
+  /* Compute number of effective vector statements for costing from the
+     number of input lanes allow for excess lanes in the last input vector.  */
+  unsigned int ncopies_for_cost;
+  bool res = vect_get_num_copies_for_invariant (loop_vinfo, node_in,
+                                               &ncopies_for_cost);
+  gcc_assert (res && ncopies_for_cost >= 1);
 
   if (vect_is_emulated_mixed_dot_prod (slp_node))
     {
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 492562bd631..97a6c8e1e0a 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -8992,7 +8992,7 @@ vect_scalar_ops_slice_hash::equal (const value_type &s1,
    excess elements in the last vector.  Returns false if *NVECTORS
    cannot be computed.  */
 
-static bool
+bool
 vect_get_num_copies_for_invariant (vec_info *vinfo, slp_tree node,
                                   unsigned *nvectors)
 {
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index d21f132a9e5..4d542d57e6d 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -2789,6 +2789,8 @@ extern tree prepare_vec_mask (loop_vec_info, tree, tree, 
tree,
                              gimple_stmt_iterator *);
 extern tree vect_get_mask_load_else (int, tree);
 extern bool vect_load_perm_consecutive_p (slp_tree, unsigned = UINT_MAX);
+extern bool vect_get_num_copies_for_invariant (vec_info *, slp_tree,
+                                              unsigned *);
 
 /* In tree-vect-patterns.cc.  */
 extern void
-- 
2.51.0

Reply via email to