On Sat, 27 Apr 2013, Jakub Jelinek wrote:

> Hi!
> 
> If shift count range is [0, 1], then for unsigned LSHIFT_EXPR
> bound is the topmost bit, but as llshift method always sign-extends
> the result into double_int, the test don't properly find out that
> deriving the value range is unsafe.  In this case
> vr0 is [0x7fff8001, 0x80000001], thus when shifting up by 0 or one bit
> we might shift out either zero or 1.
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?

Ok.

Thanks,
Richard.

> 2013-04-26  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/57083
>       * tree-vrp.c (extract_range_from_binary_expr_1): For LSHIFT_EXPR with
>       non-singleton shift count range, zero extend low_bound for uns case.
> 
>       * gcc.dg/torture/pr57083.c: New test.
> 
> --- gcc/tree-vrp.c.jj 2013-04-24 12:07:07.000000000 +0200
> +++ gcc/tree-vrp.c    2013-04-26 17:59:41.077938198 +0200
> @@ -2837,7 +2837,7 @@ extract_range_from_binary_expr_1 (value_
>  
>             if (uns)
>               {
> -               low_bound = bound;
> +               low_bound = bound.zext (prec);
>                 high_bound = complement.zext (prec);
>                 if (tree_to_double_int (vr0.max).ult (low_bound))
>                   {
> --- gcc/testsuite/gcc.dg/torture/pr57083.c.jj 2013-04-26 18:09:05.396031875 
> +0200
> +++ gcc/testsuite/gcc.dg/torture/pr57083.c    2013-04-26 18:08:51.000000000 
> +0200
> @@ -0,0 +1,15 @@
> +/* PR tree-optimization/57083 */
> +/* { dg-do run { target int32plus } } */
> +
> +extern void abort (void);
> +short x = 1;
> +int y = 0;
> +
> +int
> +main ()
> +{
> +  unsigned t = (0x7fff8001U - x) << (y == 0);
> +  if (t != 0xffff0000U)
> +    abort ();
> +  return 0;
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend

Reply via email to