From patchwork Mon Dec 21 23:39:18 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Law X-Patchwork-Id: 559818 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 778BC140328 for ; Tue, 22 Dec 2015 10:39:29 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=WAdE+7zB; 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:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=AqigUVw25Jll8GKHWmcSNICrZfjTlFCdY31aksSih7WXZz9rK0 +P2167Tr31XuMv7gjJIemQ+CdHjThledVU0OQ+5qfsV9e4XB9qytsvv+InVRYyKU oCml27SUrNLvtsvzPsTSLIGJFYWQKwIq+RleOO2GeDMrOYmkQBR+23K80= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=R7dQhYA9LryTO3TEWvPX369zCFM=; b=WAdE+7zBoLW4r2m931HI /IEfjitDyWFfWgq7shGUHfHj83YSo98s6XPvNYvjFP+Mqon0dZmqDVGBvK+t88li d6wC4yDKUBLFhHHf75B2cbjBPRtyKgjRl6ZoYnsvkUsBeAmyVgbyJuFabXrwK1nI VHsCzuwBxg8wV2PfN5VHLN0= Received: (qmail 12215 invoked by alias); 21 Dec 2015 23:39:22 -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 12205 invoked by uid 89); 21 Dec 2015 23:39:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=rodat, PierreMarie, Pierre-Marie, Rodat X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 21 Dec 2015 23:39:20 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 18679C0B7E37 for ; Mon, 21 Dec 2015 23:39:18 +0000 (UTC) Received: from localhost.localdomain (ovpn-113-82.phx2.redhat.com [10.3.113.82]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tBLNdIa2017476 for ; Mon, 21 Dec 2015 18:39:18 -0500 To: gcc-patches@gcc.gnu.org From: Jeff Law Subject: [RFA] [PATCH][PR tree-optimization/64910] Fix reassociation of binary bitwise operations with 3 operands Message-ID: <56788DA6.80904@redhat.com> Date: Mon, 21 Dec 2015 16:39:18 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 X-IsSubscribed: yes As outlined in the BZ, given (x & y) & C reassociation will turn that into (x & C) & y Which inhibits bit operations on various targets. Associating as (x & y) & C is what we want. My original patch did this for all binary operations. However, reviewing the assembly code & dump files before/after it was pretty clear that doing this for arithmetic was losing (mostly in that we were missing CSE opportunities). Restricting to logicals means there's far fewer triggering cases, but in every one I looked at the resultant code was clearly better. The testcase is a bit unusual in that it's in tree-ssa. It checks the output of reassociation. However, on x86 and m68k it also checks the resulting assembly code, which I believe is unique in the tree-ssa directory. Bootstrapped and regression tested on x86_64-linux-gnu. The test has been verified on x86_64-linux-gnu, i686-linux-gnu and m68k-linux-gnu. OK for the trunk? diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7626ff..f5ca85e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-12-20 Jeff Law + + PR tree-optimization/64910 + * tree-ssa-reassoc.c (swap_ops_for_binary_stmt): Make sure constant + is last for binary bit operations. + 2015-12-21 Pierre-Marie de Rodat * dwarf2out.c (add_data_member_location_attribute): Do not diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bb2ed22..e2f55f3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-12-20 Jeff Law + + PR tree-optimization/64910 + * gcc.dg/tree-ssa/pr64910-2.c.c: New test. + 2015-12-21 Claudiu Zissulescu * gcc.target/arc/builtin_general.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr64910-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr64910-2.c new file mode 100644 index 0000000..2e3d679 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr64910-2.c @@ -0,0 +1,85 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-reassoc1" } */ + +/* We want to make sure that we reassociate in a way that has the + constant last. With the constant last, it's more likely to result + in a bitfield test on targets with such capabilities. */ + +extern void boo (); + +int b2b_uc (unsigned char u, unsigned char w) +{ + if ((u & w) & 0x20) + boo (); +} + +int b2b_us (unsigned short u, unsigned short w) +{ + if ((u & w) & 0x20) + boo (); +} + +int b2b_ui (unsigned int u, unsigned int w) +{ + if ((u & w) & 0x20) + boo (); +} +int b2b_ul (unsigned long u, unsigned long w) +{ + if ((u & w) & 0x20) + boo (); +} +int b2b_ull (unsigned long long u, unsigned long long w) +{ + if ((u & w) & 0x20) + boo (); +} + +int b2b_sc (signed char u, signed char w) +{ + if ((u & w) & 0x20) + boo (); +} + +int b2b_ss (signed short u, signed short w) +{ + if ((u & w) & 0x20) + boo (); +} + +int b2b_si (signed int u, signed int w) +{ + if ((u & w) & 0x20) + boo (); +} +int b2b_sl (signed long u, signed long w) +{ + if ((u & w) & 0x20) + boo (); +} +int b2b_sll (signed long long u, signed long long w) +{ + if ((u & w) & 0x20) + boo (); +} + +/* The AND of U & W should go into a temporary, when is then ANDed + with the constant. + + First verify that we have the right number of ANDs between U and W. */ +/* { dg-final { scan-tree-dump-times "\[uw\]_\[0-9\]+.D. \& \[uw\]_\[0-9\]+.D.;" 10 "reassoc1"} } */ + +/* Then verify that we have the right number of ANDS between a temporary + and the constant. */ +/* { dg-final { scan-tree-dump-times "_\[0-9]+ \& 32;" 10 "reassoc1"} } */ + +/* Each function has one AND. It will have either a second AND or TEST. So + we can count the number of AND and TEST instructions. They must be 2X + the number of test functions in this file. */ +/* { dg-final { scan-assembler-times "and|test" 20 { target { i?86-*-* x86_64-*-*} } } } */ + +/* Similarly on the m68k. The code for the long long tests is suboptimal, + which catch via the second pattern and xfail. */ +/* { dg-final { scan-assembler-times "and|btst" 20 { target { m68k-*-* } } } } */ +/* { dg-final { scan-assembler-not "or" { target { m68k-*-* } xfail { *-*-* } } } } */ + diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index e54700e..1dcfce3 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -3449,6 +3449,26 @@ swap_ops_for_binary_stmt (vec ops, oe1->op = temp.op; oe1->rank = temp.rank; } + /* For X OP Y OP C, associate as (X OP Y) OP C, but only for + logicals, which encourages bit operations. Experimentation + has shown this generally isn't a win for arithmetic. */ + else if (stmt) + { + enum tree_code opcode = gimple_assign_rhs_code (stmt); + if ((opcode == BIT_AND_EXPR + || opcode == BIT_IOR_EXPR + || opcode == BIT_XOR_EXPR) + && TREE_CODE (oe1->op) != INTEGER_CST + && TREE_CODE (oe2->op) != INTEGER_CST + && TREE_CODE (oe3->op) == INTEGER_CST) + { + operand_entry temp = *oe3; + oe3->op = oe1->op; + oe3->rank = oe1->rank; + oe1->op = temp.op; + oe1->rank= temp.rank; + } + } } /* If definition of RHS1 or RHS2 dominates STMT, return the later of those