aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-04-17 05:33:38 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2007-04-17 05:33:38 +0000
commitfc6827fe9fe4d3c72013462bf2d9d658bf73d7bb (patch)
tree260efc901363034c740d1c84a2d888987c09e4ec /gcc
parent4075e2319853586499e3d059ff514151deca2396 (diff)
downloadgcc-fc6827fe9fe4d3c72013462bf2d9d658bf73d7bb.zip
gcc-fc6827fe9fe4d3c72013462bf2d9d658bf73d7bb.tar.gz
gcc-fc6827fe9fe4d3c72013462bf2d9d658bf73d7bb.tar.bz2
re PR tree-optimization/31522 (False overflow warning with phi nodes)
./: PR tree-optimization/31522 * tree-vrp.c (vr_phi_edge_counts): New static variable. (vrp_initialize): Allocate vr_phi_edge_counts. (vrp_visit_phi_node): Don't push to infinity if we saw a new executable edge. Drop test for all constants. (vrp_finalize): Free vrp_phi_edge_counts. testsuite/: PR tree-optimization/31522 * gcc.dg/Wstrict-overflow-16.c: New test. From-SVN: r123908
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-overflow-16.c11
-rw-r--r--gcc/tree-vrp.c23
4 files changed, 42 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5ff8fab..2003af8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2007-04-16 Ian Lance Taylor <iant@google.com>
+ PR tree-optimization/31522
+ * tree-vrp.c (vr_phi_edge_counts): New static variable.
+ (vrp_initialize): Allocate vr_phi_edge_counts.
+ (vrp_visit_phi_node): Don't push to infinity if we saw a new
+ executable edge. Drop test for all constants.
+ (vrp_finalize): Free vrp_phi_edge_counts.
+
* doc/cpp.texi (Common Predefined Macros): Clarify description of
__GNUC_GNU_INLINE__ and __GNUC_STDC_INLINE__.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 82ea641..ea93fcc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-04-16 Ian Lance Taylor <iant@google.com>
+
+ PR tree-optimization/31522
+ * gcc.dg/Wstrict-overflow-16.c: New test.
+
2007-04-17 Kazu Hirata <kazu@codesourcery.com>
* gcc.dg/cpp/_Pragma6.c: Skip on fido-*-* and m68k-*-*.
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-16.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-16.c
new file mode 100644
index 0000000..e8c31cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-overflow-16.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow" } */
+
+/* From PR 31522. */
+
+int f (int x) {
+ int y;
+ if (x <= 4) y = 1;
+ else y = x / 4;
+ return y <= 0;
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index ff07939..43cd0eb 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -95,6 +95,11 @@ static sbitmap blocks_visited;
of values that SSA name N_I may take. */
static value_range_t **vr_value;
+/* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
+ number of executable edges we saw the last time we visited the
+ node. */
+static int *vr_phi_edge_counts;
+
/* Return whether TYPE should use an overflow infinity distinct from
TYPE_{MIN,MAX}_VALUE. We use an overflow infinity value to
@@ -4433,6 +4438,7 @@ vrp_initialize (void)
basic_block bb;
vr_value = XCNEWVEC (value_range_t *, num_ssa_names);
+ vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
FOR_EACH_BB (bb)
{
@@ -5185,7 +5191,7 @@ vrp_visit_phi_node (tree phi)
tree lhs = PHI_RESULT (phi);
value_range_t *lhs_vr = get_value_range (lhs);
value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
- bool all_const = true;
+ int edges, old_edges;
copy_value_range (&vr_result, lhs_vr);
@@ -5195,6 +5201,7 @@ vrp_visit_phi_node (tree phi)
print_generic_expr (dump_file, phi, dump_flags);
}
+ edges = 0;
for (i = 0; i < PHI_NUM_ARGS (phi); i++)
{
edge e = PHI_ARG_EDGE (phi, i);
@@ -5212,10 +5219,11 @@ vrp_visit_phi_node (tree phi)
tree arg = PHI_ARG_DEF (phi, i);
value_range_t vr_arg;
+ ++edges;
+
if (TREE_CODE (arg) == SSA_NAME)
{
vr_arg = *(get_value_range (arg));
- all_const = false;
}
else
{
@@ -5244,11 +5252,16 @@ vrp_visit_phi_node (tree phi)
if (vr_result.type == VR_VARYING)
goto varying;
+ old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)];
+ vr_phi_edge_counts[SSA_NAME_VERSION (lhs)] = edges;
+
/* To prevent infinite iterations in the algorithm, derive ranges
when the new value is slightly bigger or smaller than the
- previous one. */
+ previous one. We don't do this if we have seen a new executable
+ edge; this helps us avoid an overflow infinity for conditionals
+ which are not in a loop. */
if (lhs_vr->type == VR_RANGE && vr_result.type == VR_RANGE
- && !all_const)
+ && edges <= old_edges)
{
if (!POINTER_TYPE_P (TREE_TYPE (lhs)))
{
@@ -5827,10 +5840,12 @@ vrp_finalize (void)
free (single_val_range);
free (vr_value);
+ free (vr_phi_edge_counts);
/* So that we can distinguish between VRP data being available
and not available. */
vr_value = NULL;
+ vr_phi_edge_counts = NULL;
}