From patchwork Thu Sep 5 11:10:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Leoshkevich X-Patchwork-Id: 1158377 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-508382-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="XjvZE9E/"; dkim-atps=neutral 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 46PJ0R3NZMz9sDQ for ; Thu, 5 Sep 2019 21:11:19 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:in-reply-to:references:mime-version :content-transfer-encoding:message-id; q=dns; s=default; b=jqfB/ srdX1zbwtvtItRHVQxtopaqzmwCSKes8a99TyL14x46ZE+Q+c+azbUt+2OhPhqe8 jrCeBlXVUBDGdeWokXCwNNIhdElk4kQPT5ls+oP/Voxe1H07ntjr3kZbZHlGBnNR uq1ltYVxPmWjgD2W9m7KRpCBX/1WVcJOsAj67k= 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:from :to:cc:subject:date:in-reply-to:references:mime-version :content-transfer-encoding:message-id; s=default; bh=g3VgYvSX8P0 cR7VmpWnDWn0PWMU=; b=XjvZE9E/VJYaK0pRi6M94zap/6Tyw92qT6jyDL3dCWi g3WwPpiLBPv/qkMEk+4v6fx86aJRseLk5aJ2S2Zi0ILjnxbT0Kou07slpxREYVW7 NJjhOf3A7OrJAEem/oYeqEBYduHmTGr0OJ5TbmKl2CgWTgepD4U8NEiJ1bFrASFU = Received: (qmail 1731 invoked by alias); 5 Sep 2019 11:11:13 -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 1689 invoked by uid 89); 5 Sep 2019 11:11:13 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.1 spammy=counterpart X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 05 Sep 2019 11:11:11 +0000 Received: from pps.filterd (m0187473.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x85B8CQG159300 for ; Thu, 5 Sep 2019 07:11:08 -0400 Received: from e06smtp07.uk.ibm.com (e06smtp07.uk.ibm.com [195.75.94.103]) by mx0a-001b2d01.pphosted.com with ESMTP id 2usu18r15c-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 05 Sep 2019 07:11:07 -0400 Received: from localhost by e06smtp07.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 5 Sep 2019 12:11:02 +0100 Received: from b06avi18626390.portsmouth.uk.ibm.com (9.149.26.192) by e06smtp07.uk.ibm.com (192.168.101.137) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 5 Sep 2019 12:10:59 +0100 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06avi18626390.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x85BAX8Z36241868 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 5 Sep 2019 11:10:33 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 60748A4055; Thu, 5 Sep 2019 11:10:57 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1A09BA404D; Thu, 5 Sep 2019 11:10:57 +0000 (GMT) Received: from white.boeblingen.de.ibm.com (unknown [9.152.97.226]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 5 Sep 2019 11:10:57 +0000 (GMT) From: Ilya Leoshkevich To: gcc-patches@gcc.gnu.org Cc: richard.guenther@gmail.com, richard.sandiford@arm.com, segher@kernel.crashing.org, joseph@codesourcery.com, krebbel@linux.ibm.com, rdapp@linux.ibm.com, Ilya Leoshkevich Subject: [PATCH v3 3/9] Introduce can_vector_compare_p function Date: Thu, 5 Sep 2019 13:10:13 +0200 In-Reply-To: <20190905111019.8951-1-iii@linux.ibm.com> References: <20190905111019.8951-1-iii@linux.ibm.com> MIME-Version: 1.0 x-cbid: 19090511-0028-0000-0000-0000039802FE X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19090511-0029-0000-0000-0000245A5829 Message-Id: <20190905111019.8951-4-iii@linux.ibm.com> X-IsSubscribed: yes z13 supports only non-signaling vector comparisons. This means we cannot vectorize LT, LE, GT, GE and LTGT when compiling for z13. However, we cannot express this restriction today: the code only checks whether vcond$a$b optab exists, which does not contain information about the operation. Introduce a function that checks whether back-end supports vector comparisons with individual rtx codes by matching vcond expander's third argument with a fake comparison with the corresponding rtx code. gcc/ChangeLog: 2019-08-27 Ilya Leoshkevich PR target/77918 * optabs-tree.c (vcond_icode_p): New function. (vcond_eq_icode_p): New function. (expand_vec_cond_expr_p): Use vcond_icode_p and vcond_eq_icode_p. * optabs.c (can_vector_compare_p): New function. (get_rtx_code): Use get_rtx_code_safe. (get_rtx_code_safe): New function. * optabs.h (enum can_vector_compare_purpose): New enum. (can_vector_compare_p): New function. (get_rtx_code_safe): Likewise. --- gcc/optabs-tree.c | 41 +++++++++++++++++++++++++++++++++-------- gcc/optabs.c | 43 +++++++++++++++++++++++++++++++++++++++---- gcc/optabs.h | 16 ++++++++++++++++ 3 files changed, 88 insertions(+), 12 deletions(-) diff --git a/gcc/optabs-tree.c b/gcc/optabs-tree.c index 8157798cc71..ff7237187dd 100644 --- a/gcc/optabs-tree.c +++ b/gcc/optabs-tree.c @@ -23,7 +23,10 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "target.h" #include "insn-codes.h" +#include "rtl.h" #include "tree.h" +#include "memmodel.h" +#include "optabs.h" #include "optabs-tree.h" #include "stor-layout.h" @@ -329,6 +332,34 @@ expand_vec_cmp_expr_p (tree value_type, tree mask_type, enum tree_code code) return false; } +/* Return TRUE iff vcond_optab/vcondu_optab support the given tree + comparison. */ + +static bool +vcond_icode_p (tree value_type, tree cmp_op_type, enum tree_code code) +{ + enum rtx_code rcode = get_rtx_code_safe (code, TYPE_UNSIGNED (cmp_op_type)); + if (rcode == LAST_AND_UNUSED_RTX_CODE) + /* This may happen, for example, if code == SSA_NAME, in which case we + cannot be certain whether a vector insn is available. */ + return false; + + return can_vector_compare_p (rcode, TYPE_MODE (value_type), + TYPE_MODE (cmp_op_type), cvcp_vcond); +} + +/* Return TRUE iff vcondeq_optab supports the given tree comparison. */ + +static bool +vcond_eq_icode_p (tree value_type, tree cmp_op_type, enum tree_code code) +{ + if (code != EQ_EXPR && code != NE_EXPR) + return false; + + return get_vcond_eq_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type)) + != CODE_FOR_nothing; +} + /* Return TRUE iff, appropriate vector insns are available for vector cond expr with vector type VALUE_TYPE and a comparison with operand vector types in CMP_OP_TYPE. */ @@ -347,14 +378,8 @@ expand_vec_cond_expr_p (tree value_type, tree cmp_op_type, enum tree_code code) || maybe_ne (GET_MODE_NUNITS (value_mode), GET_MODE_NUNITS (cmp_op_mode))) return false; - if (get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type), - TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing - && ((code != EQ_EXPR && code != NE_EXPR) - || get_vcond_eq_icode (TYPE_MODE (value_type), - TYPE_MODE (cmp_op_type)) == CODE_FOR_nothing)) - return false; - - return true; + return vcond_icode_p (value_type, cmp_op_type, code) + || vcond_eq_icode_p (value_type, cmp_op_type, code); } /* Use the current target and options to initialize diff --git a/gcc/optabs.c b/gcc/optabs.c index cdd07f3e53f..479789570a9 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -3819,6 +3819,30 @@ can_compare_p (enum rtx_code code, machine_mode mode, return 0; } +/* Return whether back-end can emit a vector comparison insn(s) using a given + CODE, with operands with CMP_OP_MODE, producing a result with VALUE_MODE, + in order to achieve a PURPOSE. */ + +bool +can_vector_compare_p (enum rtx_code code, machine_mode value_mode, + machine_mode cmp_op_mode, + enum can_vector_compare_purpose purpose) +{ + enum insn_code icode; + bool unsigned_p = (code == LTU || code == LEU || code == GTU || code == GEU); + rtx reg1 = alloca_raw_REG (cmp_op_mode, LAST_VIRTUAL_REGISTER + 1); + rtx reg2 = alloca_raw_REG (cmp_op_mode, LAST_VIRTUAL_REGISTER + 2); + rtx test = alloca_rtx_fmt_ee (code, value_mode, reg1, reg2); + + if (purpose == cvcp_vcond + && (icode = get_vcond_icode (value_mode, cmp_op_mode, unsigned_p)) + != CODE_FOR_nothing + && insn_operand_matches (icode, 3, test)) + return true; + + return false; +} + /* This function is called when we are going to emit a compare instruction that compares the values found in X and Y, using the rtl operator COMPARISON. @@ -5348,11 +5372,11 @@ gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode) return insn; } -/* Return rtx code for TCODE. Use UNSIGNEDP to select signed - or unsigned operation code. */ +/* Return rtx code for TCODE or LAST_AND_UNUSED_RTX_CODE if it has no RTL + counterpart. Use UNSIGNEDP to select signed or unsigned operation code. */ enum rtx_code -get_rtx_code (enum tree_code tcode, bool unsignedp) +get_rtx_code_safe (enum tree_code tcode, bool unsignedp) { enum rtx_code code; switch (tcode) @@ -5410,11 +5434,22 @@ get_rtx_code (enum tree_code tcode, bool unsignedp) break; default: - gcc_unreachable (); + code = LAST_AND_UNUSED_RTX_CODE; + break; } return code; } +/* Like get_rtx_code_safe, but asserts when given unsupported tree codes. */ + +enum rtx_code +get_rtx_code (enum tree_code tcode, bool unsignedp) +{ + enum rtx_code code = get_rtx_code_safe (tcode, unsignedp); + gcc_assert (code != LAST_AND_UNUSED_RTX_CODE); + return code; +} + /* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to select signed or unsigned operators. OPNO holds the index of the first comparison operand for insn ICODE. Do not generate the diff --git a/gcc/optabs.h b/gcc/optabs.h index 897bb5d4443..712470a0245 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -242,6 +242,21 @@ enum can_compare_purpose (without splitting it into pieces). */ extern int can_compare_p (enum rtx_code, machine_mode, enum can_compare_purpose); + +/* The various uses that a vector comparison can have; used by + can_vector_compare_p. So far only vcond is defined, vec_cmp is a possible + future extension. */ +enum can_vector_compare_purpose +{ + cvcp_vcond +}; + +/* Return whether back-end can emit a vector comparison insn(s) using a given + CODE, with operands with CMP_OP_MODE, producing a result with VALUE_MODE, + in order to achieve a PURPOSE. */ +extern bool can_vector_compare_p (enum rtx_code, machine_mode, machine_mode, + enum can_vector_compare_purpose); + extern rtx prepare_operand (enum insn_code, rtx, int, machine_mode, machine_mode, int); /* Emit a pair of rtl insns to compare two rtx's and to jump @@ -356,6 +371,7 @@ extern void expand_insn (enum insn_code icode, unsigned int nops, extern void expand_jump_insn (enum insn_code icode, unsigned int nops, class expand_operand *ops); +extern enum rtx_code get_rtx_code_safe (enum tree_code tcode, bool unsignedp); extern enum rtx_code get_rtx_code (enum tree_code tcode, bool unsignedp); #endif /* GCC_OPTABS_H */