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  <rguent...@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.

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; }

Reply via email to