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:
parent
b9d493510e
commit
9a46cc164c
4 changed files with 92 additions and 2 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
22
gcc/testsuite/gcc.dg/Wstrict-overflow-18.c
Normal file
22
gcc/testsuite/gcc.dg/Wstrict-overflow-18.c
Normal 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;
|
||||
}
|
|
@ -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 =
|
||||
|
|
Loading…
Add table
Reference in a new issue