From 79f0a894fe4f1b4c71b145e73e0eb539e1429a3d Mon Sep 17 00:00:00 2001 From: rguenth Date: Fri, 13 Oct 2006 20:09:10 +0000 Subject: [PATCH] 2006-10-13 Richard Guenther 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117705 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 +++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/torture/pr29446.c | 32 +++++++++ gcc/tree-vrp.c | 114 +++++++-------------------------- 4 files changed, 70 insertions(+), 91 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr29446.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bbea7ce9a78..d242366e058 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2006-10-13 Richard Guenther + + 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 * doc/install.texi (*-ibm-aix*): Add comment about 32-bit GMP diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b18ddd97dbb..5e90addb26b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-10-13 Richard Guenther + + PR tree-optimization/29446 + * gcc.dg/torture/pr29446.c: New testcase. + 2006-10-13 Bill Wendling * 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 00000000000..5571c71e82a --- /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 4a30e4ee8a5..8e67e8a3d2b 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 , 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 - if (count_19 > 63) - { - count_18 = ASSERT_EXPR 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; } } -- 2.11.0