}
-/* 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. */
|| 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)
{
}
}
}
-
- /* Remove names from the equivalence set that have ranges
- incompatible with VR_P. */
-done:
- fix_equivalence_set (vr_p);
}
debug_value_range (value_range_t *vr)
{
dump_value_range (stderr, vr);
+ fprintf (stderr, "\n");
}
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;
}
}
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;
}
}