From: Ilya Enkovich Date: Fri, 13 Nov 2015 11:45:25 +0000 (+0000) Subject: tree-vect-loop.c (vect_determine_vectorization_factor): Check mix of boolean and... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e4af0bc4650f371dc553bccd03d5dfe2704bc660;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d4758ba927..a7517f9bcaa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-11-13 Ilya Enkovich + + * 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 PR tree-optimization/66558 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2d5adaf7403..ca626846f16 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-11-13 Ilya Enkovich + + * 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 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 00000000000..a08362f4591 --- /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 00000000000..4accf56b200 --- /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 4630c86724e..80937eceb9c 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 7873259625f..bf6d1d8011f 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 7870b29eab5..f7eee9116d0 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