From patchwork Fri Aug 21 16:55:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Sayle X-Patchwork-Id: 1349421 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nextmovesoftware.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nextmovesoftware.com header.i=@nextmovesoftware.com header.a=rsa-sha256 header.s=default header.b=X9o9MZ+S; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BY71j0dphz9sPB for ; Sat, 22 Aug 2020 02:55:37 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6A0793857026; Fri, 21 Aug 2020 16:55:34 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from server.nextmovesoftware.com (server.nextmovesoftware.com [162.254.253.69]) by sourceware.org (Postfix) with ESMTPS id 577B03857C47 for ; Fri, 21 Aug 2020 16:55:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 577B03857C47 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=nextmovesoftware.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=roger@nextmovesoftware.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nextmovesoftware.com; s=default; h=Content-Type:MIME-Version:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=5nW84K5+ejEZHOJX4c2CCSXCWbPv5w9h9pLDbp9kJV8=; b=X9o9MZ+SKwMCIeXRZZs57mBBIu QHJBwhh/B5nu2x1gKiblpBPvlkWAKUBg4lWrc8TmhQJopD+UdSpdVng2cxha9ycCMBkmkZUYESYwW lxao5Ft3w7LDWqkgdiQBqCs2jvbUHaWPhnS1Apbr2Ac1shzyacNWagmTtrRyhj/qM8BJilTIgwOxA omqeYQZlJbtgpzwvk53PouN0H7bNvUsRAvZJzHQeU00ngSzumK8QL097TPjGcKVWVWIdwLjlYYyKv VCnu8GQDwmRxtByRt0Czw1XtrwMWNZEAqdSwooWD2TInBZ2Qihz08do/wmayno2IKHKhBfDWxOBCx Efly/RGA==; Received: from [185.62.158.67] (port=60674 helo=Dell) by server.nextmovesoftware.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1k9AKA-00029l-MH for gcc-patches@gcc.gnu.org; Fri, 21 Aug 2020 12:55:30 -0400 From: "Roger Sayle" To: "'GCC Patches'" Subject: [PATCH] middle-end: PR tree-optimization/21137: STRIP_NOPS avoids missed optimization. Date: Fri, 21 Aug 2020 17:55:29 +0100 Message-ID: <001201d677db$e0869d70$a193d850$@nextmovesoftware.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AdZ3244EgiKmpprbRNOTzb5b935n8Q== Content-Language: en-gb X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server.nextmovesoftware.com X-AntiAbuse: Original Domain - gcc.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - nextmovesoftware.com X-Get-Message-Sender-Via: server.nextmovesoftware.com: authenticated_id: roger@nextmovesoftware.com X-Authenticated-Sender: server.nextmovesoftware.com: roger@nextmovesoftware.com X-Source: X-Source-Args: X-Source-Dir: X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" PR tree-optimization/21137 is now an old enhancement request pointing out that an optimization I added back in 2006, to optimize "((x>>31)&64) != 0" as "x < 0", doesn't fire in the presence of unanticipated type conversions. The fix is to call STRIP_NOPS at the appropriate point. I'd considered moving this transformation to match.pd, but it's a lot of complex logic that (I suspect) would be just as ugly in match.pd as it is in fold-const.c. This patch has been tested on x86_64-pc-linux-gnu with a "make bootstrap" and "make -k check" with no new failures. Ok for mainline? 2020-08-21 Roger Sayle gcc/ChangeLog PR tree-optimization/21137 * gcc/fold-const.c (fold_binary_loc) [NE_EXPR/EQ_EXPR]: Call STRIP_NOPS when checking whether to simplify ((x>>C1)&C2) != 0. gcc/testsuite/ChangeLog PR tree-optimization/21137 * gcc.dg/pr21137.c: New test. Thanks in advance, Roger --- Roger Sayle NextMove Software Cambridge, UK diff --git a/gcc/testsuite/gcc.dg/pr21137.c b/gcc/testsuite/gcc.dg/pr21137.c new file mode 100644 index 0000000..6d73dea --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr21137.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +void foo(); + +void test5_1(int e) +{ + if ((e >> 31) & 64) + foo(); +} + +typedef int myint; + +void test5_2(myint e) +{ + if ((e >> 31) & 64) + foo(); +} + +/* { dg-final { scan-tree-dump-times " < 0" 2 "optimized" } } */ diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 9fc4c2a..efe77e7 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -11596,45 +11596,53 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type, C1 is a valid shift constant, and C2 is a power of two, i.e. a single bit. */ if (TREE_CODE (arg0) == BIT_AND_EXPR - && TREE_CODE (TREE_OPERAND (arg0, 0)) == RSHIFT_EXPR - && TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)) - == INTEGER_CST && integer_pow2p (TREE_OPERAND (arg0, 1)) && integer_zerop (arg1)) { - tree itype = TREE_TYPE (arg0); - tree arg001 = TREE_OPERAND (TREE_OPERAND (arg0, 0), 1); - prec = TYPE_PRECISION (itype); - - /* Check for a valid shift count. */ - if (wi::ltu_p (wi::to_wide (arg001), prec)) + tree arg00 = TREE_OPERAND (arg0, 0); + STRIP_NOPS (arg00); + if (TREE_CODE (arg00) == RSHIFT_EXPR + && TREE_CODE (TREE_OPERAND (arg00, 1)) == INTEGER_CST) { - tree arg01 = TREE_OPERAND (arg0, 1); - tree arg000 = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0); - unsigned HOST_WIDE_INT log2 = tree_log2 (arg01); - /* If (C2 << C1) doesn't overflow, then ((X >> C1) & C2) != 0 - can be rewritten as (X & (C2 << C1)) != 0. */ - if ((log2 + TREE_INT_CST_LOW (arg001)) < prec) + tree itype = TREE_TYPE (arg00); + tree arg001 = TREE_OPERAND (arg00, 1); + prec = TYPE_PRECISION (itype); + + /* Check for a valid shift count. */ + if (wi::ltu_p (wi::to_wide (arg001), prec)) { - tem = fold_build2_loc (loc, LSHIFT_EXPR, itype, arg01, arg001); - tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, arg000, tem); - return fold_build2_loc (loc, code, type, tem, - fold_convert_loc (loc, itype, arg1)); - } - /* Otherwise, for signed (arithmetic) shifts, - ((X >> C1) & C2) != 0 is rewritten as X < 0, and - ((X >> C1) & C2) == 0 is rewritten as X >= 0. */ - else if (!TYPE_UNSIGNED (itype)) - return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR, type, - arg000, build_int_cst (itype, 0)); - /* Otherwise, of unsigned (logical) shifts, - ((X >> C1) & C2) != 0 is rewritten as (X,false), and - ((X >> C1) & C2) == 0 is rewritten as (X,true). */ - else - return omit_one_operand_loc (loc, type, + tree arg01 = TREE_OPERAND (arg0, 1); + tree arg000 = TREE_OPERAND (arg00, 0); + unsigned HOST_WIDE_INT log2 = tree_log2 (arg01); + /* If (C2 << C1) doesn't overflow, then + ((X >> C1) & C2) != 0 can be rewritten as + (X & (C2 << C1)) != 0. */ + if ((log2 + TREE_INT_CST_LOW (arg001)) < prec) + { + tem = fold_build2_loc (loc, LSHIFT_EXPR, itype, + arg01, arg001); + tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, + arg000, tem); + return fold_build2_loc (loc, code, type, tem, + fold_convert_loc (loc, itype, arg1)); + } + /* Otherwise, for signed (arithmetic) shifts, + ((X >> C1) & C2) != 0 is rewritten as X < 0, and + ((X >> C1) & C2) == 0 is rewritten as X >= 0. */ + else if (!TYPE_UNSIGNED (itype)) + return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR + : LT_EXPR, + type, arg000, + build_int_cst (itype, 0)); + /* Otherwise, of unsigned (logical) shifts, + ((X >> C1) & C2) != 0 is rewritten as (X,false), and + ((X >> C1) & C2) == 0 is rewritten as (X,true). */ + else + return omit_one_operand_loc (loc, type, code == EQ_EXPR ? integer_one_node : integer_zero_node, arg000); + } } }