tree-vect-loop.c (vect_determine_vectorization_factor): Check mix of boolean and...
authorIlya Enkovich <enkovich.gnu@gmail.com>
Fri, 13 Nov 2015 11:45:25 +0000 (11:45 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Fri, 13 Nov 2015 11:45:25 +0000 (11:45 +0000)
gcc/

* tree-vect-loop.c (vect_determine_vectorization_factor): Check
mix of boolean and integer vectors in a single statement.
* tree-vect-slp.c (vect_mask_constant_operand_p): New.
(vect_get_constant_vectors): Use vect_mask_constant_operand_p to
determine constant type.
* tree-vect-stmts.c (vectorizable_comparison): Provide vectype
for loop invariants.

gcc/testsuite/

* g++.dg/vect/simd-bool-comparison-1.cc: New test.
* g++.dg/vect/simd-bool-comparison-2.cc: New test.

From-SVN: r230309

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/vect/simd-bool-comparison-1.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc [new file with mode: 0644]
gcc/tree-vect-loop.c
gcc/tree-vect-slp.c
gcc/tree-vect-stmts.c

index 9d4758ba9277fe245455e59be4ddd01b801c9eb3..a7517f9bcaaabbaf118d688f3458b9bd2ea7c2d7 100644 (file)
@@ -1,3 +1,13 @@
+2015-11-13  Ilya Enkovich  <enkovich.gnu@gmail.com>
+
+       * tree-vect-loop.c (vect_determine_vectorization_factor): Check
+       mix of boolean and integer vectors in a single statement.
+       * tree-vect-slp.c (vect_mask_constant_operand_p): New.
+       (vect_get_constant_vectors): Use vect_mask_constant_operand_p to
+       determine constant type.
+       * tree-vect-stmts.c (vectorizable_comparison): Provide vectype
+       for loop invariants.
+
 2015-11-13  Alan Hayward <alan.hayward@arm.com>
 
        PR tree-optimization/66558
index 2d5adaf7403c0c3338703590b0c1386edd963f21..ca626846f16c5eac65489891a01038b0c3f7d7e6 100644 (file)
@@ -1,3 +1,8 @@
+2015-11-13  Ilya Enkovich  <enkovich.gnu@gmail.com>
+
+       * g++.dg/vect/simd-bool-comparison-1.cc: New test.
+       * g++.dg/vect/simd-bool-comparison-2.cc: New test.
+
 2015-11-13  Dominique d'Humieres <dominiq@lps.ens.fr>
 
        PR fortran/47266
diff --git a/gcc/testsuite/g++.dg/vect/simd-bool-comparison-1.cc b/gcc/testsuite/g++.dg/vect/simd-bool-comparison-1.cc
new file mode 100644 (file)
index 0000000..a08362f
--- /dev/null
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-additional-options "-mavx512bw -mavx512dq" { target { i?86-*-* x86_64-*-* } } }
+
+#define N 1024
+
+double a[N];
+bool b[N];
+bool c;
+
+void test ()
+{
+  int i;
+
+  for (i = 0; i < N; i++)
+    if (b[i] != c)
+      a[i] = 0.0;
+    else
+      a[i] = 1.0;
+}
+
+// { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { i?86-*-* x86_64-*-* } } } }
diff --git a/gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc b/gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc
new file mode 100644 (file)
index 0000000..4accf56
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-additional-options "-mavx512bw -mavx512dq" { target { i?86-*-* x86_64-*-* } } }
+
+#define N 1024
+
+double a[N];
+bool b[N];
+char c[N];
+
+void test ()
+{
+  int i;
+
+  #pragma omp simd
+  for (i = 0; i < N; i++)
+    if ((c[i] > 0) && b[i])
+      a[i] = 0.0;
+    else
+      a[i] = 1.0;
+}
index 4630c86724e9f5df2b33eee4c60d3e7021b777b9..80937eceb9cab8ccda646a062f29a90877250856 100644 (file)
@@ -649,7 +649,32 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
                    }
                  return false;
                }
