diff options
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index cb43430ecb1..b0f6c78d734 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -8810,20 +8810,11 @@ vrp_visit_phi_node (gphi *phi) /* If we dropped either bound to +-INF then if this is a loop PHI node SCEV may known more about its value-range. */ - if ((cmp_min > 0 || cmp_min < 0 + if (cmp_min > 0 || cmp_min < 0 || cmp_max < 0 || cmp_max > 0) - && (l = loop_containing_stmt (phi)) - && l->header == gimple_bb (phi)) - adjust_range_with_scev (&vr_result, l, phi, lhs); - - /* If we will end up with a (-INF, +INF) range, set it to - VARYING. Same if the previous max value was invalid for - the type and we end up with vr_result.min > vr_result.max. */ - if ((vrp_val_is_max (vr_result.max) - && vrp_val_is_min (vr_result.min)) - || compare_values (vr_result.min, - vr_result.max) > 0) - goto varying; + goto scev_check; + + goto infinite_check; } /* If the new range is different than the previous value, keep @@ -8849,8 +8840,28 @@ update_range: /* Nothing changed, don't add outgoing edges. */ return SSA_PROP_NOT_INTERESTING; - /* No match found. Set the LHS to VARYING. */ varying: + set_value_range_to_varying (&vr_result); + +scev_check: + /* If this is a loop PHI node SCEV may known more about its value-range. + scev_check can be reached from two paths, one is a fall through from above + "varying" label, the other is direct goto from code block which tries to + avoid infinite simulation. */ + if ((l = loop_containing_stmt (phi)) + && l->header == gimple_bb (phi)) + adjust_range_with_scev (&vr_result, l, phi, lhs); + +infinite_check: + /* If we will end up with a (-INF, +INF) range, set it to + VARYING. Same if the previous max value was invalid for + the type and we end up with vr_result.min > vr_result.max. */ + if ((vr_result.type == VR_RANGE || vr_result.type == VR_ANTI_RANGE) + && !((vrp_val_is_max (vr_result.max) && vrp_val_is_min (vr_result.min)) + || compare_values (vr_result.min, vr_result.max) > 0)) + goto update_range; + + /* No match found. Set the LHS to VARYING. */ set_value_range_to_varying (lhs_vr); return SSA_PROP_VARYING; } |