------- Comment #8 from ian at airs dot com 2007-04-11 08:04 ------- That's not an infinite loop, it's just a loop with 2^31 iterations.
This patch takes a rather different approach. Index: tree-vrp.c =================================================================== --- tree-vrp.c (revision 123521) +++ tree-vrp.c (working copy) @@ -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_counts; + /* Return whether TYPE should use an overflow infinity distinct from TYPE_{MIN,MAX}_VALUE. We use an overflow infinity value to @@ -4306,6 +4311,7 @@ vrp_initialize (void) basic_block bb; vr_value = XCNEWVEC (value_range_t *, num_ssa_names); + vr_counts = XCNEWVEC (int, num_ssa_names); FOR_EACH_BB (bb) { @@ -5059,7 +5065,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); @@ -5069,6 +5075,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); @@ -5086,10 +5093,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 { @@ -5115,6 +5123,9 @@ vrp_visit_phi_node (tree phi) } } + old_edges = vr_counts[SSA_NAME_VERSION (lhs)]; + vr_counts[SSA_NAME_VERSION (lhs)] = edges; + if (vr_result.type == VR_VARYING) goto varying; @@ -5122,7 +5133,7 @@ vrp_visit_phi_node (tree phi) when the new value is slightly bigger or smaller than the previous one. */ if (lhs_vr->type == VR_RANGE && vr_result.type == VR_RANGE - && !all_const) + && edges <= old_edges) { if (!POINTER_TYPE_P (TREE_TYPE (lhs))) { -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31522