[GCC 10 PATCH] value-range: Give up on POLY_INT_CST ranges [PR97457]

Richard Sandiford richard.sandiford@arm.com
Wed Dec 2 16:27:02 GMT 2020


This is a gcc-10 version of:

Richard Sandiford <richard.sandiford@arm.com> writes:
> This PR shows another problem with calculating value ranges for
> POLY_INT_CSTs.  We have:
>
>   ivtmp_76 = ASSERT_EXPR <ivtmp_60, ivtmp_60 > POLY_INT_CST [9, 4294967294]>
>
> where the VQ coefficient is unsigned but is effectively acting
> as a negative number.  We wrongly give the POLY_INT_CST the range:
>
>   [9, INT_MAX]
>
> and things go downhill from there: later iterations of the unrolled
> epilogue are wrongly removed as dead.
>
> I guess this is the final nail in the coffin for doing VRP on
> POLY_INT_CSTs.  For other similarly exotic testcases we could have
> overflow for any coefficient, not just those that could be treated
> as contextually negative.
>
> Testing TYPE_OVERFLOW_UNDEFINED doesn't seem like an option because we
> couldn't handle warn_strict_overflow properly.  At this stage we're
> just recording a range that might or might not lead to strict-overflow
> assumptions later.
>
> It still feels like we should be able to do something here, but for
> now removing the code seems safest.  It's also telling that there
> are no testsuite failures on SVE from doing this.
>
> Tested on aarch64-linux-gnu (with and without SVE) and
> x86_64-linux-gnu.  OK for trunk and backports?
>
> Richard

The backport ended up looking a bit different.  Rather than fall through
to the later VR_VARYING code (which asserts for certain min and max values),
this code just moves directly to varying.

Tested on aarch64-linux-gnu, aarch64_be-elf, arm-linux-gnueabihf,
armeb-elf and x86_64-linux-gnu.  OK for GCC 10?

Richard


gcc/
	PR tree-optimization/97457
	* value-range.cc (irange::set): Don't decay POLY_INT_CST ranges
	to integer ranges.

gcc/testsuite/
	PR tree-optimization/97457
	* gcc.dg/vect/pr97457.c: New test.

(cherry picked from commit 54ef7701a9dec8c923a12d1983f8a051ba88a7b9)
---
 gcc/testsuite/gcc.dg/vect/pr97457.c | 15 +++++++++++++++
 gcc/value-range.cc                  | 29 ++++++-----------------------
 2 files changed, 21 insertions(+), 23 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/pr97457.c

diff --git a/gcc/testsuite/gcc.dg/vect/pr97457.c b/gcc/testsuite/gcc.dg/vect/pr97457.c
new file mode 100644
index 00000000000..506ba249b00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97457.c
@@ -0,0 +1,15 @@
+/* { dg-additional-options "-O3" } */
+
+int a;
+long c;
+signed char d(char e, char f) { return e + f; }
+int main(void) {
+  for (; a <= 1; a++) {
+    c = -8;
+    for (; c != 3; c = d(c, 1))
+      ;
+  }
+  char b = c;
+  if (b != 3)
+    __builtin_abort();
+}
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index bc4b061da57..04820846fe0 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -87,30 +87,13 @@ value_range::set (tree min, tree max, value_range_kind kind)
       return;
     }
 
-  if (kind == VR_RANGE)
+  if (kind != VR_VARYING
+      && (POLY_INT_CST_P (min) || POLY_INT_CST_P (max)))
     {
-      /* 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));
-	  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));
-	  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);
-	}
-    }
-  else if (kind != VR_VARYING)
-    {
-      if (POLY_INT_CST_P (min) || POLY_INT_CST_P (max))
-	kind = VR_VARYING;
+      tree typ = TREE_TYPE (min);
+      gcc_checking_assert (useless_type_conversion_p (typ, TREE_TYPE (max)));
+      set_varying (typ);
+      return;
     }
 
   if (kind == VR_VARYING)


More information about the Gcc-patches mailing list