On Tue, Oct 15, 2019 at 12:35 PM Richard Sandiford <richard.sandif...@arm.com> wrote: > > Richard Biener <richard.guent...@gmail.com> writes: > > On October 14, 2019 2:32:43 PM GMT+02:00, Richard Sandiford > > <richard.sandif...@arm.com> wrote: > >>Richard Biener <richard.guent...@gmail.com> writes: > >>> On Fri, Oct 11, 2019 at 4:42 PM Richard Sandiford > >>> <richard.sandif...@arm.com> wrote: > >>>> > >>>> The range-tracking code has a pretty hard-coded assumption that > >>>> is_gimple_min_invariant is equivalent to "INTEGER_CST or invariant > >>>> ADDR_EXPR". It seems better to add a predicate specifically for > >>>> that rather than contiually fight cases in which it can't handle > >>>> other invariants. > >>>> > >>>> Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? > >>> > >>> ICK. Nobody is going to remember this new restriction and > >>> constant_range_value_p reads like constant_value_range_p ;) > >>> > >>> Btw, is_gimple_invariant_address shouldn't have been exported, > >>> it's only use could have used is_gimple_min_invariant... > >> > >>What do you think we should do instead? > > > > Just handle POLY_INT_CST in a few place to quickly enough drop to varying. > > OK, how about this? Aldy's suggestion would be fine by me too, > but I thought I'd try this first given Aldy's queasiness about > allowing POLY_INT_CSTs further in. > > The main case in which this gives useful ranges is a lower bound > of A + B * X becoming A when B >= 0. E.g.: > > (1) [32 + 16X, 100] -> [32, 100] > (2) [32 + 16X, 32 + 16X] -> [32, MAX] > > But the same thing can be useful for the upper bound with negative > X coefficients. > > We can revisit this later if keeping a singleton range for (2) > would be better. > > Tested as before.
Works for me. Richard. > Richard > > > 2019-10-15 Richard Sandiford <richard.sandif...@arm.com> > > gcc/ > PR middle-end/92033 > * poly-int.h (constant_lower_bound_with_limit): New function. > (constant_upper_bound_with_limit): Likewise. > * doc/poly-int.texi: Document them. > * tree-vrp.c (value_range_base::set): Convert POLY_INT_CST bounds > into the worst-case INTEGER_CST bounds. > > Index: gcc/poly-int.h > =================================================================== > --- gcc/poly-int.h 2019-07-10 19:41:26.395898027 +0100 > +++ gcc/poly-int.h 2019-10-15 11:30:14.099625553 +0100 > @@ -1528,6 +1528,29 @@ constant_lower_bound (const poly_int_pod > return a.coeffs[0]; > } > > +/* Return the constant lower bound of A, given that it is no less than B. */ > + > +template<unsigned int N, typename Ca, typename Cb> > +inline POLY_CONST_COEFF (Ca, Cb) > +constant_lower_bound_with_limit (const poly_int_pod<N, Ca> &a, const Cb &b) > +{ > + if (known_ge (a, b)) > + return a.coeffs[0]; > + return b; > +} > + > +/* Return the constant upper bound of A, given that it is no greater > + than B. */ > + > +template<unsigned int N, typename Ca, typename Cb> > +inline POLY_CONST_COEFF (Ca, Cb) > +constant_upper_bound_with_limit (const poly_int_pod<N, Ca> &a, const Cb &b) > +{ > + if (known_le (a, b)) > + return a.coeffs[0]; > + return b; > +} > + > /* Return a value that is known to be no greater than A and B. This > will be the greatest lower bound for some indeterminate values but > not necessarily for all. */ > Index: gcc/doc/poly-int.texi > =================================================================== > --- gcc/doc/poly-int.texi 2019-03-08 18:14:25.333011645 +0000 > +++ gcc/doc/poly-int.texi 2019-10-15 11:30:14.099625553 +0100 > @@ -803,6 +803,18 @@ the assertion is known to hold. > @item constant_lower_bound (@var{a}) > Assert that @var{a} is nonnegative and return the smallest value it can have. > > +@item constant_lower_bound_with_limit (@var{a}, @var{b}) > +Return the least value @var{a} can have, given that the context in > +which @var{a} appears guarantees that the answer is no less than @var{b}. > +In other words, the caller is asserting that @var{a} is greater than or > +equal to @var{b} even if @samp{known_ge (@var{a}, @var{b})} doesn't hold. > + > +@item constant_upper_bound_with_limit (@var{a}, @var{b}) > +Return the greatest value @var{a} can have, given that the context in > +which @var{a} appears guarantees that the answer is no greater than @var{b}. > +In other words, the caller is asserting that @var{a} is less than or equal > +to @var{b} even if @samp{known_le (@var{a}, @var{b})} doesn't hold. > + > @item lower_bound (@var{a}, @var{b}) > Return a value that is always less than or equal to both @var{a} and @var{b}. > It will be the greatest such value for some indeterminate values > Index: gcc/tree-vrp.c > =================================================================== > --- gcc/tree-vrp.c 2019-10-14 09:04:54.515259320 +0100 > +++ gcc/tree-vrp.c 2019-10-15 11:30:14.099625553 +0100 > @@ -727,6 +727,24 @@ value_range_base::set (enum value_range_ > return; > } > > + /* Convert POLY_INT_CST bounds into worst-case INTEGER_CST bounds. */ > + if (POLY_INT_CST_P (min)) > + { > + tree type_min = vrp_val_min (TREE_TYPE (min), true); > + widest_int lb > + = constant_lower_bound_with_limit (wi::to_poly_widest (min), > + wi::to_widest (type_min)); > + min = wide_int_to_tree (TREE_TYPE (min), lb); > + } > + if (POLY_INT_CST_P (max)) > + { > + tree type_max = vrp_val_max (TREE_TYPE (max), true); > + widest_int ub > + = constant_upper_bound_with_limit (wi::to_poly_widest (max), > + wi::to_widest (type_max)); > + max = wide_int_to_tree (TREE_TYPE (max), ub); > + } > + > /* Nothing to canonicalize for symbolic ranges. */ > if (TREE_CODE (min) != INTEGER_CST > || TREE_CODE (max) != INTEGER_CST)