From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3651 invoked by alias); 16 Dec 2014 16:30:38 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 3638 invoked by uid 89); 16 Dec 2014 16:30:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 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; Tue, 16 Dec 2014 16:30:35 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id sBGGUYDP021981 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 16 Dec 2014 11:30:34 -0500 Received: from tucnak.zalov.cz (ovpn-116-64.ams2.redhat.com [10.36.116.64]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id sBGGUWlN025652 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Tue, 16 Dec 2014 11:30:33 -0500 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.14.9/8.14.9) with ESMTP id sBGGUUl9021979; Tue, 16 Dec 2014 17:30:30 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.14.9/8.14.9/Submit) id sBGGUScA021978; Tue, 16 Dec 2014 17:30:28 +0100 Date: Tue, 16 Dec 2014 16:38:00 -0000 From: Jakub Jelinek To: Richard Biener Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Teach VRP about x >> cst even if x is VARYING (PR tree-optimization/64322) Message-ID: <20141216163028.GG1667@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes X-SW-Source: 2014-12/txt/msg01351.txt.bz2 Hi! If for RSHIFT_EXPR vr0 is not VR_RANGE or is symbolic, currently we make the result VARYING, even when we can do much better just by trying to shift the min and max values down. Divisions/modulo already handles it similarly, and +/-/& also handle it. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2014-12-16 Jakub Jelinek PR tree-optimization/64322 * tree-vrp.c (extract_range_from_binary_expr_1): Attempt to derive range for RSHIFT_EXPR even if vr0 range is not VR_RANGE or is symbolic. * gcc.dg/tree-ssa/vrp95.c: New test. --- gcc/tree-vrp.c.jj 2014-12-01 14:57:30.000000000 +0100 +++ gcc/tree-vrp.c 2014-12-16 10:17:27.543111649 +0100 @@ -2434,6 +2434,7 @@ extract_range_from_binary_expr_1 (value_ && code != MAX_EXPR && code != PLUS_EXPR && code != MINUS_EXPR + && code != RSHIFT_EXPR && (vr0.type == VR_VARYING || vr1.type == VR_VARYING || vr0.type != vr1.type @@ -2948,6 +2949,15 @@ extract_range_from_binary_expr_1 (value_ { if (code == RSHIFT_EXPR) { + /* Even if vr0 is VARYING or otherwise not usable, we can derive + useful ranges just from the shift count. E.g. + x >> 63 for signed 64-bit x is always [-1, 0]. */ + if (vr0.type != VR_RANGE || symbolic_range_p (&vr0)) + { + vr0.type = type = VR_RANGE; + vr0.min = vrp_val_min (expr_type); + vr0.max = vrp_val_max (expr_type); + } extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1); return; } --- gcc/testsuite/gcc.dg/tree-ssa/vrp95.c.jj 2014-12-16 12:11:19.048361844 +0100 +++ gcc/testsuite/gcc.dg/tree-ssa/vrp95.c 2014-12-16 12:24:47.080308362 +0100 @@ -0,0 +1,50 @@ +/* PR tree-optimization/64322 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ + +extern void link_error (); +extern void required_check (); + +long long int +foo (long long int x) +{ + x >>= sizeof (long long int) * __CHAR_BIT__ - 1; + if (x != 0 && x != -1) + link_error (); + return x; +} + +unsigned long long int +bar (unsigned long long int x) +{ + x >>= sizeof (long long int) * __CHAR_BIT__ - 1; + if (x != 0 && x != 1) + link_error (); + return x; +} + +long long int +baz (long long int x) +{ + x = (x >> sizeof (long long int) * __CHAR_BIT__ - 1) << 1; + x = x / 0x100000000LL; + if (x != 0) + link_error (); + return x; +} + +unsigned long long int +range (unsigned long long int x, int y) +{ + y &= 3; + x >>= sizeof (long long int) * __CHAR_BIT__ - 1 - y; + if (x > 15) + link_error (); + if (x == 15) + required_check (); + return x; +} + +/* { dg-final { scan-tree-dump-not "link_error" "vrp1" } } */ +/* { dg-final { scan-tree-dump "required_check" "vrp1" } } */ +/* { dg-final { cleanup-tree-dump "vrp1" } } */ Jakub