On Thu, Nov 27, 2025 at 02:32:42PM +0100, Richard Biener wrote:
> > +#if GIMPLE
> > +/* (y << x) {<,<=} x -> false and (y << x) {>,>=} x -> true when y != 0
> > +   and (y << x) >> x == y and for signed comparison (y << x) >= 0.  */
> > +(for cmp (gt ge lt le)
> > + (simplify
> > +  (cmp:c (nop_convert1?@3 (lshift@2 @0 @1)) (convert2? @1))
> > +  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
> > +   (with { bool ok = false;
> > +      int_range_max vr0, vr1;
> > +      if (gimple_match_range_of_expr (vr0, @0, @2)
> > +          && !vr0.varying_p ()
> > +          && !vr0.undefined_p ()
> 
> I guess the varying and undefined checks could be put into
> gimple_match_range_of_expr as well?

Agreed about the undefined_p stuff, for varying_p I'd defer to the callers,
sometimes they are ok even with VARYING, depends on what exactly they use it
for.  Checking !vrN.varying_p () here isn't really necessary, just that
if it is varying, testing the rest is a waste of compile time, it will
vr0 surely contain zero in that case and lz will be 0, and for the shift
count it will not be smaller than lz + uns.

        Jakub

Reply via email to