Message ID | 20151013141433.GM63757@msticlxl57.ims.intel.com |
---|---|
State | New |
Headers | show |
On 10/13/2015 08:14 AM, Ilya Enkovich wrote: >>> + >>> +static tree >>> +build_vec_cmp (tree_code code, tree type, >>> + tree arg0, tree arg1) >>> +{ >>> + tree zero_vec = build_zero_cst (type); >>> + tree minus_one_vec = build_minus_one_cst (type); >>> + tree cmp_type = build_same_sized_truth_vector_type (type); >>> + tree cmp = build2 (code, cmp_type, arg0, arg1); >>> + return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec); >>> +} >> Isn't this implementation the same for C & C++? Does it make sense to put >> it in c-family/c-common.c? > > C++ version calls fold_if_not_in_template for generated comparison. It is required there to successfully recognize vector MIN, MAX and ABS templates for vector ?: conditional operator. Vector form of ?: conditional operator is supported for C++ only. Ah, nevermind then. >> >> However, more generally, do we need to do anything for the other languages? > > Looking into that I got an impression vector modes are used by C/C++ vector extensions only. And I think regression testing would reveal some failures otherwise. Maybe this stuff hasn't bled into the Fortran front-end, but the gfortran front-end certainly has OpenMP support which presumably has vector extensions. The fact that nothing's failing in the testsuite is encouraging, but it'd be worth spending a few minutes taking a look to see if there's something that might need updating. Jeff
2015-10-13 18:42 GMT+03:00 Jeff Law <law@redhat.com>: > On 10/13/2015 08:14 AM, Ilya Enkovich wrote: >>>> >>>> + >>>> +static tree >>>> +build_vec_cmp (tree_code code, tree type, >>>> + tree arg0, tree arg1) >>>> +{ >>>> + tree zero_vec = build_zero_cst (type); >>>> + tree minus_one_vec = build_minus_one_cst (type); >>>> + tree cmp_type = build_same_sized_truth_vector_type (type); >>>> + tree cmp = build2 (code, cmp_type, arg0, arg1); >>>> + return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec); >>>> +} >>> >>> Isn't this implementation the same for C & C++? Does it make sense to >>> put >>> it in c-family/c-common.c? >> >> >> C++ version calls fold_if_not_in_template for generated comparison. It is >> required there to successfully recognize vector MIN, MAX and ABS templates >> for vector ?: conditional operator. Vector form of ?: conditional operator >> is supported for C++ only. > > Ah, nevermind then. > > >>> >>> However, more generally, do we need to do anything for the other >>> languages? >> >> >> Looking into that I got an impression vector modes are used by C/C++ >> vector extensions only. And I think regression testing would reveal some >> failures otherwise. > > Maybe this stuff hasn't bled into the Fortran front-end, but the gfortran > front-end certainly has OpenMP support which presumably has vector > extensions. OpenMP extension doesn't produce any vector code in front-end. Code will be produced by vectorizer anyway. > > The fact that nothing's failing in the testsuite is encouraging, but it'd be > worth spending a few minutes taking a look to see if there's something that > might need updating. I also grepped for VEC_COND_EXPR and it never occurs in front-ends other than C/C++. Thanks, Ilya > > Jeff >
On 10/13/2015 09:59 AM, Ilya Enkovich wrote: >>> >>> Looking into that I got an impression vector modes are used by C/C++ >>> vector extensions only. And I think regression testing would reveal some >>> failures otherwise. >> >> Maybe this stuff hasn't bled into the Fortran front-end, but the gfortran >> front-end certainly has OpenMP support which presumably has vector >> extensions. > > OpenMP extension doesn't produce any vector code in front-end. Code > will be produced by vectorizer anyway. > >> >> The fact that nothing's failing in the testsuite is encouraging, but it'd be >> worth spending a few minutes taking a look to see if there's something that >> might need updating. > > I also grepped for VEC_COND_EXPR and it never occurs in front-ends > other than C/C++. Perfect. Thanks. Was that the last question on the boolean vector patches? If so, then I think they're OK for the trunk. jeff
2015-10-21 0:34 GMT+03:00 Jeff Law <law@redhat.com>: > On 10/13/2015 09:59 AM, Ilya Enkovich wrote: >>>> >>>> >>>> Looking into that I got an impression vector modes are used by C/C++ >>>> vector extensions only. And I think regression testing would reveal >>>> some >>>> failures otherwise. >>> >>> >>> Maybe this stuff hasn't bled into the Fortran front-end, but the gfortran >>> front-end certainly has OpenMP support which presumably has vector >>> extensions. >> >> >> OpenMP extension doesn't produce any vector code in front-end. Code >> will be produced by vectorizer anyway. >> >>> >>> The fact that nothing's failing in the testsuite is encouraging, but it'd >>> be >>> worth spending a few minutes taking a look to see if there's something >>> that >>> might need updating. >> >> >> I also grepped for VEC_COND_EXPR and it never occurs in front-ends >> other than C/C++. > > Perfect. Thanks. > > Was that the last question on the boolean vector patches? If so, then I > think they're OK for the trunk. > > jeff > I think there are no unanswered question. So I'll rebase it on the latest trunk, test and commit. Thanks, Ilya
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index df3245a..8fe6a74 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -4771,6 +4771,18 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, && TREE_CODE (orig_op2) == INTEGER_CST && !TREE_OVERFLOW (orig_op2))); } + + /* Need to convert condition operand into a vector mask. */ + if (VECTOR_TYPE_P (TREE_TYPE (ifexp))) + { + tree vectype = TREE_TYPE (ifexp); + tree elem_type = TREE_TYPE (vectype); + tree zero = build_int_cst (elem_type, 0); + tree zero_vec = build_vector_from_val (vectype, zero); + tree cmp_type = build_same_sized_truth_vector_type (vectype); + ifexp = build2 (NE_EXPR, cmp_type, ifexp, zero_vec); + } + if (int_const || (ifexp_bcp && TREE_CODE (ifexp) == INTEGER_CST)) ret = fold_build3_loc (colon_loc, COND_EXPR, result_type, ifexp, op1, op2); else @@ -10237,6 +10249,20 @@ push_cleanup (tree decl, tree cleanup, bool eh_only) STATEMENT_LIST_STMT_EXPR (list) = stmt_expr; } +/* Build a vector comparison of ARG0 and ARG1 using CODE opcode + into a value of TYPE type. Comparison is done via VEC_COND_EXPR. */ + +static tree +build_vec_cmp (tree_code code, tree type, + tree arg0, tree arg1) +{ + tree zero_vec = build_zero_cst (type); + tree minus_one_vec = build_minus_one_cst (type); + tree cmp_type = build_same_sized_truth_vector_type (type); + tree cmp = build2 (code, cmp_type, arg0, arg1); + return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec); +} + /* Build a binary-operation expression without default conversions. CODE is the kind of expression to build. LOCATION is the operator's location. @@ -10803,7 +10829,8 @@ build_binary_op (location_t location, enum tree_code code, result_type = build_opaque_vector_type (intt, TYPE_VECTOR_SUBPARTS (type0)); converted = 1; - break; + ret = build_vec_cmp (resultcode, result_type, op0, op1); + goto return_build_binary_op; } if (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)) warning_at (location, @@ -10955,7 +10982,8 @@ build_binary_op (location_t location, enum tree_code code, result_type = build_opaque_vector_type (intt, TYPE_VECTOR_SUBPARTS (type0)); converted = 1; - break; + ret = build_vec_cmp (resultcode, result_type, op0, op1); + goto return_build_binary_op; } build_type = integer_type_node; if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f8db2df..55b3c8c 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4627,6 +4627,15 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3, if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg1))) { + /* If arg1 is another cond_expr choosing between -1 and 0, + then we can use its comparison. It may help to avoid + additional comparison, produce more accurate diagnostics + and enables folding. */ + if (TREE_CODE (arg1) == VEC_COND_EXPR + && integer_minus_onep (TREE_OPERAND (arg1, 1)) + && integer_zerop (TREE_OPERAND (arg1, 2))) + arg1 = TREE_OPERAND (arg1, 0); + arg1 = force_rvalue (arg1, complain); arg2 = force_rvalue (arg2, complain); arg3 = force_rvalue (arg3, complain); @@ -4739,8 +4748,10 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3, } if (!COMPARISON_CLASS_P (arg1)) - arg1 = cp_build_binary_op (loc, NE_EXPR, arg1, - build_zero_cst (arg1_type), complain); + { + tree cmp_type = build_same_sized_truth_vector_type (arg1_type); + arg1 = build2 (NE_EXPR, cmp_type, arg1, build_zero_cst (arg1_type)); + } return fold_build3 (VEC_COND_EXPR, arg2_type, arg1, arg2, arg3); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9e6f949..3147609 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3916,6 +3916,20 @@ build_binary_op (location_t location, enum tree_code code, tree op0, tree op1, return cp_build_binary_op (location, code, op0, op1, tf_warning_or_error); } +/* Build a vector comparison of ARG0 and ARG1 using CODE opcode + into a value of TYPE type. Comparison is done via VEC_COND_EXPR. */ + +static tree +build_vec_cmp (tree_code code, tree type, + tree arg0, tree arg1) +{ + tree zero_vec = build_zero_cst (type); + tree minus_one_vec = build_minus_one_cst (type); + tree cmp_type = build_same_sized_truth_vector_type(type); + tree cmp = build2 (code, cmp_type, arg0, arg1); + cmp = fold_if_not_in_template (cmp); + return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec); +} /* Build a binary-operation expression without default conversions. CODE is the kind of expression to build. @@ -4785,7 +4799,7 @@ cp_build_binary_op (location_t location, result_type = build_opaque_vector_type (intt, TYPE_VECTOR_SUBPARTS (type0)); converted = 1; - break; + return build_vec_cmp (resultcode, result_type, op0, op1); } build_type = boolean_type_node; if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE diff --git a/gcc/testsuite/g++.dg/ext/vector22.C b/gcc/testsuite/g++.dg/ext/vector22.C index daf4e19..5d28637 100644 --- a/gcc/testsuite/g++.dg/ext/vector22.C +++ b/gcc/testsuite/g++.dg/ext/vector22.C @@ -18,4 +18,3 @@ void h(vec*a){ } /* { dg-final { scan-tree-dump-not "~" "gimple" } } */ -/* { dg-final { scan-tree-dump-not "VEC_COND_EXPR" "gimple" } } */