summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-10-16 09:50:44 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-10-16 09:50:44 +0000
commit96eb7d7a642085f651e9940f0ee75568d7c4441d (patch)
treef7eca938631203946dc47f7d9408210613dc0571
parent4307a485c39fd1c317d6cead2707a903052c4753 (diff)
downloadgcc-96eb7d7a642085f651e9940f0ee75568d7c4441d.tar.gz
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 <richard.sandiford@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. From-SVN: r277056
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/doc/poly-int.texi12
-rw-r--r--gcc/poly-int.h23
-rw-r--r--gcc/tree-vrp.c18
4 files changed, 62 insertions, 0 deletions
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 <richard.sandiford@arm.com>
+
+ 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 <fxue@os.amperecomputing.com>
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<N, Ca> &a)
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. */
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)