* [PATCH] Teach VRP about x >> cst even if x is VARYING (PR tree-optimization/64322)
@ 2014-12-16 16:38 Jakub Jelinek
2014-12-16 18:28 ` Richard Biener
0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2014-12-16 16:38 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches
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 <jakub@redhat.com>
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
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Teach VRP about x >> cst even if x is VARYING (PR tree-optimization/64322)
2014-12-16 16:38 [PATCH] Teach VRP about x >> cst even if x is VARYING (PR tree-optimization/64322) Jakub Jelinek
@ 2014-12-16 18:28 ` Richard Biener
0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2014-12-16 18:28 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: gcc-patches
On Tue, 16 Dec 2014, Jakub Jelinek wrote:
> 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?
Ok.
Thanks,
Richard.
> 2014-12-16 Jakub Jelinek <jakub@redhat.com>
>
> 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
>
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild,
Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2014-12-16 18:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-16 16:38 [PATCH] Teach VRP about x >> cst even if x is VARYING (PR tree-optimization/64322) Jakub Jelinek
2014-12-16 18:28 ` Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).