From fc6827fe9fe4d3c72013462bf2d9d658bf73d7bb Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 17 Apr 2007 05:33:38 +0000 Subject: 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 --- gcc/ChangeLog | 7 +++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/Wstrict-overflow-16.c | 11 +++++++++++ gcc/tree-vrp.c | 23 +++++++++++++++++++---- 4 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wstrict-overflow-16.c (limited to 'gcc') 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 + 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 + + PR tree-optimization/31522 + * gcc.dg/Wstrict-overflow-16.c: New test. + 2007-04-17 Kazu Hirata * 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; } -- cgit v1.1