Deal with incoming POLY_INT_CST ranges (PR92033)
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 16 Oct 2019 09:50:44 +0000 (09:50 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 16 Oct 2019 09:50:44 +0000 (09:50 +0000)
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

gcc/ChangeLog
gcc/doc/poly-int.texi
gcc/poly-int.h
gcc/tree-vrp.c

index 28629582a023a38740936aab36ffc5b775bddb37..072eb8ce8bdcabd6bc8a9788ebe32ff6421d2701 100644 (file)
@@ -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
index 1023e823cb3aaf7713f242cae4751f1929bbef25..d60bb02aabf264792a54631cb5567ca0d30c7c6d 100644 (file)
@@ -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 0ccdf680f43c223b5c42147cad4b376d01e35ae4..67759ad58cc0f5befc5de1c06992e70effd8e176 100644 (file)
@@ -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.  */
index cffa05083400bb2539fed72eed7c695b5c8e6949..21910b36518000469529076c8a57ae2a9a00d805 100644 (file)
@@ -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)