tree-vrp.c (adjust_range_with_scev): When loop is not expected to overflow, reduce overflow infinity to regular infinity.

./:	* tree-vrp.c (adjust_range_with_scev): When loop is not expected
	to overflow, reduce overflow infinity to regular infinity.
	(vrp_var_may_overflow): New static function.
	(vrp_visit_phi_node): Check vrp_var_may_overflow.
testsuite/:
	* gcc.dg/Wstrict-overflow-18.c: New test.

From-SVN: r125319
This commit is contained in:
Ian Lance Taylor 2007-06-04 21:56:10 +00:00 committed by Ian Lance Taylor
parent b9d493510e
commit 9a46cc164c
4 changed files with 92 additions and 2 deletions

View File

@ -1,3 +1,10 @@
2007-06-04 Ian Lance Taylor <iant@google.com>
* tree-vrp.c (adjust_range_with_scev): When loop is not expected
to overflow, reduce overflow infinity to regular infinity.
(vrp_var_may_overflow): New static function.
(vrp_visit_phi_node): Check vrp_var_may_overflow.
2007-06-04 Kazu Hirata <kazu@codesourcery.com>
* stor-layout.c (layout_type): Remove duplicate code.

View File

@ -1,3 +1,7 @@
2007-06-04 Ian Lance Taylor <iant@google.com>
* gcc.dg/Wstrict-overflow-18.c: New test.
2007-06-04 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR testsuite/25241

View File

@ -0,0 +1,22 @@
/* { dg-do compile } */
/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow" } */
/* Don't warn about an overflow when folding i > 0. The loop analysis
should determine that i does not wrap. */
struct c { unsigned int a; unsigned int b; };
extern void bar (struct c *);
int
foo (struct c *p)
{
int i;
int sum = 0;
for (i = 0; i < p->a - p->b; ++i)
{
if (i > 0)
sum += 2;
bar (p);
}
return sum;
}

View File

@ -2695,6 +2695,13 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
if (compare_values (min, max) == 1)
return;
}
/* According to the loop information, the variable does not
overflow. If we think it does, probably because of an
overflow due to arithmetic on a different INF value,
reset now. */
if (is_negative_overflow_infinity (min))
min = tmin;
}
else
{
@ -2707,12 +2714,60 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
if (compare_values (min, max) == 1)
return;
}
if (is_positive_overflow_infinity (max))
max = tmax;
}
set_value_range (vr, VR_RANGE, min, max, vr->equiv);
}
}
/* Return true if VAR may overflow at STMT. This checks any available
loop information to see if we can determine that VAR does not
overflow. */
static bool
vrp_var_may_overflow (tree var, tree stmt)
{
struct loop *l;
tree chrec, init, step;
if (current_loops == NULL)
return true;
l = loop_containing_stmt (stmt);
if (l == NULL)
return true;
chrec = instantiate_parameters (l, analyze_scalar_evolution (l, var));
if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
return true;
init = initial_condition_in_loop_num (chrec, l->num);
step = evolution_part_in_loop_num (chrec, l->num);
if (step == NULL_TREE
|| !is_gimple_min_invariant (step)
|| !valid_value_p (init))
return true;
/* If we get here, we know something useful about VAR based on the
loop information. If it wraps, it may overflow. */
if (scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
true))
return true;
if (dump_file && (dump_flags & TDF_DETAILS) != 0)
{
print_generic_expr (dump_file, var, 0);
fprintf (dump_file, ": loop information indicates does not overflow\n");
}
return false;
}
/* Given two numeric value ranges VR0, VR1 and a comparison code COMP:
@ -5391,7 +5446,8 @@ vrp_visit_phi_node (tree phi)
if (vrp_val_is_max (vr_result.max))
goto varying;
if (!needs_overflow_infinity (TREE_TYPE (vr_result.min)))
if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))
|| !vrp_var_may_overflow (lhs, phi))
vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min));
else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
vr_result.min =
@ -5409,7 +5465,8 @@ vrp_visit_phi_node (tree phi)
if (vrp_val_is_min (vr_result.min))
goto varying;
if (!needs_overflow_infinity (TREE_TYPE (vr_result.max)))
if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))
|| !vrp_var_may_overflow (lhs, phi))
vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max));
else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
vr_result.max =