Commit 7ac753f9 by Patrick Palka

Disable an unsafe VRP transformation when -fno-strict-overflow is set

gcc/
	* tree-vrp.c (test_for_singularity): New parameter
	strict_overflow_p.  Set *strict_overflow_p to true if signed
	overflow must be undefined for the return value to satisfy the
	conditional.
	(simplify_cond_using_ranges): Don't perform the simplification
	if it violates overflow rules.

gcc/testsuite/
	* gcc.dg/no-strict-overflow-8.c: New test.

From-SVN: r217895
parent 75bda2e8
2014-11-20 Patrick Palka <ppalka@gcc.gnu.org>
* tree-vrp.c (test_for_singularity): New parameter
strict_overflow_p. Set *strict_overflow_p to true if signed
overflow must be undefined for the return value to satisfy the
conditional.
(simplify_cond_using_ranges): Don't perform the simplification
if it violates overflow rules.
2014-11-20 Marek Polacek <polacek@redhat.com> 2014-11-20 Marek Polacek <polacek@redhat.com>
* tree-ssa-loop-niter.c (maybe_lower_iteration_bound): Fix typo. * tree-ssa-loop-niter.c (maybe_lower_iteration_bound): Fix typo.
2014-11-20 Patrick Palka <ppalka@gcc.gnu.org>
* gcc.dg/no-strict-overflow-8.c: New test.
2014-11-20 Andrew Stubbs <ams@codesourcery.com> 2014-11-20 Andrew Stubbs <ams@codesourcery.com>
* gcc.dg/undefined-loop-1.c: New file. * gcc.dg/undefined-loop-1.c: New file.
......
/* { dg-do compile } */
/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-optimized" } */
/* We cannot fold i > 0 because p->a - p->b can be larger than INT_MAX
and thus i can wrap. Dual of Wstrict-overflow-18.c */
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;
}
/* { dg-final { scan-tree-dump "i_.* > 0" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
...@@ -9117,11 +9117,15 @@ simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt) ...@@ -9117,11 +9117,15 @@ simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
a known value range VR. a known value range VR.
If there is one and only one value which will satisfy the If there is one and only one value which will satisfy the
conditional, then return that value. Else return NULL. */ conditional, then return that value. Else return NULL.
If signed overflow must be undefined for the value to satisfy
the conditional, then set *STRICT_OVERFLOW_P to true. */
static tree static tree
test_for_singularity (enum tree_code cond_code, tree op0, test_for_singularity (enum tree_code cond_code, tree op0,
tree op1, value_range_t *vr) tree op1, value_range_t *vr,
bool *strict_overflow_p)
{ {
tree min = NULL; tree min = NULL;
tree max = NULL; tree max = NULL;
...@@ -9172,7 +9176,16 @@ test_for_singularity (enum tree_code cond_code, tree op0, ...@@ -9172,7 +9176,16 @@ test_for_singularity (enum tree_code cond_code, tree op0,
then there is only one value which can satisfy the condition, then there is only one value which can satisfy the condition,
return that value. */ return that value. */
if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min)) if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min))
return min; {
if ((cond_code == LE_EXPR || cond_code == LT_EXPR)
&& is_overflow_infinity (vr->max))
*strict_overflow_p = true;
if ((cond_code == GE_EXPR || cond_code == GT_EXPR)
&& is_overflow_infinity (vr->min))
*strict_overflow_p = true;
return min;
}
} }
return NULL; return NULL;
} }
...@@ -9252,9 +9265,12 @@ simplify_cond_using_ranges (gcond *stmt) ...@@ -9252,9 +9265,12 @@ simplify_cond_using_ranges (gcond *stmt)
able to simplify this conditional. */ able to simplify this conditional. */
if (vr->type == VR_RANGE) if (vr->type == VR_RANGE)
{ {
tree new_tree = test_for_singularity (cond_code, op0, op1, vr); enum warn_strict_overflow_code wc = WARN_STRICT_OVERFLOW_COMPARISON;
bool sop = false;
tree new_tree = test_for_singularity (cond_code, op0, op1, vr, &sop);
if (new_tree) if (new_tree
&& (!sop || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0))))
{ {
if (dump_file) if (dump_file)
{ {
...@@ -9275,16 +9291,30 @@ simplify_cond_using_ranges (gcond *stmt) ...@@ -9275,16 +9291,30 @@ simplify_cond_using_ranges (gcond *stmt)
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
if (sop && issue_strict_overflow_warning (wc))
{
location_t location = input_location;
if (gimple_has_location (stmt))
location = gimple_location (stmt);
warning_at (location, OPT_Wstrict_overflow,
"assuming signed overflow does not occur when "
"simplifying conditional");
}
return true; return true;
} }
/* Try again after inverting the condition. We only deal /* Try again after inverting the condition. We only deal
with integral types here, so no need to worry about with integral types here, so no need to worry about
issues with inverting FP comparisons. */ issues with inverting FP comparisons. */
cond_code = invert_tree_comparison (cond_code, false); sop = false;
new_tree = test_for_singularity (cond_code, op0, op1, vr); new_tree = test_for_singularity
(invert_tree_comparison (cond_code, false),
op0, op1, vr, &sop);
if (new_tree) if (new_tree
&& (!sop || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0))))
{ {
if (dump_file) if (dump_file)
{ {
...@@ -9305,6 +9335,17 @@ simplify_cond_using_ranges (gcond *stmt) ...@@ -9305,6 +9335,17 @@ simplify_cond_using_ranges (gcond *stmt)
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
if (sop && issue_strict_overflow_warning (wc))
{
location_t location = input_location;
if (gimple_has_location (stmt))
location = gimple_location (stmt);
warning_at (location, OPT_Wstrict_overflow,
"assuming signed overflow does not occur when "
"simplifying conditional");
}
return true; return true;
} }
} }
......
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