https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64322
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Richard Biener from comment #4) > (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 DIV and MOD already handle it (DIV quite similarly to this). And from the list of codes that extract_range_from_binary_expr_1 handles, I think RSHIFT_EXPR is the only one that (for certain VR_RANGEs of one argument) can decrease a VR_VARYING into something narrower and didn't handle arbitrary ranges of the other operand yet.