On Fri, Feb 03, 2023 at 11:23:28AM -0500, Andrew MacLeod wrote:
> 
> On 2/3/23 04:16, Jakub Jelinek wrote:
> > On Fri, Feb 03, 2023 at 09:50:43AM +0100, Aldy Hernandez wrote:
> > > [PR tree-optimization/18639] Compare nonzero bits in irange with 
> > > widest_int.
> > 0 missing in the bug number in the subject line, though the current
> > recommended formatting of the subject is I think:
> > value-range: Compare nonzero bits in irange with widest_int [PR180639]
> >          PR 108639/tree-optimization
> > 
> > Reversed component and number
> > 
> > > --- a/gcc/value-range.cc
> > > +++ b/gcc/value-range.cc
> > > @@ -1259,7 +1259,10 @@ irange::legacy_equal_p (const irange &other) const
> > >                                  other.tree_lower_bound (0))
> > >             && vrp_operand_equal_p (tree_upper_bound (0),
> > >                                     other.tree_upper_bound (0))
> > > -   && get_nonzero_bits () == other.get_nonzero_bits ());
> > > +   && (widest_int::from (get_nonzero_bits (),
> > > +                         TYPE_SIGN (type ()))
> > > +       == widest_int::from (other.get_nonzero_bits (),
> > > +                            TYPE_SIGN (other.type ()))));
> > >   }
> > >   bool
> > > @@ -1294,7 +1297,11 @@ irange::operator== (const irange &other) const
> > >             || !operand_equal_p (ub, ub_other, 0))
> > >           return false;
> > >       }
> > > -  return get_nonzero_bits () == other.get_nonzero_bits ();
> > > +  widest_int nz1 = widest_int::from (get_nonzero_bits (),
> > > +                              TYPE_SIGN (type ()));
> > > +  widest_int nz2 = widest_int::from (other.get_nonzero_bits (),
> > > +                              TYPE_SIGN (other.type ()));
> > > +  return nz1 == nz2;
> > >   }
> > While the above avoids the ICE (and would be certainly correct for
> > the bounds, depending on the sign of their type sign or zero extended
> > to widest int), but is the above what we want for non-zero bits
> > to be considered equal?  The wide_ints (which ought to have precision
> > of the corresponding type) don't represent normal numbers but bitmasks,
> > 0 - this bit is known to be zero, 1 - nothing is known about this bit).
> > So, if there are different precisions and the narrower value has 0
> > in the MSB of the bitmask (so MSB is known to be zero), the above requires
> > for equality that in the other range all upper bits are known to be zero
> > too for both signed and unsigned.  That is ok.  Similarly for MSB set
> > if TYPE_SIGN of the narrower is unsigned, the MSB value is unknown, but we
> > require on the wider to have all the upper bits cleared.  But for signed
> > narrower type with MSB set, i.e. it is unknown if it is positive or
> > negative, the above requires that all the above bits are unknown too.
> > And that is the case I'm not sure about, whether in that case the
> > upper bits of the wider wide_int should be checked at all.
> > Though, perhaps from the POV of nonzero bits derived from the sign-extended
> > values in the ranges sign bit copies (so all above bits 1) is what one would
> > get, so maybe it is ok.  Just food for thought.
> > 
> if the bits match exactly along with everything else, then we can be sure
> the ranges are truly equal.  If for some reason the numbers are all the same
> but the non-zero bits don't compare equal,  then I can't think of what harm
> it could cause to compare unequal..  Worst case is we dont perform some
> optimization in this extremely rare scenario of differing precisions.  And
> in fact they could actually be unequal...
> 
> So I suspect this is fine...

Ok then.

        Jakub

Reply via email to