When we end up with a widen-sum with an invariant smaller operand
the reduction code uses a wrong vector type for it, causing
IL checking ICEs.  The following fixes that and the inefficiency
of using a widen-sum with a widenend invariant operand as well
by actually performing the check the following comment wants.

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

        PR tree-optimization/108950
        * tree-vect-patterns.cc (vect_recog_widen_sum_pattern):
        Check oprnd0 is defined in the loop.
        * tree-vect-loop.cc (vectorizable_reduction): Record all
        operands vector types, compute that of invariants and
        properly update their SLP nodes.

        * gcc.dg/vect/pr108950.c: New testcase.
---
 gcc/testsuite/gcc.dg/vect/pr108950.c | 13 +++++++++++++
 gcc/tree-vect-loop.cc                | 17 +++++++++++------
 gcc/tree-vect-patterns.cc            |  4 +++-
 3 files changed, 27 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/pr108950.c

diff --git a/gcc/testsuite/gcc.dg/vect/pr108950.c 
b/gcc/testsuite/gcc.dg/vect/pr108950.c
new file mode 100644
index 00000000000..2163866dfa7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr108950.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+int m;
+short int n;
+
+__attribute__ ((simd)) int
+foo (void)
+{
+  m += n;
+  m += n;
+}
+
+/* { dg-final { scan-tree-dump-not "widen_sum" "vect" } } */
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index ab7af0ea3b8..b17e8745d3f 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -6790,6 +6790,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
                        stmt_vector_for_cost *cost_vec)
 {
   tree vectype_in = NULL_TREE;
+  tree vectype_op[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
   class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   enum vect_def_type cond_reduc_dt = vect_unknown_def_type;
   stmt_vec_info cond_stmt_vinfo = NULL;
@@ -6799,7 +6800,6 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
   bool nested_cycle = false;
   bool double_reduc = false;
   int vec_num;
-  tree tem;
   tree cr_index_scalar_type = NULL_TREE, cr_index_vector_type = NULL_TREE;
   tree cond_reduc_val = NULL_TREE;
 
@@ -7037,7 +7037,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
       enum vect_def_type dt;
       if (!vect_is_simple_use (loop_vinfo, stmt_info, slp_for_stmt_info,
                               i + opno_adjust, &op.ops[i], &slp_op[i], &dt,
-                              &tem, &def_stmt_info))
+                              &vectype_op[i], &def_stmt_info))
        {
          if (dump_enabled_p ())
            dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -7052,15 +7052,20 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
       if (VECTORIZABLE_CYCLE_DEF (dt))
        return false;
 
+      if (!vectype_op[i])
+       vectype_op[i]
+         = get_vectype_for_scalar_type (loop_vinfo,
+                                        TREE_TYPE (op.ops[i]), slp_op[i]);
+
       /* To properly compute ncopies we are interested in the widest
         non-reduction input type in case we're looking at a widening
         accumulation that we later handle in vect_transform_reduction.  */
       if (lane_reduc_code_p
-         && tem
+         && vectype_op[i]
          && (!vectype_in
              || (GET_MODE_SIZE (SCALAR_TYPE_MODE (TREE_TYPE (vectype_in)))
-                 < GET_MODE_SIZE (SCALAR_TYPE_MODE (TREE_TYPE (tem))))))
-       vectype_in = tem;
+                 < GET_MODE_SIZE (SCALAR_TYPE_MODE (TREE_TYPE 
(vectype_op[i]))))))
+       vectype_in = vectype_op[i];
 
       if (op.code == COND_EXPR)
        {
@@ -7581,7 +7586,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
           && !lane_reduc_code_p
           && reduction_type != FOLD_LEFT_REDUCTION))
     for (i = 0; i < (int) op.num_ops; i++)
-      if (!vect_maybe_update_slp_op_vectype (slp_op[i], vectype_in))
+      if (!vect_maybe_update_slp_op_vectype (slp_op[i], vectype_op[i]))
        {
          if (dump_enabled_p ())
            dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index cefe331620f..dd585e59bf7 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -1821,7 +1821,9 @@ vect_recog_widen_sum_pattern (vec_info *vinfo,
      of the above pattern.  */
 
   if (!vect_reassociating_reduction_p (vinfo, stmt_vinfo, PLUS_EXPR,
-                                      &oprnd0, &oprnd1))
+                                      &oprnd0, &oprnd1)
+      || TREE_CODE (oprnd0) != SSA_NAME
+      || !vinfo->lookup_def (oprnd0))
     return NULL;
 
   type = TREE_TYPE (gimple_get_lhs (last_stmt));
-- 
2.35.3

Reply via email to