+             else if (VECTOR_BOOLEAN_TYPE_P (mask_type)
+                      != VECTOR_BOOLEAN_TYPE_P (vectype))
+               {
+                 if (dump_enabled_p ())
+                   {
+                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                                      "not vectorized: mixed mask and "
+                                      "nonmask vector types in statement, ");
+                     dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+                                        mask_type);
+                     dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
+                     dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+                                        vectype);
+                     dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
+                   }
+                 return false;
+               }
            }
+
+         /* We may compare boolean value loaded as vector of integers.
+            Fix mask_type in such case.  */
+         if (mask_type
+             && !VECTOR_BOOLEAN_TYPE_P (mask_type)
+             && gimple_code (stmt) == GIMPLE_ASSIGN
+             && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
+           mask_type = build_same_sized_truth_vector_type (mask_type);
        }
 
       /* No mask_type should mean loop invariant predicate.
index 7873259625f24d398974d818c74c3b9202b3d29e..bf6d1d8011ff51df9d828d83f568e4528a529396 100644 (file)
@@ -2573,6 +2573,57 @@ vect_slp_bb (basic_block bb)
 }
 
 
+/* Return 1 if vector type of boolean constant which is OPNUM
+   operand in statement STMT is a boolean vector.  */
+
+static bool
+vect_mask_constant_operand_p (gimple *stmt, int opnum)
+{
+  stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+  enum tree_code code = gimple_expr_code (stmt);
+  tree op, vectype;
+  gimple *def_stmt;
+  enum vect_def_type dt;
+
+  /* For comparison and COND_EXPR type is chosen depending
+     on the other comparison operand.  */
+  if (TREE_CODE_CLASS (code) == tcc_comparison)
+    {
+      if (opnum)
+       op = gimple_assign_rhs1 (stmt);
+      else
+       op = gimple_assign_rhs2 (stmt);
+
+      if (!vect_is_simple_use (op, stmt_vinfo->vinfo, &def_stmt,
+                              &dt, &vectype))
+       gcc_unreachable ();
+
+      return !vectype || VECTOR_BOOLEAN_TYPE_P (vectype);
+    }
+
+  if (code == COND_EXPR)
+    {
+      tree cond = gimple_assign_rhs1 (stmt);
+
+      if (TREE_CODE (cond) == SSA_NAME)
+       return false;
+
+      if (opnum)
+       op = TREE_OPERAND (cond, 1);
+      else
+       op = TREE_OPERAND (cond, 0);
+
+      if (!vect_is_simple_use (op, stmt_vinfo->vinfo, &def_stmt,
+                              &dt, &vectype))
+       gcc_unreachable ();
+
+      return !vectype || VECTOR_BOOLEAN_TYPE_P (vectype);
+    }
+
+  return VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_vinfo));
+}
+
+
 /* For constant and loop invariant defs of SLP_NODE this function returns
    (vector) defs (VEC_OPRNDS) that will be used in the vectorized stmts.
    OP_NUM determines if we gather defs for operand 0 or operand 1 of the RHS of
@@ -2609,8 +2660,7 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
 
   /* Check if vector type is a boolean vector.  */
   if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE
-      && (VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_vinfo))
-         || (code == COND_EXPR && op_num < 2)))
+      && vect_mask_constant_operand_p (stmt, op_num))
     vector_type
       = build_same_sized_truth_vector_type (STMT_VINFO_VECTYPE (stmt_vinfo));
   else
index 7870b29eab55e5e6ef54483cf7fd8b08e0769ff9..f7eee9116d0982ac11f1a5eadd7d2ccb95708941 100644 (file)
@@ -7645,8 +7645,8 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi,
            }
          else
            {
-             vec_rhs1 = vect_get_vec_def_for_operand (rhs1, stmt, NULL);
-             vec_rhs2 = vect_get_vec_def_for_operand (rhs2, stmt, NULL);
+             vec_rhs1 = vect_get_vec_def_for_operand (rhs1, stmt, vectype);
+             vec_rhs2 = vect_get_vec_def_for_operand (rhs2, stmt, vectype);
            }
        }
       else