summaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-13 20:09:10 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-13 20:09:10 +0000
commit79f0a894fe4f1b4c71b145e73e0eb539e1429a3d (patch)
treea9303b29ceddb34952d7b02a412ec28a7fc868d1 /gcc/tree-vrp.c
parentbd73b22890e7fc448463453750725dcc302c5e11 (diff)
downloadgcc-79f0a894fe4f1b4c71b145e73e0eb539e1429a3d.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117705 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c114
1 files changed, 23 insertions, 91 deletions
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 <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;
}
}