+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
+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
--- /dev/null
+// { 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-*-* } } } }
--- /dev/null
+// { 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;
+}
}
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.
}
+/* 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
/* 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
}
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