aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2006-10-13 20:09:10 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2006-10-13 20:09:10 +0000
commit96644abaa5e60670b8f3801faba6694b2866b93a (patch)
treea9303b29ceddb34952d7b02a412ec28a7fc868d1
parent4010308ce53f36930935a230441630c8f5e79b86 (diff)
downloadgcc-96644abaa5e60670b8f3801faba6694b2866b93a.zip
gcc-96644abaa5e60670b8f3801faba6694b2866b93a.tar.gz
gcc-96644abaa5e60670b8f3801faba6694b2866b93a.tar.bz2
re PR tree-optimization/29446 (VRP ICE in compare_names)
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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr29446.c32
-rw-r--r--gcc/tree-vrp.c114
4 files changed, 70 insertions, 91 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bbea7ce..d242366 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b18ddd9..5e90add 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..5571c71
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr29446.c
@@ -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;
+ }
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 4a30e4e..8e67e8a 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -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;
}
}