From patchwork Mon Oct 31 11:53:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tamar Christina X-Patchwork-Id: 59643 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5EF1F385483B for ; Mon, 31 Oct 2022 11:54:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5EF1F385483B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1667217246; bh=HNWDfr82PEJwa/wdkliSCwAyJPtcDAix7rYs/3XsG40=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=Q38rLjVIy5C8bBLBL876oK0UWj7IoVYRnN9YkVixFlASv1xEKHhXAsk4z8pwy0VVz BmvSPGr+skbXVoT4/Ohh4eJnB9c5KL/Tvty50TVoQf1GP8H2kNZb21WsHcgD6DWQcz 9+oALXJzKn5UQd2oMPtlMZDxSnpxBzWONkMUvN6I= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2042.outbound.protection.outlook.com [40.107.21.42]) by sourceware.org (Postfix) with ESMTPS id C4B30385C418 for ; Mon, 31 Oct 2022 11:53:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C4B30385C418 ARC-Seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=YiOQEVcaHVgVWjmn18HbFcd1UAd3dhKT/QwGi3JB9JuIvn/eWd0jsGu+FX3lOVqP+tQKrpRGRUyTAStDWDSekT8PkVBj7d6y8EGJcDCljSD6Y645FY6JvTaOAnz28Ub7auUf+LoUij2d3H33PrNDeQiDLiyam7iNJGr6W0O00d3XK2wmfuwZSr60K171RrOGiy3bpciS8dq7aLBFhDgCEFhfhur7a56V6bKgaqvi0/i+34CtFjRpBDk1Ci8zwo+LonDn3stg9kAdlAP9pK/heTdYeu8OaOaeVJ+ezafxYtRPs1Ld5ESVFub/0Bk1gTpQ45OWqNZBtMlTU1g0tMdSIg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=HNWDfr82PEJwa/wdkliSCwAyJPtcDAix7rYs/3XsG40=; b=kjbqWhIljYKyjtWKH2ZzX/caXMGGqBS7T/BlouZ4+uNqzgN2GWUWOKqhAKiNKvmuJRm84z1l8dpJqYfgLb0uhLVBCmWSZE34/QCKcVfZvJW9P7Y02DXTqOejEK/Plpz45ZlWxEfR1kkofR2NSkzn3v+nU69VFjr3q2vGwxoOElmLi50QUxWtuF5e72dqyYqVdSNNs3S3JpnuaRto/p8hHpt4Av4LMmgDgcU93PFzHYrTNlHvalQbUSZVhmNWmTzYVzmawIn+XKqZ1ZW4V25X12k5A7e7rYgMlNY/+FYmKIDNF00HsH06cMPElVj9Xons+44M8gaFc3zmAia5Iw7UFA== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 63.35.35.123) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com]) Received: from AM5PR0701CA0057.eurprd07.prod.outlook.com (2603:10a6:203:2::19) by GV2PR08MB9376.eurprd08.prod.outlook.com (2603:10a6:150:d0::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5769.15; Mon, 31 Oct 2022 11:53:29 +0000 Received: from AM7EUR03FT028.eop-EUR03.prod.protection.outlook.com (2603:10a6:203:2:cafe::59) by AM5PR0701CA0057.outlook.office365.com (2603:10a6:203:2::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5791.15 via Frontend Transport; Mon, 31 Oct 2022 11:53:29 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by AM7EUR03FT028.mail.protection.outlook.com (100.127.140.192) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5769.14 via Frontend Transport; Mon, 31 Oct 2022 11:53:29 +0000 Received: ("Tessian outbound 0800d254cb3b:v130"); Mon, 31 Oct 2022 11:53:28 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: d0e9378248163ef6 X-CR-MTA-TID: 64aa7808 Received: from 0ea9e0f94ffe.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id F3892B1E-C553-4451-9396-E392AD2635D0.1; Mon, 31 Oct 2022 11:53:21 +0000 Received: from EUR04-HE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 0ea9e0f94ffe.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Mon, 31 Oct 2022 11:53:21 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=XeXzvR42Hf/AW2ysbTkfbtr4vzb//A0Y4AhNgthVzrzqr4bTdbhD8poFGERX8Jbajp5rLqMp+CS4NZQ12E5MvFxXszekBNsH4OmLZ2mtBomdtXL82VtLHd5ZVezd3zBnZVRb6pgypn8sNwUZorNd/E72s1YXDCXeacnS7N+kwH9Uaa9vAfgOzkIHeDExSQyEfNOIWEwFJRHKlQAIkscaKDNjX+fl/xRb3S1jJtZmsdcBWFemVd6tZiJJW+2BYBvQt4GN3uaJwMDevYArSknt+vx/CZSooToOSKqvLjQD9EdA3PLI6ZwFm8MUljbYNmX3ogPpK055IOF+j0VNpFs8Uw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=HNWDfr82PEJwa/wdkliSCwAyJPtcDAix7rYs/3XsG40=; b=YftC9+KllD6pAxzMSeofd2Xt8MidDS1w82L1GHpyvL3fROJms00Bjg4xpMRZ/WpPapLSnUJtFM5TKyk5Pc0tFAtxiAgjIaK4KHtZWMeCPIwRJbWIaWJBfrDXdd8eg3CNEfnjUJ5dSDTUO14qZP24i8vAp81DfcNDpjEgYNkihav0deD4PhQkvQoFj6eix+ziKnRrtAfIjcBQpYx16+FsIOOapZPBkWhCfjDQNAUPMPonaqsAv16eB42zwavOesQ7R9VL8PLP1Bo+oZwoH/vEs02UGQRDRtFUrJ310L6Y1WiSfBoW8OtyeM5HlSWknYnJTj0OLhifR6ZlkgMDsaEm5g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) by GV2PR08MB8319.eurprd08.prod.outlook.com (2603:10a6:150:b5::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5769.19; Mon, 31 Oct 2022 11:53:16 +0000 Received: from VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::c57d:50c2:3502:a52]) by VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::c57d:50c2:3502:a52%4]) with mapi id 15.20.5769.019; Mon, 31 Oct 2022 11:53:16 +0000 Date: Mon, 31 Oct 2022 11:53:08 +0000 To: gcc-patches@gcc.gnu.org Subject: [PATCH 1/2]middle-end: Add new tbranch optab to add support for bit-test-and-branch operations Message-ID: Content-Disposition: inline X-ClientProxiedBy: SA0PR11CA0055.namprd11.prod.outlook.com (2603:10b6:806:d0::30) To VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: VI1PR08MB5325:EE_|GV2PR08MB8319:EE_|AM7EUR03FT028:EE_|GV2PR08MB9376:EE_ X-MS-Office365-Filtering-Correlation-Id: 6ff6d17a-1ae2-4565-2bac-08dabb3686e0 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: MQk6/TqhFRlUWwVsxVLTfwP5h0TijRZANz02VpdoJaKUsFQ8mMsBlQb4nmdmMhmpVaNNp6WXDG/lfRUhRpVfkKsuDk6yXPmFzk9pX3bm+3PK7u41qZEfB0wM/iWDECvGEBJ7v7APKlm39D0AUOFZKvAbzHZEmd+bVXycqbOpsCEtoyhu/hg+clO8+/It9ZV5C3Q8dYnCl6Afu4+Eh+0I10EnA+RVqmkkrge3AIB+mHksGNLOpIn3FQSkn0RALV3AgrUTYiV4CZbIhDTtSWdkPYiPGuRGCGy2tlJwDEJCimFZYPe2f/rpKXfK65bvUsUKU6DIHhNIcFriDPkKNNrDEIDSSkSkzLi59cVOR8ciQ9/ypR7QpZ9uQ1CNN7tMNoBIKlv9UuwX5g96EqKSm4Kr1L+ENEVjn5/EiCL5BQZ/C46/X02dARt8Lr4BKTpp8h9m69O2RYgzgbaAuWATP+iz0AbrmbnJfo1fbRx47GI1mt2Aiugu/WDh0znnR+LkxrOpJEK7LI3bwTFQojcvtqJFcYSunVOAUbMPRr9mgMwVLhWRDnX++zWvkn4jSvwt5MKCPIv0PJ9RO6aDRJuJxL4OB+2KfCwpU1rEgTucWSiEAqGrB5ZpNG35p99oLaiPo8FLDL59UpTBKCFhf8KaT7zH8QHtAtuahskbTIyxTpjN3iVF2ja4kK+KtCwiHjcLO3Ui9Niky9ixkj1PH9D2oMwnF7NNEpjGlqOXuG3JwFISnTRrK3D9whTfOvqKw4bmAnZJ3w4or3E/TLTsJE5GiE2eNxhwYa7wv6XIupkmwsXeUMU= X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR08MB5325.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230022)(4636009)(366004)(396003)(136003)(346002)(376002)(39860400002)(451199015)(6512007)(26005)(33964004)(6506007)(44144004)(6486002)(36756003)(478600001)(6666004)(6916009)(316002)(38100700002)(86362001)(2616005)(186003)(83380400001)(4743002)(66556008)(66476007)(41300700001)(30864003)(235185007)(8676002)(66946007)(2906002)(5660300002)(4326008)(8936002)(44832011)(4216001)(2700100001); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV2PR08MB8319 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM7EUR03FT028.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 22282a0f-f3a0-4728-c7aa-08dabb367f05 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: CAheCj8QLe6knTM8AIz2leBXAcoG+nrYuSx4bWxQCQPkoRkuI0xnUcBt81F202Kh0jit/QwgbiFU6e8d1ZZdjRf2KuyC84Fc5a+1z2KDOH9/NYqKCA4jQuOYRJhaTIlAMunc7X25hzz5Hg5tZdrP0uA8iNMTVDiiy/B3nityrQTIjruZl8PkPdE/mxdBWSkDMzeP32y9hiaJzEjKdiN2amDhiK+F4PZjTFJpwK7I5f8eHQXo58uwM76bxhKeVjPKk+3IDpK3CZKLHgqEB9VKr/HUQa4g/EWZhLlIxpnKulNJKgx2xrXREzMVRFKJGH5r7aKGGTDWvyQaYB4QHBacjRbdhdmsMdP7N7ez1ks0K5JZLGlUo8FQIQxlU15U3sBCsxl3hRs0JYzacYl5AqGdY5w7uduaa03c+u6fZd2cPLPcZs80sndcvXTkOQW50c2imuGBBnV2yplGUqgCtAqpCtutlXZci3cSOL2/zjkcrH0fFGQb0eyY0EkiIVNfhRgzq6mcB3AcadSYLTqBeV3c1kNJYAiwYMCSwKlNK0HYYFYmbhNSGSGh7hOUQVqRAs5Ros2c8vSWdQh5Wpm3C/jYFzji9l3xCk77hsN2ZVaq+MU4J5fLIbWV5N0+6fbzf2WPGxT52Tkyf6PIqnZDNnBjLzhoiJ38sfOSrBRD7wcrLx5dz0+8O1gVF2G0wHRRuTpec8XbDgRQ1mSg7Flb/LjGqYaERz8IZE2v1QWC+nSdWc8kqMVYOfsig0jYhgHqjp/982J6Prlpbp7J9ffaU5ROAcfsW3WEMK4qha+z5AyKnoQ8CEqhe8wAGf5h51tVWC5F X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFS:(13230022)(4636009)(39860400002)(346002)(396003)(376002)(136003)(451199015)(36840700001)(40470700004)(46966006)(478600001)(44832011)(2906002)(235185007)(8936002)(5660300002)(6506007)(36756003)(83380400001)(41300700001)(36860700001)(6486002)(316002)(70586007)(70206006)(8676002)(4326008)(6916009)(336012)(47076005)(6666004)(86362001)(82310400005)(30864003)(2616005)(107886003)(40460700003)(356005)(186003)(33964004)(82740400003)(4743002)(26005)(40480700001)(44144004)(6512007)(81166007)(4216001)(2700100001); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 Oct 2022 11:53:29.1031 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6ff6d17a-1ae2-4565-2bac-08dabb3686e0 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: AM7EUR03FT028.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV2PR08MB9376 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_NONE, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_NONE, TXREP, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tamar Christina via Gcc-patches From: Tamar Christina Reply-To: Tamar Christina Cc: nd@arm.com, rguenther@suse.de Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi All, This adds a new test-and-branch optab that can be used to do a conditional test of a bit and branch. This is similar to the cbranch optab but instead can test any arbitrary bit inside the register. This patch recognizes boolean comparisons and single bit mask tests. Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. Ok for master? Thanks, Tamar gcc/ChangeLog: * dojump.cc (do_jump): Pass along value. (do_jump_by_parts_greater_rtx): Likewise. (do_jump_by_parts_zero_rtx): Likewise. (do_jump_by_parts_equality_rtx): Likewise. (do_compare_rtx_and_jump): Likewise. (do_compare_and_jump): Likewise. * dojump.h (do_compare_rtx_and_jump): New. * optabs.cc (emit_cmp_and_jump_insn_1): Refactor to take optab to check. (validate_test_and_branch): New. (emit_cmp_and_jump_insns): Optiobally take a value, and when value is supplied then check if it's suitable for tbranch. * optabs.def (tbranch$a4): New. * doc/md.texi (tbranch@var{mode}4): Document it. * optabs.h (emit_cmp_and_jump_insns): * tree.h (tree_zero_one_valued_p): New. --- inline copy of patch -- diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index c08691ab4c9a4bfe55ae81e5e228a414d6242d78..f8b32ec12f46d3fb3815f121a16b5a8a1819b66a 100644 --- diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index c08691ab4c9a4bfe55ae81e5e228a414d6242d78..f8b32ec12f46d3fb3815f121a16b5a8a1819b66a 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -6972,6 +6972,13 @@ case, you can and should make operand 1's predicate reject some operators in the @samp{cstore@var{mode}4} pattern, or remove the pattern altogether from the machine description. +@cindex @code{tbranch@var{mode}4} instruction pattern +@item @samp{tbranch@var{mode}4} +Conditional branch instruction combined with a bit test-and-compare +instruction. Operand 0 is a comparison operator. Operand 1 is the +operand of the comparison. Operand 2 is the bit position of Operand 1 to test. +Operand 3 is the @code{code_label} to jump to. + @cindex @code{cbranch@var{mode}4} instruction pattern @item @samp{cbranch@var{mode}4} Conditional branch instruction combined with a compare instruction. diff --git a/gcc/dojump.h b/gcc/dojump.h index e379cceb34bb1765cb575636e4c05b61501fc2cf..d1d79c490c420a805fe48d58740a79c1f25fb839 100644 --- a/gcc/dojump.h +++ b/gcc/dojump.h @@ -71,6 +71,10 @@ extern void jumpifnot (tree exp, rtx_code_label *label, extern void jumpifnot_1 (enum tree_code, tree, tree, rtx_code_label *, profile_probability); +extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int, tree, + machine_mode, rtx, rtx_code_label *, + rtx_code_label *, profile_probability); + extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int, machine_mode, rtx, rtx_code_label *, rtx_code_label *, profile_probability); diff --git a/gcc/dojump.cc b/gcc/dojump.cc index 2af0cd1aca3b6af13d5d8799094ee93f18022296..190324f36f1a31990f8c49bc8c0f45c23da5c31e 100644 --- a/gcc/dojump.cc +++ b/gcc/dojump.cc @@ -619,7 +619,7 @@ do_jump (tree exp, rtx_code_label *if_false_label, } do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)), NE, TYPE_UNSIGNED (TREE_TYPE (exp)), - GET_MODE (temp), NULL_RTX, + exp, GET_MODE (temp), NULL_RTX, if_false_label, if_true_label, prob); } @@ -687,7 +687,7 @@ do_jump_by_parts_greater_rtx (scalar_int_mode mode, int unsignedp, rtx op0, /* All but high-order word must be compared as unsigned. */ do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0), - word_mode, NULL_RTX, NULL, if_true_label, + NULL, word_mode, NULL_RTX, NULL, if_true_label, prob); /* Emit only one comparison for 0. Do not emit the last cond jump. */ @@ -695,8 +695,8 @@ do_jump_by_parts_greater_rtx (scalar_int_mode mode, int unsignedp, rtx op0, break; /* Consider lower words only if these are equal. */ - do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode, - NULL_RTX, NULL, if_false_label, + do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, NULL, + word_mode, NULL_RTX, NULL, if_false_label, prob.invert ()); } @@ -755,7 +755,7 @@ do_jump_by_parts_zero_rtx (scalar_int_mode mode, rtx op0, if (part != 0) { - do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode, + do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, NULL, word_mode, NULL_RTX, if_false_label, if_true_label, prob); return; } @@ -766,7 +766,7 @@ do_jump_by_parts_zero_rtx (scalar_int_mode mode, rtx op0, for (i = 0; i < nwords; i++) do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), - const0_rtx, EQ, 1, word_mode, NULL_RTX, + const0_rtx, EQ, 1, NULL, word_mode, NULL_RTX, if_false_label, NULL, prob); if (if_true_label) @@ -809,8 +809,8 @@ do_jump_by_parts_equality_rtx (scalar_int_mode mode, rtx op0, rtx op1, for (i = 0; i < nwords; i++) do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), - operand_subword_force (op1, i, mode), - EQ, 0, word_mode, NULL_RTX, + operand_subword_force (op1, i, mode), + EQ, 0, NULL, word_mode, NULL_RTX, if_false_label, NULL, prob); if (if_true_label) @@ -962,6 +962,23 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, rtx_code_label *if_false_label, rtx_code_label *if_true_label, profile_probability prob) +{ + do_compare_rtx_and_jump (op0, op1, code, unsignedp, NULL, mode, size, + if_false_label, if_true_label, prob); +} + +/* Like do_compare_and_jump but expects the values to compare as two rtx's. + The decision as to signed or unsigned comparison must be made by the caller. + + If MODE is BLKmode, SIZE is an RTX giving the size of the objects being + compared. */ + +void +do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, + tree val, machine_mode mode, rtx size, + rtx_code_label *if_false_label, + rtx_code_label *if_true_label, + profile_probability prob) { rtx tem; rtx_code_label *dummy_label = NULL; @@ -1177,8 +1194,10 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, } else dest_label = if_false_label; - do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, - size, dest_label, NULL, first_prob); + + do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, + val, mode, size, dest_label, NULL, + first_prob); } /* For !and_them we want to split: if (x) goto t; // prob; @@ -1192,8 +1211,9 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, else { profile_probability first_prob = prob.split (cprob); - do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, - size, NULL, if_true_label, first_prob); + do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, + val, mode, size, NULL, + if_true_label, first_prob); if (orig_code == NE && can_compare_p (UNEQ, mode, ccp_jump)) { /* x != y can be split into x unord y || x ltgt y @@ -1215,7 +1235,7 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, } } - emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, + emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, val, if_true_label, prob); } @@ -1289,9 +1309,9 @@ do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code, op1 = new_op1; } - do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, - ((mode == BLKmode) - ? expr_size (treeop0) : NULL_RTX), + do_compare_rtx_and_jump (op0, op1, code, unsignedp, treeop0, mode, + ((mode == BLKmode) + ? expr_size (treeop0) : NULL_RTX), if_false_label, if_true_label, prob); } diff --git a/gcc/optabs.cc b/gcc/optabs.cc index cff37ccb0dfc3dd79b97d0abfd872f340855dc96..5b368f77e91d3fce29870f1a5b54a0301e6b7794 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see #include "libfuncs.h" #include "internal-fn.h" #include "langhooks.h" +#include "gimple.h" static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *, machine_mode *); @@ -4620,7 +4621,7 @@ prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode, static void emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, - profile_probability prob) + direct_optab cmp_optab, profile_probability prob) { machine_mode optab_mode; enum mode_class mclass; @@ -4629,7 +4630,7 @@ emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, mclass = GET_MODE_CLASS (mode); optab_mode = (mclass == MODE_CC) ? CCmode : mode; - icode = optab_handler (cbranch_optab, optab_mode); + icode = optab_handler (cmp_optab, optab_mode); gcc_assert (icode != CODE_FOR_nothing); gcc_assert (insn_operand_matches (icode, 0, test)); @@ -4644,6 +4645,71 @@ emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, add_reg_br_prob_note (insn, prob); } +/* Check to see if the supplied comparison in PTEST can be performed as a + bit-test-and-branch instead. VAL must contain the original tree + expression of the non-zero operand which will be used to rewrite the + comparison in PTEST. + + Returns TRUE if operation succeeds and returns updated PMODE and PTEST, + else FALSE. */ + +bool +static validate_test_and_branch (tree val, rtx *ptest, machine_mode *pmode) +{ + if (!val) + return false; + + machine_mode mode = TYPE_MODE (TREE_TYPE (val)); + rtx test = *ptest; + + if (GET_CODE (test) != EQ && GET_CODE (test) != NE) + return false; + + if (tree_zero_one_valued_p (val)) + { + auto pos = BYTES_BIG_ENDIAN ? GET_MODE_BITSIZE (mode) - 1 : 0; + XEXP (test, 1) = gen_int_mode (pos, mode); + *ptest = test; + *pmode = mode; + return true; + } + + if (TREE_CODE (val) != SSA_NAME) + return false; + + gimple *def = SSA_NAME_DEF_STMT (val); + if (!is_gimple_assign (def) + || gimple_assign_rhs_code (def) != BIT_AND_EXPR) + return false; + + tree cst = gimple_assign_rhs2 (def); + + if (!tree_fits_uhwi_p (cst)) + return false; + + tree op0 = gimple_assign_rhs1 (def); + if (TREE_CODE (op0) == SSA_NAME) + { + def = SSA_NAME_DEF_STMT (op0); + if (gimple_assign_cast_p (def)) + op0 = gimple_assign_rhs1 (def); + } + + wide_int wcst = wi::uhwi (tree_to_uhwi (cst), + TYPE_PRECISION (TREE_TYPE (op0))); + int bitpos; + + if ((bitpos = wi::exact_log2 (wcst)) == -1) + return false; + + mode = TYPE_MODE (TREE_TYPE (op0)); + auto pos = BYTES_BIG_ENDIAN ? GET_MODE_BITSIZE (mode) - 1 - bitpos : bitpos; + XEXP (test, 1) = gen_int_mode (pos, mode); + *ptest = test; + *pmode = mode; + return true; +} + /* Generate code to compare X with Y so that the condition codes are set and to jump to LABEL if the condition is true. If X is a constant and Y is not a constant, then the comparison is swapped to @@ -4661,15 +4727,18 @@ emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, It will be potentially converted into an unsigned variant based on UNSIGNEDP to select a proper jump instruction. - PROB is the probability of jumping to LABEL. */ + PROB is the probability of jumping to LABEL. If the comparison is against + zero then VAL contains the expression from which the non-zero RTL is + derived. */ void emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size, - machine_mode mode, int unsignedp, rtx label, + machine_mode mode, int unsignedp, tree val, rtx label, profile_probability prob) { rtx op0 = x, op1 = y; rtx test; + enum insn_code icode; /* Swap operands and condition to ensure canonical RTL. */ if (swap_commutative_operands_p (x, y) @@ -4690,10 +4759,37 @@ emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size, prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN, &test, &mode); - emit_cmp_and_jump_insn_1 (test, mode, label, prob); + + /* Check if we're comparing a truth type with 0, and if so check if + the target supports tbranch. */ + machine_mode tmode = mode; + if (op1 == CONST0_RTX (GET_MODE (op1)) + && validate_test_and_branch (val, &test, &tmode)) + { + /* If the target supports the testbit comparison directly, great. */ + icode = direct_optab_handler (tbranch_optab, tmode); + if (icode != CODE_FOR_nothing) + { + emit_cmp_and_jump_insn_1 (test, tmode, label, tbranch_optab, prob); + return; + } + } + + emit_cmp_and_jump_insn_1 (test, mode, label, cbranch_optab, prob); } - +/* Overloaded version of emit_cmp_and_jump_insns in which VAL is unknown. */ + +void +emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size, + machine_mode mode, int unsignedp, rtx label, + profile_probability prob) +{ + emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, NULL, + label, prob); +} + + /* Emit a library call comparison between floating point X and Y. COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */ diff --git a/gcc/optabs.def b/gcc/optabs.def index 9947aed67fb8a3b675cb0aab9aeb059f89644106..623a596aca2f538a03602e02e6ac12f43f3303c4 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -220,6 +220,7 @@ OPTAB_D (reload_in_optab, "reload_in$a") OPTAB_D (reload_out_optab, "reload_out$a") OPTAB_DC(cbranch_optab, "cbranch$a4", COMPARE) +OPTAB_D (tbranch_optab, "tbranch$a4") OPTAB_D (addcc_optab, "add$acc") OPTAB_D (negcc_optab, "neg$acc") OPTAB_D (notcc_optab, "not$acc") diff --git a/gcc/optabs.h b/gcc/optabs.h index cfd7c742d2d21b0539f5227c22a94f32c793d6f7..cd55604bc3d452d7e28c5530bb4793d481766f4f 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -268,6 +268,10 @@ extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx, machine_mode, int, rtx, profile_probability prob = profile_probability::uninitialized ()); +extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx, + machine_mode, int, tree, rtx, + profile_probability prob + = profile_probability::uninitialized ()); /* Generate code to indirectly jump to a location given in the rtx LOC. */ extern void emit_indirect_jump (rtx); diff --git a/gcc/tree.h b/gcc/tree.h index 8f8a9660c9e0605eb516de194640b8c1b531b798..be3d2dee82f692e81082cf21c878c10f9fe9e1f1 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4690,6 +4690,7 @@ extern tree signed_or_unsigned_type_for (int, tree); extern tree signed_type_for (tree); extern tree unsigned_type_for (tree); extern bool is_truth_type_for (tree, tree); +extern bool tree_zero_one_valued_p (tree); extern tree truth_type_for (tree); extern tree build_pointer_type_for_mode (tree, machine_mode, bool); extern tree build_pointer_type (tree); --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -6972,6 +6972,13 @@ case, you can and should make operand 1's predicate reject some operators in the @samp{cstore@var{mode}4} pattern, or remove the pattern altogether from the machine description. +@cindex @code{tbranch@var{mode}4} instruction pattern +@item @samp{tbranch@var{mode}4} +Conditional branch instruction combined with a bit test-and-compare +instruction. Operand 0 is a comparison operator. Operand 1 is the +operand of the comparison. Operand 2 is the bit position of Operand 1 to test. +Operand 3 is the @code{code_label} to jump to. + @cindex @code{cbranch@var{mode}4} instruction pattern @item @samp{cbranch@var{mode}4} Conditional branch instruction combined with a compare instruction. diff --git a/gcc/dojump.h b/gcc/dojump.h index e379cceb34bb1765cb575636e4c05b61501fc2cf..d1d79c490c420a805fe48d58740a79c1f25fb839 100644 --- a/gcc/dojump.h +++ b/gcc/dojump.h @@ -71,6 +71,10 @@ extern void jumpifnot (tree exp, rtx_code_label *label, extern void jumpifnot_1 (enum tree_code, tree, tree, rtx_code_label *, profile_probability); +extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int, tree, + machine_mode, rtx, rtx_code_label *, + rtx_code_label *, profile_probability); + extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int, machine_mode, rtx, rtx_code_label *, rtx_code_label *, profile_probability); diff --git a/gcc/dojump.cc b/gcc/dojump.cc index 2af0cd1aca3b6af13d5d8799094ee93f18022296..190324f36f1a31990f8c49bc8c0f45c23da5c31e 100644 --- a/gcc/dojump.cc +++ b/gcc/dojump.cc @@ -619,7 +619,7 @@ do_jump (tree exp, rtx_code_label *if_false_label, } do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)), NE, TYPE_UNSIGNED (TREE_TYPE (exp)), - GET_MODE (temp), NULL_RTX, + exp, GET_MODE (temp), NULL_RTX, if_false_label, if_true_label, prob); } @@ -687,7 +687,7 @@ do_jump_by_parts_greater_rtx (scalar_int_mode mode, int unsignedp, rtx op0, /* All but high-order word must be compared as unsigned. */ do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0), - word_mode, NULL_RTX, NULL, if_true_label, + NULL, word_mode, NULL_RTX, NULL, if_true_label, prob); /* Emit only one comparison for 0. Do not emit the last cond jump. */ @@ -695,8 +695,8 @@ do_jump_by_parts_greater_rtx (scalar_int_mode mode, int unsignedp, rtx op0, break; /* Consider lower words only if these are equal. */ - do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode, - NULL_RTX, NULL, if_false_label, + do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, NULL, + word_mode, NULL_RTX, NULL, if_false_label, prob.invert ()); } @@ -755,7 +755,7 @@ do_jump_by_parts_zero_rtx (scalar_int_mode mode, rtx op0, if (part != 0) { - do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode, + do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, NULL, word_mode, NULL_RTX, if_false_label, if_true_label, prob); return; } @@ -766,7 +766,7 @@ do_jump_by_parts_zero_rtx (scalar_int_mode mode, rtx op0, for (i = 0; i < nwords; i++) do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), - const0_rtx, EQ, 1, word_mode, NULL_RTX, + const0_rtx, EQ, 1, NULL, word_mode, NULL_RTX, if_false_label, NULL, prob); if (if_true_label) @@ -809,8 +809,8 @@ do_jump_by_parts_equality_rtx (scalar_int_mode mode, rtx op0, rtx op1, for (i = 0; i < nwords; i++) do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), - operand_subword_force (op1, i, mode), - EQ, 0, word_mode, NULL_RTX, + operand_subword_force (op1, i, mode), + EQ, 0, NULL, word_mode, NULL_RTX, if_false_label, NULL, prob); if (if_true_label) @@ -962,6 +962,23 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, rtx_code_label *if_false_label, rtx_code_label *if_true_label, profile_probability prob) +{ + do_compare_rtx_and_jump (op0, op1, code, unsignedp, NULL, mode, size, + if_false_label, if_true_label, prob); +} + +/* Like do_compare_and_jump but expects the values to compare as two rtx's. + The decision as to signed or unsigned comparison must be made by the caller. + + If MODE is BLKmode, SIZE is an RTX giving the size of the objects being + compared. */ + +void +do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, + tree val, machine_mode mode, rtx size, + rtx_code_label *if_false_label, + rtx_code_label *if_true_label, + profile_probability prob) { rtx tem; rtx_code_label *dummy_label = NULL; @@ -1177,8 +1194,10 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, } else dest_label = if_false_label; - do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, - size, dest_label, NULL, first_prob); + + do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, + val, mode, size, dest_label, NULL, + first_prob); } /* For !and_them we want to split: if (x) goto t; // prob; @@ -1192,8 +1211,9 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, else { profile_probability first_prob = prob.split (cprob); - do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, - size, NULL, if_true_label, first_prob); + do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, + val, mode, size, NULL, + if_true_label, first_prob); if (orig_code == NE && can_compare_p (UNEQ, mode, ccp_jump)) { /* x != y can be split into x unord y || x ltgt y @@ -1215,7 +1235,7 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, } } - emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, + emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, val, if_true_label, prob); } @@ -1289,9 +1309,9 @@ do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code, op1 = new_op1; } - do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, - ((mode == BLKmode) - ? expr_size (treeop0) : NULL_RTX), + do_compare_rtx_and_jump (op0, op1, code, unsignedp, treeop0, mode, + ((mode == BLKmode) + ? expr_size (treeop0) : NULL_RTX), if_false_label, if_true_label, prob); } diff --git a/gcc/optabs.cc b/gcc/optabs.cc index cff37ccb0dfc3dd79b97d0abfd872f340855dc96..5b368f77e91d3fce29870f1a5b54a0301e6b7794 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see #include "libfuncs.h" #include "internal-fn.h" #include "langhooks.h" +#include "gimple.h" static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *, machine_mode *); @@ -4620,7 +4621,7 @@ prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode, static void emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, - profile_probability prob) + direct_optab cmp_optab, profile_probability prob) { machine_mode optab_mode; enum mode_class mclass; @@ -4629,7 +4630,7 @@ emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, mclass = GET_MODE_CLASS (mode); optab_mode = (mclass == MODE_CC) ? CCmode : mode; - icode = optab_handler (cbranch_optab, optab_mode); + icode = optab_handler (cmp_optab, optab_mode); gcc_assert (icode != CODE_FOR_nothing); gcc_assert (insn_operand_matches (icode, 0, test)); @@ -4644,6 +4645,71 @@ emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, add_reg_br_prob_note (insn, prob); } +/* Check to see if the supplied comparison in PTEST can be performed as a + bit-test-and-branch instead. VAL must contain the original tree + expression of the non-zero operand which will be used to rewrite the + comparison in PTEST. + + Returns TRUE if operation succeeds and returns updated PMODE and PTEST, + else FALSE. */ + +bool +static validate_test_and_branch (tree val, rtx *ptest, machine_mode *pmode) +{ + if (!val) + return false; + + machine_mode mode = TYPE_MODE (TREE_TYPE (val)); + rtx test = *ptest; + + if (GET_CODE (test) != EQ && GET_CODE (test) != NE) + return false; + + if (tree_zero_one_valued_p (val)) + { + auto pos = BYTES_BIG_ENDIAN ? GET_MODE_BITSIZE (mode) - 1 : 0; + XEXP (test, 1) = gen_int_mode (pos, mode); + *ptest = test; + *pmode = mode; + return true; + } + + if (TREE_CODE (val) != SSA_NAME) + return false; + + gimple *def = SSA_NAME_DEF_STMT (val); + if (!is_gimple_assign (def) + || gimple_assign_rhs_code (def) != BIT_AND_EXPR) + return false; + + tree cst = gimple_assign_rhs2 (def); + + if (!tree_fits_uhwi_p (cst)) + return false; + + tree op0 = gimple_assign_rhs1 (def); + if (TREE_CODE (op0) == SSA_NAME) + { + def = SSA_NAME_DEF_STMT (op0); + if (gimple_assign_cast_p (def)) + op0 = gimple_assign_rhs1 (def); + } + + wide_int wcst = wi::uhwi (tree_to_uhwi (cst), + TYPE_PRECISION (TREE_TYPE (op0))); + int bitpos; + + if ((bitpos = wi::exact_log2 (wcst)) == -1) + return false; + + mode = TYPE_MODE (TREE_TYPE (op0)); + auto pos = BYTES_BIG_ENDIAN ? GET_MODE_BITSIZE (mode) - 1 - bitpos : bitpos; + XEXP (test, 1) = gen_int_mode (pos, mode); + *ptest = test; + *pmode = mode; + return true; +} + /* Generate code to compare X with Y so that the condition codes are set and to jump to LABEL if the condition is true. If X is a constant and Y is not a constant, then the comparison is swapped to @@ -4661,15 +4727,18 @@ emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, It will be potentially converted into an unsigned variant based on UNSIGNEDP to select a proper jump instruction. - PROB is the probability of jumping to LABEL. */ + PROB is the probability of jumping to LABEL. If the comparison is against + zero then VAL contains the expression from which the non-zero RTL is + derived. */ void emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size, - machine_mode mode, int unsignedp, rtx label, + machine_mode mode, int unsignedp, tree val, rtx label, profile_probability prob) { rtx op0 = x, op1 = y; rtx test; + enum insn_code icode; /* Swap operands and condition to ensure canonical RTL. */ if (swap_commutative_operands_p (x, y) @@ -4690,10 +4759,37 @@ emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size, prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN, &test, &mode); - emit_cmp_and_jump_insn_1 (test, mode, label, prob); + + /* Check if we're comparing a truth type with 0, and if so check if + the target supports tbranch. */ + machine_mode tmode = mode; + if (op1 == CONST0_RTX (GET_MODE (op1)) + && validate_test_and_branch (val, &test, &tmode)) + { + /* If the target supports the testbit comparison directly, great. */ + icode = direct_optab_handler (tbranch_optab, tmode); + if (icode != CODE_FOR_nothing) + { + emit_cmp_and_jump_insn_1 (test, tmode, label, tbranch_optab, prob); + return; + } + } + + emit_cmp_and_jump_insn_1 (test, mode, label, cbranch_optab, prob); } - +/* Overloaded version of emit_cmp_and_jump_insns in which VAL is unknown. */ + +void +emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size, + machine_mode mode, int unsignedp, rtx label, + profile_probability prob) +{ + emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, NULL, + label, prob); +} + + /* Emit a library call comparison between floating point X and Y. COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */ diff --git a/gcc/optabs.def b/gcc/optabs.def index 9947aed67fb8a3b675cb0aab9aeb059f89644106..623a596aca2f538a03602e02e6ac12f43f3303c4 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -220,6 +220,7 @@ OPTAB_D (reload_in_optab, "reload_in$a") OPTAB_D (reload_out_optab, "reload_out$a") OPTAB_DC(cbranch_optab, "cbranch$a4", COMPARE) +OPTAB_D (tbranch_optab, "tbranch$a4") OPTAB_D (addcc_optab, "add$acc") OPTAB_D (negcc_optab, "neg$acc") OPTAB_D (notcc_optab, "not$acc") diff --git a/gcc/optabs.h b/gcc/optabs.h index cfd7c742d2d21b0539f5227c22a94f32c793d6f7..cd55604bc3d452d7e28c5530bb4793d481766f4f 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -268,6 +268,10 @@ extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx, machine_mode, int, rtx, profile_probability prob = profile_probability::uninitialized ()); +extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx, + machine_mode, int, tree, rtx, + profile_probability prob + = profile_probability::uninitialized ()); /* Generate code to indirectly jump to a location given in the rtx LOC. */ extern void emit_indirect_jump (rtx); diff --git a/gcc/tree.h b/gcc/tree.h index 8f8a9660c9e0605eb516de194640b8c1b531b798..be3d2dee82f692e81082cf21c878c10f9fe9e1f1 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4690,6 +4690,7 @@ extern tree signed_or_unsigned_type_for (int, tree); extern tree signed_type_for (tree); extern tree unsigned_type_for (tree); extern bool is_truth_type_for (tree, tree); +extern bool tree_zero_one_valued_p (tree); extern tree truth_type_for (tree); extern tree build_pointer_type_for_mode (tree, machine_mode, bool); extern tree build_pointer_type (tree); From patchwork Mon Oct 31 11:53:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tamar Christina X-Patchwork-Id: 59644 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0E7F0385DC3E for ; Mon, 31 Oct 2022 11:54:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0E7F0385DC3E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1667217284; bh=px7DWlP4lFxjsJUapUuDRaS/gqWnBj/e08G5I7+4+uA=; h=Date:To:Subject:In-Reply-To:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=EF60pkpVmk4tvudQm66IApQ6xmU9kJvSo2xcEMOLUD3scD8bGzMEGJE1BSfWC4mr6 1ojgGCGtriu/0CHN9eOuoEhjVC7FCaMA7UdBBlSUSvTAS5K84k0WRq0Cu1XD2GUuVF ZKwap9Hg0Lf96dQLIXNdAZKFGG7WLtO1FUEPkj3w= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2064.outbound.protection.outlook.com [40.107.20.64]) by sourceware.org (Postfix) with ESMTPS id D6906385416D for ; Mon, 31 Oct 2022 11:54:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D6906385416D ARC-Seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=DbNTn0wbIryp95MPdiyViKgikK9Chtr9DtEq1wWi7GXt3z8e9MXWUNHxVoIILoEr202/Kaoh1U2+nxC2xyIBXKgPSOnG5KKoIFObMjWfNMBKSQcQ9LX0hIY6tp7a6+DeOJIyPKUOfpJX1D5V5/FIzgG2/goBLolmmzkn9tyIk583lG5BVG8jpRY+a0BzIXAKB5+u+2lklSX6jShubxOGJZGynuXO5EH39gAR9eWrqcePPFxooZZacDAnvhnywJ3IUK+OOdsMf+UzUY7iTE4zFjBVlojjkXJ+zYZVlMGv+zZKoegP0sHfx0rqhaYDKRM10VRnd7fJ4uE0cP6UoblcSA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=px7DWlP4lFxjsJUapUuDRaS/gqWnBj/e08G5I7+4+uA=; b=DAAqk+sOTDJyRzysHifkEgmA5DgBInhARC+IAic8U4vNPom9fXQ7cTwO5dCWVR9YLSxhtDAFWFynAUP7xsrt2fVer4mqu0tiuGvYczhBdCOMowZ83WcPs1JH27os1866k50gkg6bMa3FZMcUZYib3w9CGNm4OX6iP0LWVcN9RKLeKragptUVVZqE9mHm/z5FFsbAWTeImpfYpYXClYPH0/KV3ysifW9FliYTRyCXP0vCoJc3fcEKJcX53deG2leNguMVi30zgDfTdi1vphoekHYa/P6tqur1dYQDPjWe0jmw5/MBZMGZuNLG51IYARM/7wZ19l06P2ccWZzKNCLd1g== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 63.35.35.123) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com]) Received: from AM5PR0601CA0082.eurprd06.prod.outlook.com (2603:10a6:206::47) by GV2PR08MB7954.eurprd08.prod.outlook.com (2603:10a6:150:a8::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5746.28; Mon, 31 Oct 2022 11:54:07 +0000 Received: from AM7EUR03FT032.eop-EUR03.prod.protection.outlook.com (2603:10a6:206:0:cafe::1) by AM5PR0601CA0082.outlook.office365.com (2603:10a6:206::47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5709.15 via Frontend Transport; Mon, 31 Oct 2022 11:54:07 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by AM7EUR03FT032.mail.protection.outlook.com (100.127.140.65) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5769.14 via Frontend Transport; Mon, 31 Oct 2022 11:54:06 +0000 Received: ("Tessian outbound b4aebcc5bc64:v130"); Mon, 31 Oct 2022 11:54:06 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 9fb6ac0ad0eaddd8 X-CR-MTA-TID: 64aa7808 Received: from acf62bf6dec9.2 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 4F8AC3DB-83CE-4B44-9033-38735994AAF9.1; Mon, 31 Oct 2022 11:53:56 +0000 Received: from EUR04-HE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id acf62bf6dec9.2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Mon, 31 Oct 2022 11:53:56 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=M97ty4Jxh0eagAB6mtWkYXeIm57Gt1DSkBbTUPjwHDW/I1E7hF608Erh4ERP7LV2wopMuW14ocJrSNlHLrMjDhN+5Ns5azGCRhShG6BMkF8GIGcDHCltt7/m1w3nKEgncGO5K10xWEh6bV82WNe1ZZ7JuGB5BwnIyeg92wd4R6u4Dh6HJsQy5MIIZFaJ+hgLOvhASvDseW1chlGGVB+tsau0Hb34a/kfLfJyn7tqhtwlQ7DUT1uNPKNmpoz1O+UQXKMuYG2Jb0N/2QvMdPG1FHw0qDsmkRGbgDDF21F4W3AKDNJLX6vSlbYuADpKzMNJ8WW2slLrc7P0BcAdUDNLlw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=px7DWlP4lFxjsJUapUuDRaS/gqWnBj/e08G5I7+4+uA=; b=CnHsHMrgt6Hc160mk8Jh2Qa/nx6lE2TWVEZUUXUz530M7wYQAJ1RxO87TnBsBCu5JKXpvPE87pODrefxnqpfFEElg+q0v4/oZtnl62I2IXajacSr7eHbSbcrJpyBDm1FDdsI4k7ECR5ykNcNAUZk0oh/aA0gTiU2dwr7Kq21bqG4g1t4LcTWpwI+McEZahJwo2mRe/Bk3eU4ionb//j4d8Tc2Npuatwmny/VZZs9wNwztj3ix9gfnsPNDmthTMqSFd04Bx5ChaYvZ0FDvdNcgwHoKRByPwRhFfkh/6xFhSAHf7NCUPxxNR9MfThP7BuZJRzRIwuT7/93G7JVdXF4fg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) by GV2PR08MB8319.eurprd08.prod.outlook.com (2603:10a6:150:b5::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5769.19; Mon, 31 Oct 2022 11:53:53 +0000 Received: from VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::c57d:50c2:3502:a52]) by VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::c57d:50c2:3502:a52%4]) with mapi id 15.20.5769.019; Mon, 31 Oct 2022 11:53:52 +0000 Date: Mon, 31 Oct 2022 11:53:50 +0000 To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/2]AArch64 Support new tbranch optab. Message-ID: Content-Disposition: inline In-Reply-To: X-ClientProxiedBy: LO2P265CA0308.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:a5::32) To VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: VI1PR08MB5325:EE_|GV2PR08MB8319:EE_|AM7EUR03FT032:EE_|GV2PR08MB7954:EE_ X-MS-Office365-Filtering-Correlation-Id: 497d76f4-466b-48c1-b2fd-08dabb369d78 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: 8AKlRYlDoWsyZndR3iDh5BpcLCGkjkHabvfh0j/mSqyWweWnqwsWdsSxBY67eh9ycXmJnRBHaIIUBoJ+Y8Og9nx+ORa8ysYAzC4Ct6DQFJuMVmTPYIenR66WvilD/t2+uvenrtWYnC0jvhFGCLr6AjlWwKm8kkpaMrcPpCBu551lH3xX9n7cJOF7NtmjUoKE4WGcWu9lgX+3aUUxWsYLbeUlTZBegvLLAchr0IflfvseawvXcw1EwkUha5IV7QWVv9AE/PuKWAu9vswbITlIOD0k0SQr3R15juw1NBVO1t5DjTRD/TMog1MJEC1z/JZqNW8vg+oPJswQPF6ZLqPcN95e8ICuahvCH3GzPGzePTXku7lSDzeJSkUYimNEGyspks1bQD8vRP+6elqNGptQL24zXIdFSh04gqptzI19mnNBRVb+833EU3JJHgf9eqP558ITXwJDn8HZo2faoltZaAMlRYsm2PNyvxk/Wc+UjhhGh3jcsOJCK8iXoBVd/l8QG6Q+hAQA0HWCJKitr2Q7Hv5awpUkOUmSI+IyP5GCGB7nuZxj0MDt73vN7asuGGdXKG6zcC9oId4YS4ZB/YgWcUf59f2WEbyTFru/kcBWDC7DGUiSocYLyTddikV9nd5c8fTWwzCnF/Mjlvq1+QhINVX86Ck17mqda4aucdwSq0SnpT94pmdGCo1vU5NJIe7W9ybE/FVulhXt4GY/+6W64XZUlvfkFPRk4K7dPEvVqGYGrcNT3tJOJYuH0Jrt1Jerf3FTU4GHak5UXqb3M06V1AGBwCeQQk9aFXv1MmHMvXlZZjhaGOzCbxxcyu8IuKCC/fG0Mmw3Za/mKoT+svuY1Q== X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR08MB5325.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230022)(4636009)(366004)(396003)(136003)(346002)(376002)(39860400002)(451199015)(6512007)(26005)(33964004)(6506007)(44144004)(6486002)(36756003)(478600001)(6916009)(316002)(38100700002)(86362001)(2616005)(186003)(83380400001)(4743002)(66556008)(66476007)(41300700001)(235185007)(8676002)(66946007)(2906002)(5660300002)(4326008)(8936002)(84970400001)(44832011)(2700100001)(67856001); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV2PR08MB8319 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM7EUR03FT032.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 6a2273f7-5820-4bcd-2393-08dabb3694da X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: h0/DYisR9JYMu23VAlKOEHQvglM7HusAOoQS7rtTJxN6InRQNYj+1MHGdyavjcbFgqRqjojYV1TOokHHsMbE6YP8rojgV68BEDlJqWxnenOiustkz3t1qwRaaU8WhFL3sgiA6kc+WRSNg4tZ/Vdr99vexWc93z4W89pPn0XtvVB6sO91iOJOrN6kvAfXNDSOKSBuidAYB2n+jQHERwZyajjAicMs6nnBrernkFgRZ199KPYW03+9Vnkpql3ZlqOWZxPg9NEVOBBN8pLMRYLfnODs3jbl8JZzh2lfzpZjsOOcMEiyGLHLwIOLKICiVyrNmh6qbkzcJmJ6RwKj2OTGSaPx4VsDzKkRFNmLi+hkbtKU5qLL2ma95iZjezJCR1726Mc5sjVFWyS7pa4KCLpJmZLZJOhB5atz6x5XscdidDRVOtnXktHAXrlPTDZ7i4Pa696c+a3APdmhIGx0VWfZvo3oKNO+v4FjbQB7NuTRFgPb4cxBeZzFdU1MIZoZI5SiYpLEHxT+c0pl74L2rty/bDrKPaJUVEw2UQWyNqjMDgQR9TpXIxm7ERqPjG3j4/g4Yfgwt5PIC5WoKUdG0tvi36/sunbFnnf+bbrrbFbGi+9r20UIQQlfL5qyIzseZ9ni2Vj9P+THm+JmpZt+ug86oxm0cLm2QA/O1c1Vz15wxzOvbx4009odxTsoX7B94z4/C+NrYA/zRDSbVvR6cNmK3o2BxorpZXOvsF29mvjJKystXoityMNGxOtHYwhVFVdeyhgJ8veXQdPLKharQ1BvFEftB0/ozO0LMIu+B8zC0EQKmxPJ1fK9fYzHG6Xux+ipqoUK2BbYYVtFTZP30G6QZlyp89yBbgq2ZEsdKQc5rMg= X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFS:(13230022)(4636009)(396003)(39860400002)(346002)(376002)(136003)(451199015)(36840700001)(40470700004)(46966006)(4326008)(8676002)(44832011)(2906002)(6916009)(82740400003)(2616005)(47076005)(70206006)(36756003)(70586007)(83380400001)(8936002)(5660300002)(235185007)(81166007)(316002)(336012)(36860700001)(40460700003)(186003)(41300700001)(356005)(26005)(4743002)(86362001)(478600001)(6506007)(6486002)(40480700001)(33964004)(44144004)(6512007)(82310400005)(84970400001)(2700100001)(67856001); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 Oct 2022 11:54:06.9970 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 497d76f4-466b-48c1-b2fd-08dabb369d78 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: AM7EUR03FT032.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV2PR08MB7954 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_NONE, KAM_LOTSOFHASH, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_NONE, TXREP, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tamar Christina via Gcc-patches From: Tamar Christina Reply-To: Tamar Christina Cc: Richard.Earnshaw@arm.com, nd@arm.com, richard.sandiford@arm.com, Marcus.Shawcroft@arm.com Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi All, This implements the new tbranch optab for AArch64. Instead of emitting the instruction directly I've chosen to expand the pattern using a zero extract and generating the existing pattern for comparisons for two reasons: 1. Allows for CSE of the actual comparison. 2. It looks like the code in expand makes the label as unused and removed it if it doesn't see a separate reference to it. Because of this expansion though I disable the pattern at -O0 since we have no combine in that case so we'd end up with worse code. I did try emitting the pattern directly, but as mentioned in no#2 expand would then kill the label. While doing this I noticed that the version that checks the signbit doesn't work The reason for this looks like an incorrect pattern. The [us]fbx instructions are defined for index + size == regiter size. They architecturally alias to different instructions and binutils handles this correctly. In GCC however we tried to prematurely optimize this and added a separate split pattern. But this pattern is also missing alternatives only handling DImode. This just removes this and relaxes the constraints on the normal bfx pattern. Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. Ok for master? Thanks, Tamar gcc/ChangeLog: * config/aarch64/aarch64.md (*tb1): Rename to... (*tb1): ... this. (tbranch4): New. (*): Rename to... (*): ... this. gcc/testsuite/ChangeLog: * gcc.target/aarch64/tbz_1.c: New test. --- inline copy of patch -- diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 2bc2684b82c35a44e0a2cea6e3aaf32d939f8cdf..6a4494a9a370139313cc8e57447717aafa14da2d 100644 --- diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 2bc2684b82c35a44e0a2cea6e3aaf32d939f8cdf..6a4494a9a370139313cc8e57447717aafa14da2d 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -943,12 +943,28 @@ (define_insn "*cb1" (const_int 1)))] ) -(define_insn "*tb1" +(define_expand "tbranch4" [(set (pc) (if_then_else - (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r") - (const_int 1) - (match_operand 1 - "aarch64_simd_shift_imm_" "n")) + (match_operator 0 "aarch64_comparison_operator" + [(match_operand:ALLI 1 "register_operand") + (match_operand:ALLI 2 "aarch64_simd_shift_imm_")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "optimize > 0" +{ + rtx bitvalue = gen_reg_rtx (DImode); + emit_insn (gen_extzv (bitvalue, operands[1], const1_rtx, operands[2])); + operands[2] = const0_rtx; + operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), bitvalue, + operands[2]); +}) + +(define_insn "*tb1" + [(set (pc) (if_then_else + (EQL (zero_extract:GPI (match_operand:ALLI 0 "register_operand" "r") + (const_int 1) + (match_operand 1 + "aarch64_simd_shift_imm_" "n")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc))) @@ -959,15 +975,15 @@ (define_insn "*tb1" { if (get_attr_far_branch (insn) == 1) return aarch64_gen_far_branch (operands, 2, "Ltb", - "\\t%0, %1, "); + "\\t%0, %1, "); else { operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1])); - return "tst\t%0, %1\;\t%l2"; + return "tst\t%0, %1\;\t%l2"; } } else - return "\t%0, %1, %l2"; + return "\t%0, %1, %l2"; } [(set_attr "type" "branch") (set (attr "length") @@ -5752,39 +5768,19 @@ (define_expand "" ) -(define_insn "*" +(define_insn "*" [(set (match_operand:GPI 0 "register_operand" "=r") - (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r") + (ANY_EXTRACT:GPI (match_operand:ALLI 1 "register_operand" "r") (match_operand 2 - "aarch64_simd_shift_imm_offset_" "n") + "aarch64_simd_shift_imm_offset_" "n") (match_operand 3 - "aarch64_simd_shift_imm_" "n")))] + "aarch64_simd_shift_imm_" "n")))] "IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]), - 1, GET_MODE_BITSIZE (mode) - 1)" - "bfx\\t%0, %1, %3, %2" + 1, GET_MODE_BITSIZE (mode))" + "bfx\\t%0, %1, %3, %2" [(set_attr "type" "bfx")] ) -;; When the bit position and width add up to 32 we can use a W-reg LSR -;; instruction taking advantage of the implicit zero-extension of the X-reg. -(define_split - [(set (match_operand:DI 0 "register_operand") - (zero_extract:DI (match_operand:DI 1 "register_operand") - (match_operand 2 - "aarch64_simd_shift_imm_offset_di") - (match_operand 3 - "aarch64_simd_shift_imm_di")))] - "IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]), 1, - GET_MODE_BITSIZE (DImode) - 1) - && (INTVAL (operands[2]) + INTVAL (operands[3])) - == GET_MODE_BITSIZE (SImode)" - [(set (match_dup 0) - (zero_extend:DI (lshiftrt:SI (match_dup 4) (match_dup 3))))] - { - operands[4] = gen_lowpart (SImode, operands[1]); - } -) - ;; Bitfield Insert (insv) (define_expand "insv" [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand") diff --git a/gcc/testsuite/gcc.target/aarch64/tbz_1.c b/gcc/testsuite/gcc.target/aarch64/tbz_1.c new file mode 100644 index 0000000000000000000000000000000000000000..86f5d3e23cf7f1ea6f3596549ce1a0cff6774463 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tbz_1.c @@ -0,0 +1,95 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O2 -std=c99 -fno-unwind-tables -fno-asynchronous-unwind-tables" } */ +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ + +#include + +void h(void); + +/* +** g1: +** tbnz x[0-9]+, #?0, .L([0-9]+) +** ret +** ... +*/ +void g1(bool x) +{ + if (__builtin_expect (x, 0)) + h (); +} + +/* +** g2: +** tbz x[0-9]+, #?0, .L([0-9]+) +** b h +** ... +*/ +void g2(bool x) +{ + if (__builtin_expect (x, 1)) + h (); +} + +/* +** g3_ge: +** tbnz w[0-9]+, #?31, .L[0-9]+ +** b h +** ... +*/ +void g3_ge(int x) +{ + if (__builtin_expect (x >= 0, 1)) + h (); +} + +/* +** g3_gt: +** cmp w[0-9]+, 0 +** ble .L[0-9]+ +** b h +** ... +*/ +void g3_gt(int x) +{ + if (__builtin_expect (x > 0, 1)) + h (); +} + +/* +** g3_lt: +** tbz w[0-9]+, #?31, .L[0-9]+ +** b h +** ... +*/ +void g3_lt(int x) +{ + if (__builtin_expect (x < 0, 1)) + h (); +} + +/* +** g3_le: +** cmp w[0-9]+, 0 +** bgt .L[0-9]+ +** b h +** ... +*/ +void g3_le(int x) +{ + if (__builtin_expect (x <= 0, 1)) + h (); +} + +/* +** g5: +** mov w[0-9]+, 65279 +** tst w[0-9]+, w[0-9]+ +** beq .L[0-9]+ +** b h +** ... +*/ +void g5(int x) +{ + if (__builtin_expect (x & 0xfeff, 1)) + h (); +} --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -943,12 +943,28 @@ (define_insn "*cb1" (const_int 1)))] ) -(define_insn "*tb1" +(define_expand "tbranch4" [(set (pc) (if_then_else - (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r") - (const_int 1) - (match_operand 1 - "aarch64_simd_shift_imm_" "n")) + (match_operator 0 "aarch64_comparison_operator" + [(match_operand:ALLI 1 "register_operand") + (match_operand:ALLI 2 "aarch64_simd_shift_imm_")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "optimize > 0" +{ + rtx bitvalue = gen_reg_rtx (DImode); + emit_insn (gen_extzv (bitvalue, operands[1], const1_rtx, operands[2])); + operands[2] = const0_rtx; + operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), bitvalue, + operands[2]); +}) + +(define_insn "*tb1" + [(set (pc) (if_then_else + (EQL (zero_extract:GPI (match_operand:ALLI 0 "register_operand" "r") + (const_int 1) + (match_operand 1 + "aarch64_simd_shift_imm_" "n")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc))) @@ -959,15 +975,15 @@ (define_insn "*tb1" { if (get_attr_far_branch (insn) == 1) return aarch64_gen_far_branch (operands, 2, "Ltb", - "\\t%0, %1, "); + "\\t%0, %1, "); else { operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1])); - return "tst\t%0, %1\;\t%l2"; + return "tst\t%0, %1\;\t%l2"; } } else - return "\t%0, %1, %l2"; + return "\t%0, %1, %l2"; } [(set_attr "type" "branch") (set (attr "length") @@ -5752,39 +5768,19 @@ (define_expand "" ) -(define_insn "*" +(define_insn "*" [(set (match_operand:GPI 0 "register_operand" "=r") - (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r") + (ANY_EXTRACT:GPI (match_operand:ALLI 1 "register_operand" "r") (match_operand 2 - "aarch64_simd_shift_imm_offset_" "n") + "aarch64_simd_shift_imm_offset_" "n") (match_operand 3 - "aarch64_simd_shift_imm_" "n")))] + "aarch64_simd_shift_imm_" "n")))] "IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]), - 1, GET_MODE_BITSIZE (mode) - 1)" - "bfx\\t%0, %1, %3, %2" + 1, GET_MODE_BITSIZE (mode))" + "bfx\\t%0, %1, %3, %2" [(set_attr "type" "bfx")] ) -;; When the bit position and width add up to 32 we can use a W-reg LSR -;; instruction taking advantage of the implicit zero-extension of the X-reg. -(define_split - [(set (match_operand:DI 0 "register_operand") - (zero_extract:DI (match_operand:DI 1 "register_operand") - (match_operand 2 - "aarch64_simd_shift_imm_offset_di") - (match_operand 3 - "aarch64_simd_shift_imm_di")))] - "IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]), 1, - GET_MODE_BITSIZE (DImode) - 1) - && (INTVAL (operands[2]) + INTVAL (operands[3])) - == GET_MODE_BITSIZE (SImode)" - [(set (match_dup 0) - (zero_extend:DI (lshiftrt:SI (match_dup 4) (match_dup 3))))] - { - operands[4] = gen_lowpart (SImode, operands[1]); - } -) - ;; Bitfield Insert (insv) (define_expand "insv" [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand") diff --git a/gcc/testsuite/gcc.target/aarch64/tbz_1.c b/gcc/testsuite/gcc.target/aarch64/tbz_1.c new file mode 100644 index 0000000000000000000000000000000000000000..86f5d3e23cf7f1ea6f3596549ce1a0cff6774463 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tbz_1.c @@ -0,0 +1,95 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O2 -std=c99 -fno-unwind-tables -fno-asynchronous-unwind-tables" } */ +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ + +#include + +void h(void); + +/* +** g1: +** tbnz x[0-9]+, #?0, .L([0-9]+) +** ret +** ... +*/ +void g1(bool x) +{ + if (__builtin_expect (x, 0)) + h (); +} + +/* +** g2: +** tbz x[0-9]+, #?0, .L([0-9]+) +** b h +** ... +*/ +void g2(bool x) +{ + if (__builtin_expect (x, 1)) + h (); +} + +/* +** g3_ge: +** tbnz w[0-9]+, #?31, .L[0-9]+ +** b h +** ... +*/ +void g3_ge(int x) +{ + if (__builtin_expect (x >= 0, 1)) + h (); +} + +/* +** g3_gt: +** cmp w[0-9]+, 0 +** ble .L[0-9]+ +** b h +** ... +*/ +void g3_gt(int x) +{ + if (__builtin_expect (x > 0, 1)) + h (); +} + +/* +** g3_lt: +** tbz w[0-9]+, #?31, .L[0-9]+ +** b h +** ... +*/ +void g3_lt(int x) +{ + if (__builtin_expect (x < 0, 1)) + h (); +} + +/* +** g3_le: +** cmp w[0-9]+, 0 +** bgt .L[0-9]+ +** b h +** ... +*/ +void g3_le(int x) +{ + if (__builtin_expect (x <= 0, 1)) + h (); +} + +/* +** g5: +** mov w[0-9]+, 65279 +** tst w[0-9]+, w[0-9]+ +** beq .L[0-9]+ +** b h +** ... +*/ +void g5(int x) +{ + if (__builtin_expect (x & 0xfeff, 1)) + h (); +}