Commit cf35667e by Richard Guenther Committed by Richard Biener

tree-vrp.c (vrp_meet): Properly meet equivalent ranges.

2012-06-13  Richard Guenther  <rguenther@suse.de>

	* tree-vrp.c (vrp_meet): Properly meet equivalent ranges.
	Handle meeting two VR_RANGE to an VR_ANTI_RANGE.  Implement
	all possible meetings of VR_RANGE with VR_ANTI_RANGE and
	VR_ANTI_RANGE with VR_ANTI_RANGE.

From-SVN: r188517
parent 31e3bc1b
2012-06-13 Richard Guenther <rguenther@suse.de>
* tree-vrp.c (vrp_meet): Properly meet equivalent ranges.
Handle meeting two VR_RANGE to an VR_ANTI_RANGE. Implement
all possible meetings of VR_RANGE with VR_ANTI_RANGE and
VR_ANTI_RANGE with VR_ANTI_RANGE.
2012-06-13 Richard Earnshaw <rearnsha@arm.com> 2012-06-13 Richard Earnshaw <rearnsha@arm.com>
* config.gcc (unsupported): Move obsoleted FPA-based configurations * config.gcc (unsupported): Move obsoleted FPA-based configurations
......
...@@ -6914,14 +6914,44 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1) ...@@ -6914,14 +6914,44 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
return; return;
} }
if (vr0->type == VR_RANGE && vr1->type == VR_RANGE) if (vr0->type == vr1->type
&& compare_values (vr0->min, vr1->min) == 0
&& compare_values (vr0->max, vr1->max) == 0)
{
/* If the value-ranges are identical just insersect
their equivalencies. */
}
else if (vr0->type == VR_RANGE && vr1->type == VR_RANGE)
{ {
int cmp; int cmp;
tree min, max; tree min, max;
/* Compute the convex hull of the ranges. The lower limit of /* If the two ranges represent an anti-range produce a
VR_RANGE with swapped min/max and let the range canonicalization
fix things up. */
if (vrp_val_is_min (vr0->min) && !is_overflow_infinity (vr0->min)
&& vrp_val_is_max (vr1->max) && !is_overflow_infinity (vr1->max)
&& TREE_CODE (vr1->min) == INTEGER_CST
&& TREE_CODE (vr0->max) == INTEGER_CST
&& compare_values (vr0->max, vr1->min) == -1)
{
min = vr1->min;
max = vr0->max;
}
else if (vrp_val_is_min (vr1->min) && !is_overflow_infinity (vr1->min)
&& vrp_val_is_max (vr0->max) && !is_overflow_infinity (vr0->max)
&& TREE_CODE (vr1->max) == INTEGER_CST
&& TREE_CODE (vr0->min) == INTEGER_CST
&& compare_values (vr1->max, vr0->min) == -1)
{
max = vr1->max;
min = vr0->min;
}
/* Otherwise compute the convex hull of the ranges. The lower limit of
the new range is the minimum of the two ranges. If they the new range is the minimum of the two ranges. If they
cannot be compared, then give up. */ cannot be compared, then give up. */
else
{
cmp = compare_values (vr0->min, vr1->min); cmp = compare_values (vr0->min, vr1->min);
if (cmp == 0 || cmp == 1) if (cmp == 0 || cmp == 1)
min = vr1->min; min = vr1->min;
...@@ -6946,55 +6976,91 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1) ...@@ -6946,55 +6976,91 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
&& ((vrp_val_is_min (min) || is_overflow_infinity (min)) && ((vrp_val_is_min (min) || is_overflow_infinity (min))
&& (vrp_val_is_max (max) || is_overflow_infinity (max)))) && (vrp_val_is_max (max) || is_overflow_infinity (max))))
goto give_up; goto give_up;
}
/* The resulting set of equivalences is the intersection of set_and_canonicalize_value_range (vr0, vr0->type, min, max, vr0->equiv);
the two sets. */
if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
bitmap_and_into (vr0->equiv, vr1->equiv);
else if (vr0->equiv && !vr1->equiv)
bitmap_clear (vr0->equiv);
set_value_range (vr0, vr0->type, min, max, vr0->equiv);
} }
else if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE) else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
{ {
/* Two anti-ranges meet only if their complements intersect. if (symbolic_range_p (vr0)
Only handle the case of identical ranges. */ || symbolic_range_p (vr1))
if (compare_values (vr0->min, vr1->min) == 0 goto give_up;
&& compare_values (vr0->max, vr1->max) == 0
&& compare_values (vr0->min, vr0->max) == 0) /* [] is vr0, () is vr1 in the following classification comments. */
if (operand_less_p (vr0->max, vr1->min) == 1
|| operand_less_p (vr1->max, vr0->min) == 1)
{ {
/* The resulting set of equivalences is the intersection of /* [ ] ( ) or ( ) [ ]
the two sets. */ If the ranges have an empty intersection, result of the meet
if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv) operation is the anti-range or if both are anti-ranges
bitmap_and_into (vr0->equiv, vr1->equiv); it covers all. */
else if (vr0->equiv && !vr1->equiv) if (vr0->type == VR_ANTI_RANGE
bitmap_clear (vr0->equiv); && vr1->type == VR_ANTI_RANGE)
goto give_up;
else if (vr1->type == VR_ANTI_RANGE)
set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr0->equiv);
} }
else if (operand_less_p (vr1->max, vr0->max) == 1
&& operand_less_p (vr0->min, vr1->min) == 1)
{
/* [ ( ) ]
Arbitrarily choose the left or inner gap. */
if (vr0->type == VR_ANTI_RANGE
&& vr1->type == VR_ANTI_RANGE)
set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr0->equiv);
else if (vr0->type == VR_ANTI_RANGE)
set_and_canonicalize_value_range (vr0, vr0->type, vr0->min,
int_const_binop (MINUS_EXPR, vr1->min, integer_one_node),
vr0->equiv);
else else
goto give_up; goto give_up;
} }
else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE) else if (operand_less_p (vr0->max, vr1->max) == 1
&& operand_less_p (vr1->min, vr0->min) == 1)
{ {
/* For a numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4], /* ( [ ] )
only handle the case where the ranges have an empty intersection. Arbitrarily choose the left or inner gap. */
The result of the meet operation is the anti-range. */ if (vr0->type == VR_ANTI_RANGE
if (!symbolic_range_p (vr0) && vr1->type == VR_ANTI_RANGE)
&& !symbolic_range_p (vr1) /* Nothing to do. */;
&& !value_ranges_intersect_p (vr0, vr1)) else if (vr1->type == VR_ANTI_RANGE)
set_and_canonicalize_value_range (vr0, vr1->type, vr1->min,
int_const_binop (MINUS_EXPR, vr0->min, integer_one_node),
vr0->equiv);
else
goto give_up;
}
else if (operand_less_p (vr1->min, vr0->max) == 1
&& operand_less_p (vr0->max, vr1->max) == 1)
{ {
/* Copy most of VR1 into VR0. Don't copy VR1's equivalence /* [ ( ] ) */
set. We need to compute the intersection of the two if (vr0->type == VR_ANTI_RANGE
equivalence sets. */ && vr1->type == VR_ANTI_RANGE)
if (vr1->type == VR_ANTI_RANGE) set_value_range (vr0, vr0->type, vr1->min, vr0->max, vr0->equiv);
set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr0->equiv); else if (vr0->type == VR_ANTI_RANGE)
set_and_canonicalize_value_range (vr0, vr0->type, vr0->min,
/* The resulting set of equivalences is the intersection of int_const_binop (MINUS_EXPR, vr1->min, integer_one_node),
the two sets. */ vr0->equiv);
if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv) else
bitmap_and_into (vr0->equiv, vr1->equiv); set_and_canonicalize_value_range (vr0, vr1->type,
else if (vr0->equiv && !vr1->equiv) int_const_binop (PLUS_EXPR, vr0->max, integer_one_node),
bitmap_clear (vr0->equiv); vr1->max, vr0->equiv);
}
else if (operand_less_p (vr0->min, vr1->max) == 1
&& operand_less_p (vr1->max, vr0->max) == 1)
{
/* ( [ ) ] */
if (vr0->type == VR_ANTI_RANGE
&& vr1->type == VR_ANTI_RANGE)
set_value_range (vr0, vr1->type, vr0->min, vr1->max, vr0->equiv);
else if (vr0->type == VR_ANTI_RANGE)
set_and_canonicalize_value_range (vr0, vr0->type,
int_const_binop (PLUS_EXPR, vr1->max, integer_one_node),
vr0->max, vr0->equiv);
else
set_and_canonicalize_value_range (vr0, vr1->type, vr1->min,
int_const_binop (MINUS_EXPR, vr0->min, integer_one_node),
vr0->equiv);
} }
else else
goto give_up; goto give_up;
...@@ -7002,6 +7068,13 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1) ...@@ -7002,6 +7068,13 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
else else
gcc_unreachable (); gcc_unreachable ();
/* The resulting set of equivalences is always the intersection of
the two sets. Above we always left the equivalency set of vr0 as-is. */
if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
bitmap_and_into (vr0->equiv, vr1->equiv);
else if (vr0->equiv && !vr1->equiv)
bitmap_clear (vr0->equiv);
return; return;
give_up: give_up:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment