re PR bootstrap/87640 (internal compiler error: in check, at tree-vrp.c:155)
authorRichard Biener <rguenther@suse.de>
Mon, 22 Oct 2018 10:22:48 +0000 (10:22 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 22 Oct 2018 10:22:48 +0000 (10:22 +0000)
2018-10-22  Richard Biener  <rguenther@suse.de>

PR tree-optimization/87640
* tree-vrp.c (set_value_range_with_overflow): Decompose
incomplete result.
(extract_range_from_binary_expr_1): Adjust.

* gcc.dg/torture/pr87640.c: New testcase.

From-SVN: r265375

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr87640.c [new file with mode: 0644]
gcc/tree-vrp.c

index 57db965f6e6ff284dab914a272d5464fc3d2a53a..1fad1da2e4a29ca86f1dab6fabbc8cdd1ea8d18c 100644 (file)
@@ -1,3 +1,10 @@
+2018-10-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87640
+       * tree-vrp.c (set_value_range_with_overflow): Decompose
+       incomplete result.
+       (extract_range_from_binary_expr_1): Adjust.
+
 2018-10-22  Martin Jambor  <mjambor@suse.cz>
 
        * tree-eh.h (stmt_could_throw_p): Add function parameter.
index bb22d82864dab3eae2c165862aaec86dcd980fba..1ca548120a8330668fac987522350add432bd2d0 100644 (file)
@@ -1,3 +1,8 @@
+2018-10-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87640
+       * gcc.dg/torture/pr87640.c: New testcase.
+
 2018-10-22  Ilya Leoshkevich  <iii@linux.ibm.com>
 
        * gcc.target/s390/litpool-int.c: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr87640.c b/gcc/testsuite/gcc.dg/torture/pr87640.c
new file mode 100644 (file)
index 0000000..09bd3b4
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+int main ()
+{ 
+  unsigned b = 0;
+  int c, d = -8;
+  for (; b < 2; b++)
+    for (c = 1; c; c--)
+      d++;
+  return 0;
+}
index d3276397d8bde4642d1dc6e2ad6606d1080fd9af..28b4d566a526c3032f3f96c2d7d9261b1047e205 100644 (file)
@@ -1328,7 +1328,7 @@ combine_bound (enum tree_code code, wide_int &wi, wi::overflow_type &ovf,
    underflow.  +1 indicates overflow.  0 indicates neither.  */
 
 static void
-set_value_range_with_overflow (value_range &vr,
+set_value_range_with_overflow (value_range_kind &kind, tree &min, tree &max,
                               tree type,
                               const wide_int &wmin, const wide_int &wmax,
                               wi::overflow_type min_ovf,
@@ -1341,7 +1341,7 @@ set_value_range_with_overflow (value_range &vr,
      range covers all values.  */
   if (prec == 1 && wi::lt_p (wmax, wmin, sgn))
     {
-      set_value_range_to_varying (&vr);
+      kind = VR_VARYING;
       return;
     }
 
@@ -1357,13 +1357,15 @@ set_value_range_with_overflow (value_range &vr,
             the entire range.  We have a similar check at the end of
             extract_range_from_binary_expr_1.  */
          if (wi::gt_p (tmin, tmax, sgn))
-           vr.set_varying ();
+           kind = VR_VARYING;
          else
-           /* No overflow or both overflow or underflow.  The
-              range kind stays VR_RANGE.  */
-           vr = value_range (VR_RANGE,
-                             wide_int_to_tree (type, tmin),
-                             wide_int_to_tree (type, tmax));
+           {
+             kind = VR_RANGE;
+             /* No overflow or both overflow or underflow.  The
+                range kind stays VR_RANGE.  */
+             min = wide_int_to_tree (type, tmin);
+             max = wide_int_to_tree (type, tmax);
+           }
          return;
        }
       else if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
@@ -1384,18 +1386,18 @@ set_value_range_with_overflow (value_range &vr,
             types values.  */
          if (covers || wi::cmp (tmin, tmax, sgn) > 0)
            {
-             set_value_range_to_varying (&vr);
+             kind = VR_VARYING;
              return;
            }
-         vr = value_range (VR_ANTI_RANGE,
-                           wide_int_to_tree (type, tmin),
-                           wide_int_to_tree (type, tmax));
+         kind = VR_ANTI_RANGE;
+         min = wide_int_to_tree (type, tmin);
+         max = wide_int_to_tree (type, tmax);
          return;
        }
       else
        {
          /* Other underflow and/or overflow, drop to VR_VARYING.  */
-         set_value_range_to_varying (&vr);
+         kind = VR_VARYING;
          return;
        }
     }
@@ -1405,7 +1407,7 @@ set_value_range_with_overflow (value_range &vr,
         value.  */
       wide_int type_min = wi::min_value (prec, sgn);
       wide_int type_max = wi::max_value (prec, sgn);
-      tree min, max;
+      kind = VR_RANGE;
       if (min_ovf == wi::OVF_UNDERFLOW)
        min = wide_int_to_tree (type, type_min);
       else if (min_ovf == wi::OVF_OVERFLOW)
@@ -1419,7 +1421,6 @@ set_value_range_with_overflow (value_range &vr,
        max = wide_int_to_tree (type, type_max);
       else
        max = wide_int_to_tree (type, wmax);
-      vr = value_range (VR_RANGE, min, max);
     }
 }
 
@@ -1676,21 +1677,23 @@ extract_range_from_binary_expr_1 (value_range *vr,
            }
 
          /* Adjust the range for possible overflow.  */
-         set_value_range_with_overflow (*vr, expr_type,
+         min = NULL_TREE;
+         max = NULL_TREE;
+         set_value_range_with_overflow (type, min, max, expr_type,
                                         wmin, wmax, min_ovf, max_ovf);
-         if (vr->varying_p ())
-           return;
+         if (type == VR_VARYING)
+           {
+             set_value_range_to_varying (vr);
+             return;
+           }
 
          /* Build the symbolic bounds if needed.  */
-         min = vr->min ();
-         max = vr->max ();
          adjust_symbolic_bound (min, code, expr_type,
                                 sym_min_op0, sym_min_op1,
                                 neg_min_op0, neg_min_op1);
          adjust_symbolic_bound (max, code, expr_type,
                                 sym_max_op0, sym_max_op1,
                                 neg_max_op0, neg_max_op1);
-         type = vr->kind ();
        }
       else
        {