+2017-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/81303
+ * tree-vect-stmts.c (vect_is_simple_cond): For invariant
+ conditions try to create a comparison vector type matching
+ the data vector type.
+ (vectorizable_condition): Adjust.
+ * tree-vect-patterns.c (vect_recog_mask_conversion_pattern):
+ Leave invariant conditions alone in case we can vectorize those.
+
2017-12-08 Julia Koval <julia.koval@intel.com>
* config/i386/avx512vnniintrin.h (_mm512_dpwssd_epi32,
+2017-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/81303
+ * gcc.target/i386/vectorize9.c: New testcase.
+ * gcc.target/i386/vectorize10.c: New testcase.
+
2017-12-08 Julia Koval <julia.koval@intel.com>
* gcc.target/i386/avx512f-vnni-1.c: Add vdpwssd checks.
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-loop-vectorize -fdump-tree-vect-details -fno-tree-loop-im -msse2 -mno-avx" } */
+
+double x[1024][1024], red[1024];
+void foo (void)
+{
+ for (int i = 0; i < 1024; ++i)
+ for (int j = 0; j < 1024; ++j)
+ {
+ double v = i == 0 ? 0.0 : red[j];
+ v = v + x[i][j];
+ red[j] = v;
+ }
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-loop-vectorize -fdump-tree-vect-details -fno-tree-loop-im -mavx2 -mprefer-vector-width=256" } */
+
+double x[1024][1024], red[1024];
+void foo (void)
+{
+ for (int i = 0; i < 1024; ++i)
+ for (int j = 0; j < 1024; ++j)
+ {
+ double v = i == 0 ? 0.0 : red[j];
+ v = v + x[i][j];
+ red[j] = v;
+ }
+}
+
+/* { dg-final { scan-tree-dump "vectorization factor = 4" "vect" } } */
|| TYPE_VECTOR_SUBPARTS (vectype1) == TYPE_VECTOR_SUBPARTS (vectype2))
return NULL;
+ /* If rhs1 is invariant and we can promote it leave the COND_EXPR
+ in place, we can handle it in vectorizable_condition. This avoids
+ unnecessary promotion stmts and increased vectorization factor. */
+ if (COMPARISON_CLASS_P (rhs1)
+ && INTEGRAL_TYPE_P (rhs1_type)
+ && TYPE_VECTOR_SUBPARTS (vectype1) < TYPE_VECTOR_SUBPARTS (vectype2))
+ {
+ gimple *dummy;
+ enum vect_def_type dt;
+ if (vect_is_simple_use (TREE_OPERAND (rhs1, 0), stmt_vinfo->vinfo,
+ &dummy, &dt)
+ && dt == vect_external_def
+ && vect_is_simple_use (TREE_OPERAND (rhs1, 1), stmt_vinfo->vinfo,
+ &dummy, &dt)
+ && (dt == vect_external_def
+ || dt == vect_constant_def))
+ {
+ tree wide_scalar_type = build_nonstandard_integer_type
+ (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype1))),
+ TYPE_UNSIGNED (rhs1_type));
+ tree vectype3 = get_vectype_for_scalar_type (wide_scalar_type);
+ if (expand_vec_cond_expr_p (vectype1, vectype3, TREE_CODE (rhs1)))
+ return NULL;
+ }
+ }
+
/* If rhs1 is a comparison we need to move it into a
separate statement. */
if (TREE_CODE (rhs1) != SSA_NAME)
static bool
vect_is_simple_cond (tree cond, vec_info *vinfo,
- tree *comp_vectype, enum vect_def_type *dts)
+ tree *comp_vectype, enum vect_def_type *dts,
+ tree vectype)
{
tree lhs, rhs;
tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
return false;
*comp_vectype = vectype1 ? vectype1 : vectype2;
+ /* Invariant comparison. */
+ if (! *comp_vectype)
+ {
+ tree scalar_type = TREE_TYPE (lhs);
+ /* If we can widen the comparison to match vectype do so. */
+ if (INTEGRAL_TYPE_P (scalar_type)
+ && tree_int_cst_lt (TYPE_SIZE (scalar_type),
+ TYPE_SIZE (TREE_TYPE (vectype))))
+ scalar_type = build_nonstandard_integer_type
+ (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype))),
+ TYPE_UNSIGNED (scalar_type));
+ *comp_vectype = get_vectype_for_scalar_type (scalar_type);
+ }
+
return true;
}
else_clause = gimple_assign_rhs3 (stmt);
if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo,
- &comp_vectype, &dts[0])
+ &comp_vectype, &dts[0], vectype)
|| !comp_vectype)
return false;