Commit e4af0bc4 by Ilya Enkovich Committed by Ilya Enkovich

tree-vect-loop.c (vect_determine_vectorization_factor): Check mix of boolean and…

tree-vect-loop.c (vect_determine_vectorization_factor): Check mix of boolean and integer vectors in a single statement.

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
parent f7259dd4
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
......
// { 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-*-* } } } }
// { 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;
}
......@@ -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.
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment