https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64322

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #3)
> For VRP I'm thinking of (completely untested):
> --- 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);
> +             }

Yeah, that should work.  We should probably simply handle all operation
codes that do not explicitely handle non-simple VR_RANGEs by promoting
all operands that way (also handle the single-VR_UNDEFINED op case and
VR_VARYING generally that way).  The DIV and MOD_EXPR cases look like
they would benefit from that.

>             extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1);
>             return;
>           }

Reply via email to