Hi!

In vrp_visit_assignment_or_call we try to return SSA_PROP_VARYING
if update_value_range returned true and the new range is VR_VARYING,
but vrp_visit_phi_node fails to do that.
Another thing is that if update_value_range decides to
set_value_range_to_varying (old_vr);
it doesn't update new_vr, so the caller doesn't know the new vr
is varying (and calling get_value_range again sounds unnecessary).

The following patch fixes it, bootstrapped/regtested on x86_64-linux and
i686-linux, ok for trunk and 5.2?

2015-04-24  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/65875
        * tree-vrp.c (update_value_range): If in is_new case setting
        old_vr to VR_VARYING, also set new_vr to it.
        (vrp_visit_phi_node): Return SSA_PROP_VARYING instead of
        SSA_PROP_INTERESTING if update_value_range returned true,
        but new range is VR_VARYING.

        * gcc.c-torture/compile/pr65875.c: New test.

--- gcc/tree-vrp.c.jj   2015-04-20 14:35:39.000000000 +0200
+++ gcc/tree-vrp.c      2015-04-24 18:10:41.321367440 +0200
@@ -892,7 +892,12 @@ update_value_range (const_tree var, valu
         UNDEFINED or from VARYING.  */
       if (new_vr->type == VR_UNDEFINED
          || old_vr->type == VR_VARYING)
-       set_value_range_to_varying (old_vr);
+       {
+         BITMAP_FREE (new_vr->equiv);
+         set_value_range_to_varying (old_vr);
+         set_value_range_to_varying (new_vr);
+         return true;
+       }
       else
        set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
                         new_vr->equiv);
@@ -8941,6 +8946,9 @@ update_range:
          fprintf (dump_file, "\n");
        }
 
+      if (vr_result.type == VR_VARYING)
+       return SSA_PROP_VARYING;
+
       return SSA_PROP_INTERESTING;
     }
 
--- gcc/testsuite/gcc.c-torture/compile/pr65875.c.jj    2015-04-24 
18:20:47.650595581 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr65875.c       2015-04-24 
18:20:30.000000000 +0200
@@ -0,0 +1,24 @@
+/* PR tree-optimization/65875 */
+
+int a, b, c, d, e, f, g;
+
+void
+foo (void)
+{
+  long h = 0, i;
+  if (g < 0)
+    i = -g;
+  for (; b;)
+    for (; c;)
+      if (e)
+       h = 1;
+  for (; f;)
+    if (a)
+      break;
+  if (h > i)
+    while (h > i)
+      {
+       d = 0;
+       h--;
+      }
+}

        Jakub

Reply via email to