diff mbox series

Fix PR84933

Message ID alpine.LSU.2.20.1803191427250.18265@zhemvz.fhfr.qr
State New
Headers show
Series Fix PR84933 | expand

Commit Message

Richard Biener March 19, 2018, 1:33 p.m. UTC
The following fixes PR84933 without really tackling the underlying
issue of having out-of-bound ranges in the lattice (out-of-bound
with respect to TYPE_MIN/MAX_VALUE) which is not sth I'd like to
resolve at this point.  It simply avoids the bogus transform
in set_and_canonicalize_value_range that results in this case
(~[0, 5] -> [4, 1] with TYPE_MAX_VALUE == 1).  I realize there
are similar conditions throughout the code so a more conservative
"fix" would be to not use TYPE_MIN/MAX_VALUE at all but IIRC
that will regress some optimization cases - still that's sth
to consider for GCC9.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2018-03-19  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/84933
	* tree-vrp.c (set_and_canonicalize_value_range): Treat out-of-bound
	values as -INF/INF when canonicalizing an ANTI_RANGE to a RANGE.

	* g++.dg/pr84933.C: New testcase.
diff mbox series

Patch

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c	(revision 258641)
+++ gcc/tree-vrp.c	(working copy)
@@ -386,8 +386,13 @@  set_and_canonicalize_value_range (value_
   /* Anti-ranges that can be represented as ranges should be so.  */
   if (t == VR_ANTI_RANGE)
     {
-      bool is_min = vrp_val_is_min (min);
-      bool is_max = vrp_val_is_max (max);
+      /* For -fstrict-enums we may receive out-of-range ranges so consider
+         values < -INF and values > INF as -INF/INF as well.  */
+      tree type = TREE_TYPE (min);
+      bool is_min = (INTEGRAL_TYPE_P (type)
+		     && tree_int_cst_compare (min, TYPE_MIN_VALUE (type)) <= 0);
+      bool is_max = (INTEGRAL_TYPE_P (type)
+		     && tree_int_cst_compare (max, TYPE_MAX_VALUE (type)) >= 0);
 
       if (is_min && is_max)
 	{
Index: gcc/testsuite/g++.dg/pr84933.C
===================================================================
--- gcc/testsuite/g++.dg/pr84933.C	(nonexistent)
+++ gcc/testsuite/g++.dg/pr84933.C	(working copy)
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O3 -fstrict-enums -fno-inline" } */
+
+enum a {};
+int *d;
+int b, e, f;
+a c, g;
+class h {
+    virtual unsigned i();
+};
+class j : h {
+    unsigned i() {
+	for (;;) {
+	    b = c <= 0;
+	    if (b)
+	      e = *d;
+	    b = g && c;
+	    if (b)
+	      f = *d;
+	}
+    }
+};
+void k() { new j; }