aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@gcc.gnu.org>2014-11-20 22:25:35 +0000
committerPatrick Palka <ppalka@gcc.gnu.org>2014-11-20 22:25:35 +0000
commit7ac753f9683133e7b91f2d497ab6b25418a05c5d (patch)
tree50fdade7d7ba6205c00a1d0613c261fa0f192e1f /gcc
parent75bda2e8134c013bc3d02b78e5b8b34022961985 (diff)
downloadgcc-7ac753f9683133e7b91f2d497ab6b25418a05c5d.zip
gcc-7ac753f9683133e7b91f2d497ab6b25418a05c5d.tar.gz
gcc-7ac753f9683133e7b91f2d497ab6b25418a05c5d.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/no-strict-overflow-8.c25
-rw-r--r--gcc/tree-vrp.c57
4 files changed, 87 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 394ae4f..4501014 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+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>
* tree-ssa-loop-niter.c (maybe_lower_iteration_bound): Fix typo.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4aba5fb..882e2ac 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+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>
* gcc.dg/undefined-loop-1.c: New file.
diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-8.c b/gcc/testsuite/gcc.dg/no-strict-overflow-8.c
new file mode 100644
index 0000000..11ef935
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/no-strict-overflow-8.c
@@ -0,0 +1,25 @@
+/* { 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" } } */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index bcf4c2b..a75138f 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -9117,11 +9117,15 @@ simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
a known value range VR.
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
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 max = NULL;
@@ -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,
return that value. */
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;
}
@@ -9252,9 +9265,12 @@ simplify_cond_using_ranges (gcond *stmt)
able to simplify this conditional. */
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)
{
@@ -9275,16 +9291,30 @@ simplify_cond_using_ranges (gcond *stmt)
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;
}
/* Try again after inverting the condition. We only deal
with integral types here, so no need to worry about
issues with inverting FP comparisons. */
- cond_code = invert_tree_comparison (cond_code, false);
- new_tree = test_for_singularity (cond_code, op0, op1, vr);
+ sop = false;
+ 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)
{
@@ -9305,6 +9335,17 @@ simplify_cond_using_ranges (gcond *stmt)
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;
}
}