re PR tree-optimization/29446 (VRP ICE in compare_names)
authorRichard Guenther <rguenther@suse.de>
Fri, 13 Oct 2006 20:09:10 +0000 (20:09 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 13 Oct 2006 20:09:10 +0000 (20:09 +0000)
2006-10-13  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/29446
* tree-vrp.c (fix_equivalence_set): Remove.
(extract_range_from_assert): Do not call fix_equivalence_set.
(debug_value_range): Print a newline.
(compare_name_with_value): For equivalence sets with
inconsistent value ranges conservatively bail out.
(compare_names): Likewise.

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

From-SVN: r117705

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

index bbea7ce9a786aee58c282e778fcbbf0eadb0a83d..d242366e058128fb38ffb8421e2b1d400186ca8a 100644 (file)
@@ -1,3 +1,13 @@
+2006-10-13  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/29446
+       * tree-vrp.c (fix_equivalence_set): Remove.
+       (extract_range_from_assert): Do not call fix_equivalence_set.
+       (debug_value_range): Print a newline.
+       (compare_name_with_value): For equivalence sets with
+       inconsistent value ranges conservatively bail out.
+       (compare_names): Likewise.
+
 2006-10-13  David Edelsohn  <edelsohn@gnu.org>
 
        * doc/install.texi (*-ibm-aix*): Add comment about 32-bit GMP
index b18ddd97dbbfbd8cebefaee89450221cf65f89df..5e90addb26bc5b7570f192ecc783c609e78f5e55 100644 (file)
@@ -1,3 +1,8 @@
+2006-10-13  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/29446
+       * gcc.dg/torture/pr29446.c: New testcase.
+
 2006-10-13  Bill Wendling  <wendling@apple.com>
  
        * g++.old-deja/g++.brendan/scope5.C: Changed "Class" to "Klasse".
diff --git a/gcc/testsuite/gcc.dg/torture/pr29446.c b/gcc/testsuite/gcc.dg/torture/pr29446.c
new file mode 100644 (file)
index 0000000..5571c71
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+
+void f(_Bool D917, int j0, int ubound1, int ubound5)
+{
+  int i, j = j0;
+  int (*abc)[3];
+  i = 1;
+  while (1)
+    {
+       if (j <= 3)
+         while (1)
+           {
+              if (i != j)
+                {
+                  if (ubound1 <= 0)
+                    return;
+                  (*abc)[1] = 0;
+                }
+               else
+                 {
+                    if (j > ubound1)
+                      return;
+                    if (ubound5 <= 0)
+                      return;
+                  }
+               j = j + 1;
+               if (D917)
+                 break;
+           }
+    i = i + 1;
+  }
+}
index 4a30e4ee8a553670d264e40a738add32efbdcd86..8e67e8a3d2b327f3ee0ba1ab25f946a61a040803 100644 (file)
@@ -724,86 +724,6 @@ ssa_name_nonzero_p (tree t)
 }
 
 
