From patchwork Fri Sep 10 11:37:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 64379 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]) by ozlabs.org (Postfix) with SMTP id 1C3E0B70DB for ; Fri, 10 Sep 2010 21:37:48 +1000 (EST) Received: (qmail 17338 invoked by alias); 10 Sep 2010 11:37:46 -0000 Received: (qmail 17311 invoked by uid 22791); 10 Sep 2010 11:37:45 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 10 Sep 2010 11:37:40 +0000 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8ABbGo9018713 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 10 Sep 2010 07:37:16 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o8ABbFd2027013 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 10 Sep 2010 07:37:15 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id o8ABbnTe023912; Fri, 10 Sep 2010 13:37:49 +0200 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id o8ABbnSO023910; Fri, 10 Sep 2010 13:37:49 +0200 Date: Fri, 10 Sep 2010 13:37:49 +0200 From: Jakub Jelinek To: Eric Botcazou Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] Optimize (X >> N) {>, >=, <, <=} C in the combiner (PR tree-optimization/20517) Message-ID: <20100910113748.GV1269@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek References: <20100909070521.GT1269@tyan-ft48-01.lab.bos.redhat.com> <201009101000.27189.ebotcazou@adacore.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <201009101000.27189.ebotcazou@adacore.com> User-Agent: Mutt/1.5.20 (2009-12-10) X-IsSubscribed: yes 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 On Fri, Sep 10, 2010 at 10:00:27AM +0200, Eric Botcazou wrote: > > 2010-09-09 Jakub Jelinek > > > > PR tree-optimization/20517 > > * combine.c (simplify_comparison): Optimize (X >> N) {>,>=,<,<+} C > > even if low N bits of X aren't known to be zero. > > OK on principle, but can we avoid the code duplication by ORing the comparison > on low bits with !equality_comparison_p and setting the low order bits in the > shifted constant only for the appropriate codes? Like this? The reason I haven't done this initially was that a) I was afraid of LTGT and UN* codes, but those shouldn't be present for MODE_INT op0 which is checked earlier b) I want to prefer C << N over ((C + 1) << N) - 1 when possible (when low bits are known to be zero), because the former might be a cheaper constant and I didn't want to call nonzero_bits twice. In the patch below that is handled by adding the low_bits temporary. 2010-09-10 Jakub Jelinek PR rtl-optimization/45617 * combine.c (simplify_comparison): Optimize (X >> N) {>,>=,<,<=} C even if low N bits of X aren't known to be zero. * gcc.target/i386/pr45617.c: New test. Jakub --- gcc/combine.c.jj 2010-09-09 08:40:37.676409513 +0200 +++ gcc/combine.c 2010-09-10 13:24:30.019646880 +0200 @@ -11773,13 +11773,14 @@ simplify_comparison (enum rtx_code code, /* If we have (compare (xshiftrt FOO N) (const_int C)) and the low order N bits of FOO are known to be zero, we can do this by comparing FOO with C shifted left N bits so long as no - overflow occurs. */ + overflow occurs. Even if the low order N bits of FOO aren't known + to be zero, if the comparison is >= or < we can use the same + optimization and for > or <= by setting all the low + order N bits in the comparison constant. */ if (CONST_INT_P (XEXP (op0, 1)) - && INTVAL (XEXP (op0, 1)) >= 0 + && INTVAL (XEXP (op0, 1)) > 0 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT && mode_width <= HOST_BITS_PER_WIDE_INT - && (nonzero_bits (XEXP (op0, 0), mode) - & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0 && (((unsigned HOST_WIDE_INT) const_op + (GET_CODE (op0) != LSHIFTRT ? ((GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)) >> 1) @@ -11787,15 +11788,25 @@ simplify_comparison (enum rtx_code code, : 0)) <= GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)))) { - /* If the shift was logical, then we must make the condition - unsigned. */ - if (GET_CODE (op0) == LSHIFTRT) - code = unsigned_condition (code); - - const_op <<= INTVAL (XEXP (op0, 1)); - op1 = GEN_INT (const_op); - op0 = XEXP (op0, 0); - continue; + HOST_WIDE_INT low_bits + = (nonzero_bits (XEXP (op0, 0), mode) + & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)); + if (low_bits == 0 || !equality_comparison_p) + { + /* If the shift was logical, then we must make the condition + unsigned. */ + if (GET_CODE (op0) == LSHIFTRT) + code = unsigned_condition (code); + + const_op <<= INTVAL (XEXP (op0, 1)); + if (low_bits != 0 + && (code == GT || code == GTU || code == LE || code == LEU)) + const_op + |= (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1); + op1 = GEN_INT (const_op); + op0 = XEXP (op0, 0); + continue; + } } /* If we are using this shift to extract just the sign bit, we --- gcc/testsuite/gcc.target/i386/pr45617.c.jj 2010-09-10 13:20:41.868771521 +0200 +++ gcc/testsuite/gcc.target/i386/pr45617.c 2010-09-10 13:20:41.868771521 +0200 @@ -0,0 +1,22 @@ +/* PR rtl-optimization/45617 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int f1 (int x) +{ + return (x >> 23) > 12; +} +int f2 (int x) +{ + return x > ((13 << 23) - 1); +} +int f3 (int x) +{ + return (x >> 23) >= 12; +} +int f4 (int x) +{ + return x >= (12 << 23); +} + +/* { dg-final { scan-assembler-not "sarl" } } */