re PR tree-optimization/31605 (VRP eliminates a useful test due with conversion from unsigned int to int)
./: PR tree-optimization/31605 * tree-vrp.c (set_value_range): Check that min and max are not both overflow infinities. (set_value_range_to_value): New static function. (extract_range_from_binary_expr): Call set_value_range_to_value. (extract_range_from_cond_expr): Likewise. (extract_range_from_expr): Likewise. (extract_range_from_unary_expr): Likewise. Don't create a range which overflows on both sides. (vrp_meet): Check for a useless range. (vrp_visit_phi_node): If we see a constant which looks like an overflow infinity, turn off the TREE_OVERFLOW flag. testsuite/: PR tree-optimizatoin/31605 * gcc.c-torture/execute/pr31605.c: New test. From-SVN: r124128
This commit is contained in:
parent
1e9ecf6da4
commit
8cf781f088
@ -1,3 +1,18 @@
|
||||
2007-04-24 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
PR tree-optimization/31605
|
||||
* tree-vrp.c (set_value_range): Check that min and max are not
|
||||
both overflow infinities.
|
||||
(set_value_range_to_value): New static function.
|
||||
(extract_range_from_binary_expr): Call set_value_range_to_value.
|
||||
(extract_range_from_cond_expr): Likewise.
|
||||
(extract_range_from_expr): Likewise.
|
||||
(extract_range_from_unary_expr): Likewise. Don't create a range
|
||||
which overflows on both sides.
|
||||
(vrp_meet): Check for a useless range.
|
||||
(vrp_visit_phi_node): If we see a constant which looks like an
|
||||
overflow infinity, turn off the TREE_OVERFLOW flag.
|
||||
|
||||
2007-04-24 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* flow.c (elim_reg_cond): Handle a comparison of a subreg.
|
||||
|
@ -1,3 +1,8 @@
|
||||
2007-04-24 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
PR tree-optimizatoin/31605
|
||||
* gcc.c-torture/execute/pr31605.c: New test.
|
||||
|
||||
2007-04-24 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
|
||||
|
||||
PR fortran/31587
|
||||
|
13
gcc/testsuite/gcc.c-torture/execute/pr31605.c
Normal file
13
gcc/testsuite/gcc.c-torture/execute/pr31605.c
Normal file
@ -0,0 +1,13 @@
|
||||
void put_field (unsigned int start, unsigned int len)
|
||||
{
|
||||
int cur_bitshift = ((start + len) % 8) - 8;
|
||||
if (cur_bitshift > -8)
|
||||
exit (0);
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
put_field (0, 1);
|
||||
abort ();
|
||||
}
|
@ -272,6 +272,10 @@ set_value_range (value_range_t *vr, enum value_range_type t, tree min,
|
||||
|
||||
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)
|
||||
@ -320,6 +324,23 @@ set_value_range_to_varying (value_range_t *vr)
|
||||
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
|
||||
@ -1646,7 +1667,7 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
|
||||
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);
|
||||
|
||||
@ -1654,7 +1675,7 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
|
||||
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);
|
||||
|
||||
@ -2053,7 +2074,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
|
||||
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);
|
||||
|
||||
@ -2185,7 +2206,9 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
|
||||
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
|
||||
{
|
||||
@ -2361,6 +2384,18 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
|
||||
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))
|
||||
@ -2422,7 +2457,7 @@ extract_range_from_cond_expr (value_range_t *vr, tree expr)
|
||||
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);
|
||||
|
||||
@ -2430,7 +2465,7 @@ extract_range_from_cond_expr (value_range_t *vr, tree expr)
|
||||
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);
|
||||
|
||||
@ -2494,7 +2529,7 @@ extract_range_from_expr (value_range_t *vr, tree expr)
|
||||
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);
|
||||
|
||||
@ -5106,6 +5141,14 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
|
||||
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)
|
||||
@ -5235,6 +5278,12 @@ vrp_visit_phi_node (tree phi)
|
||||
}
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user