-/* When extracting ranges from X_i = ASSERT_EXPR <Y_j, pred>, we will
-   initially consider X_i and Y_j equivalent, so the equivalence set
-   of Y_j is added to the equivalence set of X_i.  However, it is
-   possible to have a chain of ASSERT_EXPRs whose predicates are
-   actually incompatible.  This is usually the result of nesting of
-   contradictory if-then-else statements.  For instance, in PR 24670:
-
-       count_4 has range [-INF, 63]
-
-       if (count_4 != 0)
-         {
-           count_19 = ASSERT_EXPR <count_4, count_4 != 0>
-           if (count_19 > 63)
-             {
-               count_18 = ASSERT_EXPR <count_19, count_19 > 63>
-               if (count_18 <= 63)
-                 ...
-             }
-         }
-
-   Notice that 'if (count_19 > 63)' is trivially false and will be
-   folded out at the end.  However, during propagation, the flowgraph
-   is not cleaned up and so, VRP will evaluate predicates more
-   predicates than necessary, so it must support these
-   inconsistencies.  The problem here is that because of the chaining
-   of ASSERT_EXPRs, the equivalency set for count_18 includes count_4.
-   Since count_4 has an incompatible range, we ICE when evaluating the
-   ranges in the equivalency set.  So, we need to remove count_4 from
-   it.  */
-
-static void
-fix_equivalence_set (value_range_t *vr_p)
-{
-  bitmap_iterator bi;
-  unsigned i;
-  bitmap e = vr_p->equiv;
-  bitmap to_remove;
-
-  /* Only detect inconsistencies on numeric ranges.  */
-  if (vr_p->type == VR_VARYING
-      || vr_p->type == VR_UNDEFINED
-      || symbolic_range_p (vr_p))
-    return;
-
-  to_remove = BITMAP_ALLOC (NULL);
-  EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
-    {
-      value_range_t *equiv_vr = vr_value[i];
-
-      if (equiv_vr->type == VR_VARYING
-         || equiv_vr->type == VR_UNDEFINED)
-       continue;
-
-      if (vr_p->type == VR_RANGE
-         && equiv_vr->type == VR_RANGE)
-       {
-         /* Two ranges have an empty intersection if their end points
-            are outside of the other range.  */
-         if (compare_values (equiv_vr->min, vr_p->max) == 1
-             || compare_values (equiv_vr->max, vr_p->min) == -1)
-           bitmap_set_bit (to_remove, i);
-       }
-      else if ((equiv_vr->type == VR_RANGE && vr_p->type == VR_ANTI_RANGE)
-              || (equiv_vr->type == VR_ANTI_RANGE && vr_p->type == VR_RANGE))
-       {
-         /* A range and an anti-range have an empty intersection if
-            their end points are the same.  FIXME,
-            value_ranges_intersect_p should handle this
-            automatically.  */
-         if (compare_values (equiv_vr->min, vr_p->min) == 0
-             && compare_values (equiv_vr->max, vr_p->max) == 0)
-           bitmap_set_bit (to_remove, i);
-       }
-    }
-
-  bitmap_and_compl_into (vr_p->equiv, to_remove);
-  BITMAP_FREE (to_remove);
-}
-
-
 /* Extract value range information from an ASSERT_EXPR EXPR and store
    it in *VR_P.  */
 
@@ -1056,7 +976,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
       || var_vr->type == VR_UNDEFINED
       || symbolic_range_p (vr_p)
       || symbolic_range_p (var_vr))
-    goto done;
+    return;
 
   if (var_vr->type == VR_RANGE && vr_p->type == VR_RANGE)
     {
@@ -1191,11 +1111,6 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
            }
        }
     }
-
-  /* Remove names from the equivalence set that have ranges
-     incompatible with VR_P.  */
-done:
-  fix_equivalence_set (vr_p);
 }
 
 
@@ -2438,6 +2353,7 @@ void
 debug_value_range (value_range_t *vr)
 {
   dump_value_range (stderr, vr);
+  fprintf (stderr, "\n");
 }
 
 
@@ -3555,8 +3471,16 @@ compare_name_with_value (enum tree_code comp, tree var, tree val)
       t = compare_range_with_value (comp, &equiv_vr, val);
       if (t)
        {
-         /* All the ranges should compare the same against VAL.  */
-         gcc_assert (retval == NULL || t == retval);
+         /* If we get different answers from different members
+            of the equivalence set this check must be in a dead
+            code region.  Folding it to a trap representation
+            would be correct here.  For now just return don't-know.  */
+         if (retval != NULL
+             && t != retval)
+           {
+             retval = NULL_TREE;
+             break;
+           }
          retval = t;
        }
     }
@@ -3638,9 +3562,17 @@ compare_names (enum tree_code comp, tree n1, tree n2)
          t = compare_ranges (comp, &vr1, &vr2);
          if (t)
            {
-             /* All the ranges in the equivalent sets should compare
-                the same.  */
-             gcc_assert (retval == NULL || t == retval);
+             /* If we get different answers from different members
+                of the equivalence set this check must be in a dead
+                code region.  Folding it to a trap representation
+                would be correct here.  For now just return don't-know.  */
+             if (retval != NULL
+                 && t != retval)
+               {
+                 bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
+                 bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
+                 return NULL_TREE;
+               }
              retval = t;
            }
        }