cmp = compare_values (min, max);
gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
+
+ if (needs_overflow_infinity (TREE_TYPE (min)))
+ gcc_assert (!is_overflow_infinity (min)
+ || !is_overflow_infinity (max));
}
if (t == VR_UNDEFINED || t == VR_VARYING)
bitmap_clear (vr->equiv);
}
+/* Set value range VR to a single value. This function is only called
+ with values we get from statements, and exists to clear the
+ TREE_OVERFLOW flag so that we don't think we have an overflow
+ infinity when we shouldn't. */
+
+static inline void
+set_value_range_to_value (value_range_t *vr, tree val)
+{
+ gcc_assert (is_gimple_min_invariant (val));
+ if (is_overflow_infinity (val))
+ {
+ val = copy_node (val);
+ TREE_OVERFLOW (val) = 0;
+ }
+ set_value_range (vr, VR_RANGE, val, val, NULL);
+}
+
/* Set value range VR to a non-negative range of type TYPE.
OVERFLOW_INFINITY indicates whether to use a overflow infinity
rather than TYPE_MAX_VALUE; this should be true if we determine
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0));
else if (is_gimple_min_invariant (op0))
- set_value_range (&vr0, VR_RANGE, op0, op0, NULL);
+ set_value_range_to_value (&vr0, op0);
else
set_value_range_to_varying (&vr0);
if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1));
else if (is_gimple_min_invariant (op1))
- set_value_range (&vr1, VR_RANGE, op1, op1, NULL);
+ set_value_range_to_value (&vr1, op1);
else
set_value_range_to_varying (&vr1);
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0));
else if (is_gimple_min_invariant (op0))
- set_value_range (&vr0, VR_RANGE, op0, op0, NULL);
+ set_value_range_to_value (&vr0, op0);
else
set_value_range_to_varying (&vr0);
min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
else if (needs_overflow_infinity (TREE_TYPE (expr)))
{
- if (supports_overflow_infinity (TREE_TYPE (expr)))
+ if (supports_overflow_infinity (TREE_TYPE (expr))
+ && !is_overflow_infinity (vr0.min)
+ && vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr)))
min = positive_overflow_infinity (TREE_TYPE (expr));
else
{
if (needs_overflow_infinity (TREE_TYPE (expr)))
{
gcc_assert (code != NEGATE_EXPR && code != ABS_EXPR);
+
+ /* If both sides have overflowed, we don't know
+ anything. */
+ if ((is_overflow_infinity (vr0.min)
+ || TREE_OVERFLOW (min))
+ && (is_overflow_infinity (vr0.max)
+ || TREE_OVERFLOW (max)))
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+
if (is_overflow_infinity (vr0.min))
min = vr0.min;
else if (TREE_OVERFLOW (min))
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0));
else if (is_gimple_min_invariant (op0))
- set_value_range (&vr0, VR_RANGE, op0, op0, NULL);
+ set_value_range_to_value (&vr0, op0);
else
set_value_range_to_varying (&vr0);
if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1));
else if (is_gimple_min_invariant (op1))
- set_value_range (&vr1, VR_RANGE, op1, op1, NULL);
+ set_value_range_to_value (&vr1, op1);
else
set_value_range_to_varying (&vr1);
else if (TREE_CODE_CLASS (code) == tcc_comparison)
extract_range_from_comparison (vr, expr);
else if (is_gimple_min_invariant (expr))
- set_value_range (vr, VR_RANGE, expr, expr, NULL);
+ set_value_range_to_value (vr, expr);
else
set_value_range_to_varying (vr);
else
goto give_up;
+ /* Check for useless ranges. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (min))
+ && ((min == TYPE_MIN_VALUE (TREE_TYPE (min))
+ || is_overflow_infinity (min))
+ && (max == TYPE_MAX_VALUE (TREE_TYPE (max))
+ || is_overflow_infinity (max))))
+ goto give_up;
+
/* The resulting set of equivalences is the intersection of
the two sets. */
if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
}
else
{
+ if (is_overflow_infinity (arg))
+ {
+ arg = copy_node (arg);
+ TREE_OVERFLOW (arg) = 0;
+ }
+
vr_arg.type = VR_RANGE;
vr_arg.min = arg;
vr_arg.max = arg;