diff options
author | Ilya Enkovich <enkovich.gnu@gmail.com> | 2015-11-13 11:45:25 +0000 |
---|---|---|
committer | Ilya Enkovich <ienkovich@gcc.gnu.org> | 2015-11-13 11:45:25 +0000 |
commit | e4af0bc4650f371dc553bccd03d5dfe2704bc660 (patch) | |
tree | ad5f4cf9d3ab2efb6a3c4da48f6a2d31e1790633 | |
parent | f7259dd4be3a6edba6035e2d7c580ee11ed16800 (diff) | |
download | gcc-e4af0bc4650f371dc553bccd03d5dfe2704bc660.zip gcc-e4af0bc4650f371dc553bccd03d5dfe2704bc660.tar.gz gcc-e4af0bc4650f371dc553bccd03d5dfe2704bc660.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/vect/simd-bool-comparison-1.cc | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc | 20 | ||||
-rw-r--r-- | gcc/tree-vect-loop.c | 25 | ||||
-rw-r--r-- | gcc/tree-vect-slp.c | 54 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 4 |
7 files changed, 135 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d4758b..a7517f9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2d5adaf..ca62684 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..a08362f --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/simd-bool-comparison-1.cc @@ -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 index 0000000..4accf56 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc @@ -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; +} diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 4630c86..80937ec 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -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. diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 7873259..bf6d1d8 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -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 diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 7870b29..f7eee91 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -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 |