From patchwork Tue Oct 13 14:14:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 529755 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E4BA21402A1 for ; Wed, 14 Oct 2015 01:15:25 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=D2iHkDSS; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=Xi940X3mOJbOiWEQN ykYumPJQO9zw25YZdVxsKpoSYhqsZuMXEir/zt2qa+PQupJfLOJx1yYemZAP1H5z VIJRAXO9Sk9muErwvph/Hm64Tsv7+CGH5XqjTfwAG7yjUAZoh52YECcVQO29RcFK W7cML/Pk8zRwEsAXTQTuhJdAYI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=HYaS/v1ChRSsV9qV10vvMuR yQtI=; b=D2iHkDSS+BeIOL4gGCFfPfEOpQVW+uOdiaodOZ/MlqdJttOscWzLbhd 1GbP5PBATo2saUQki2DHGyz0uPxtsTjm5xJSiQcQrce5zVdCWum0YIIGo9Exoovg gBtYR9hy35E+s0eRydWEZxT3nXe74evJD4R25rPu94uNoUcEfpg4= Received: (qmail 8050 invoked by alias); 13 Oct 2015 14:15:15 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 8035 invoked by uid 89); 13 Oct 2015 14:15:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-qk0-f177.google.com Received: from mail-qk0-f177.google.com (HELO mail-qk0-f177.google.com) (209.85.220.177) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 13 Oct 2015 14:15:13 +0000 Received: by qkas79 with SMTP id s79so8006567qka.0 for ; Tue, 13 Oct 2015 07:15:11 -0700 (PDT) X-Received: by 10.194.235.6 with SMTP id ui6mr43492999wjc.92.1444745710826; Tue, 13 Oct 2015 07:15:10 -0700 (PDT) Received: from msticlxl57.ims.intel.com ([134.134.139.77]) by smtp.gmail.com with ESMTPSA id p4sm15215647wia.15.2015.10.13.07.15.08 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 Oct 2015 07:15:10 -0700 (PDT) Date: Tue, 13 Oct 2015 17:14:33 +0300 From: Ilya Enkovich To: Jeff Law Cc: gcc-patches@gcc.gnu.org Subject: Re: [Boolean Vector, patch 3/5] Use boolean vector in C/C++ FE Message-ID: <20151013141433.GM63757@msticlxl57.ims.intel.com> References: <20151002140449.GG26618@msticlxl57.ims.intel.com> <561828E4.6070905@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <561828E4.6070905@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes On 09 Oct 14:51, Jeff Law wrote: > On 10/02/2015 08:04 AM, Ilya Enkovich wrote: > >Hi, > > > >This patch makes C/C++ FE to use boolean vector as a resulting type for vector comparison. As a result vector comparison in source code now parsed into VEC_COND_EXPR, it required a testcase fix-up. > > > >Thanks, > >Ilya > >-- > >gcc/c > > > >2015-10-02 Ilya Enkovich > > > > * c-typeck.c (build_conditional_expr): Use boolean vector > > type for vector comparison. > > (build_vec_cmp): New. > > (build_binary_op): Use build_vec_cmp for comparison. > > > >gcc/cp > > > >2015-10-02 Ilya Enkovich > > > > * call.c (build_conditional_expr_1): Use boolean vector > > type for vector comparison. > > * typeck.c (build_vec_cmp): New. > > (cp_build_binary_op): Use build_vec_cmp for comparison. > > > >gcc/testsuite/ > > > >2015-10-02 Ilya Enkovich > > > > * g++.dg/ext/vector22.C: Allow VEC_COND_EXPR. > > > > > >diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c > >index 3b26231..3f64d76 100644 > >--- a/gcc/c/c-typeck.c > >+++ b/gcc/c/c-typeck.c > >@@ -10220,6 +10232,19 @@ push_cleanup (tree decl, tree cleanup, bool eh_only) > > STATEMENT_LIST_STMT_EXPR (list) = stmt_expr; > > } > > > >+/* Build a vector comparison using VEC_COND_EXPR. */ > Please make sure your function comments include descriptions of all the > arguments and return values. Fixed. > > > >+ > >+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. > > > >+ > > /* Build a binary-operation expression without default conversions. > > CODE is the kind of expression to build. > > LOCATION is the operator's location. > >@@ -10786,7 +10811,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; > I suspect there's some kind of whitespace/tab problem. Those two lines > should be indented the same, right? Fixed. > > > > } > > if (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)) > > warning_at (location, > >@@ -10938,7 +10964,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; > Similarly here. > > With the items above fixed, this is OK. > > 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. > > Jeff Here is an updated version. Thanks, Ilya --- gcc/c 2015-10-02 Ilya Enkovich * c-typeck.c (build_conditional_expr): Use boolean vector type for vector comparison. (build_vec_cmp): New. (build_binary_op): Use build_vec_cmp for comparison. gcc/cp 2015-10-02 Ilya Enkovich * call.c (build_conditional_expr_1): Use boolean vector type for vector comparison. * typeck.c (build_vec_cmp): New. (cp_build_binary_op): Use build_vec_cmp for comparison. gcc/testsuite/ 2015-10-02 Ilya Enkovich * g++.dg/ext/vector22.C: Allow VEC_COND_EXPR. 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" } } */