From 96eb7d7a642085f651e9940f0ee75568d7c4441d Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 16 Oct 2019 09:50:44 +0000 Subject: [PATCH] Deal with incoming POLY_INT_CST ranges (PR92033) This patch makes value_range_base::set convert POLY_INT_CST bounds into the worst-case INTEGER_CST bounds. The main case in which this gives useful ranges is a lower bound of A + B * X becoming A when B >= 0. E.g.: [32 + 16X, 100] -> [32, 100] [32 + 16X, 32 + 16X] -> [32, MAX] But the same thing can be useful for the upper bound with negative X coefficients. 2019-10-16 Richard Sandiford 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. From-SVN: r277056 --- gcc/ChangeLog | 9 +++++++++ gcc/doc/poly-int.texi | 12 ++++++++++++ gcc/poly-int.h | 23 +++++++++++++++++++++++ gcc/tree-vrp.c | 18 ++++++++++++++++++ 4 files changed, 62 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 28629582a02..072eb8ce8bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-10-16 Richard Sandiford + + 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. + 2019-10-16 Feng Xue PR ipa/91088 diff --git a/gcc/doc/poly-int.texi b/gcc/doc/poly-int.texi index 1023e823cb3..d60bb02aabf 100644 --- a/gcc/doc/poly-int.texi +++ b/gcc/doc/poly-int.texi @@ -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 diff --git a/gcc/poly-int.h b/gcc/poly-int.h index 0ccdf680f43..67759ad58cc 100644 --- a/gcc/poly-int.h +++ b/gcc/poly-int.h @@ -1528,6 +1528,29 @@ constant_lower_bound (const poly_int_pod &a) return a.coeffs[0]; } +/* Return the constant lower bound of A, given that it is no less than B. */ + +template +inline POLY_CONST_COEFF (Ca, Cb) +constant_lower_bound_with_limit (const poly_int_pod &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 +inline POLY_CONST_COEFF (Ca, Cb) +constant_upper_bound_with_limit (const poly_int_pod &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. */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index cffa0508340..21910b36518 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -727,6 +727,24 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max) 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) -- 2.30.2