This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Teach VRP about x >> cst even if x is VARYING (PR tree-optimization/64322)


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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]