From 661d6efd62869911344c2d8bd57dd3ca8f4af1dc Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 17 Aug 2016 11:51:51 +0000 Subject: [PATCH] re PR tree-optimization/76490 (when use -O2 -fcheck-founds compiler appears to hang and consumes all memory) 2016-08-17 Richard Biener PR tree-optimization/76490 * tree-vrp.c (update_value_range): Preserve overflow infinities when intersecting with ranges from get_range_info. (operand_less_p): Handle overflow infinities correctly. (value_range_constant_singleton): Use vrp_operand_equal_p to handle overflow max/min correctly. (vrp_valueize): Likewise. (union_ranges): Likewise. (intersect_ranges): Likewise. (vrp_visit_phi_node): Improve iteration limitation to only apply when we'll possibly re-visit the PHI via a changed argument on the backedge. * gfortran.fortran-torture/compile/pr76490.f90: New testcase. * gcc.dg/pr52904.c: XFAIL. From-SVN: r239529 --- gcc/ChangeLog | 15 ++++++ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.dg/pr52904.c | 2 +- .../compile/pr76490.f90 | 23 ++++++++++ gcc/tree-vrp.c | 46 ++++++++++++------- 5 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 01ad7e28a79..5142c920e8e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2016-08-17 Richard Biener + + PR tree-optimization/76490 + * tree-vrp.c (update_value_range): Preserve overflow infinities + when intersecting with ranges from get_range_info. + (operand_less_p): Handle overflow infinities correctly. + (value_range_constant_singleton): Use vrp_operand_equal_p + to handle overflow max/min correctly. + (vrp_valueize): Likewise. + (union_ranges): Likewise. + (intersect_ranges): Likewise. + (vrp_visit_phi_node): Improve iteration limitation to only + apply when we'll possibly re-visit the PHI via a changed argument + on the backedge. + 2016-08-17 Thomas Preud'homme * config/arm/t-aprofile (MULTILIB_EXCEPTIONS): Rewrite into ... diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ffa81389d16..ed2ce1c12b3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-08-17 Richard Biener + + PR tree-optimization/76490 + * gfortran.fortran-torture/compile/pr76490.f90: New testcase. + * gcc.dg/pr52904.c: XFAIL. + 2016-08-17 Richard Biener PR tree-optimization/23855 diff --git a/gcc/testsuite/gcc.dg/pr52904.c b/gcc/testsuite/gcc.dg/pr52904.c index 107d89ee7d3..2818c247b0a 100644 --- a/gcc/testsuite/gcc.dg/pr52904.c +++ b/gcc/testsuite/gcc.dg/pr52904.c @@ -14,7 +14,7 @@ wait_reading_process_output (void) nfds++; } - if (nfds < 0) /* { dg-bogus "assuming signed overflow does not occur" } */ + if (nfds < 0) /* { dg-bogus "assuming signed overflow does not occur" "" { xfail *-*-* } } */ return 1; return 0; } diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90 new file mode 100644 index 00000000000..aeb0717086d --- /dev/null +++ b/gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90 @@ -0,0 +1,23 @@ +program membug +call bug1() +end program membug +subroutine unknown(x1,y1,ibig) + write(*,*)x1,y1,ibig +end subroutine unknown +subroutine bug1() +real arrayq(3000) + isize=0 + ibig=-1 + x2=0 +10 continue + isize=isize+1 + arrayq(isize)=x2 +15 continue + call unknown(x1,y1,ibig) + if(ibig.eq.1)then + goto 10 + elseif(ibig.eq.2)then + isize=max(1,isize-1) + goto 15 + endif +end subroutine bug1 diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 6934914c149..a8810134b31 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -774,8 +774,20 @@ update_value_range (const_tree var, value_range *new_vr) { value_range nr; nr.type = rtype; - nr.min = wide_int_to_tree (TREE_TYPE (var), min); - nr.max = wide_int_to_tree (TREE_TYPE (var), max); + /* Range info on SSA names doesn't carry overflow information + so make sure to preserve the overflow bit on the lattice. */ + if (new_vr->type == VR_RANGE + && is_negative_overflow_infinity (new_vr->min) + && wi::eq_p (new_vr->min, min)) + nr.min = new_vr->min; + else + nr.min = wide_int_to_tree (TREE_TYPE (var), min); + if (new_vr->type == VR_RANGE + && is_positive_overflow_infinity (new_vr->max) + && wi::eq_p (new_vr->max, max)) + nr.max = new_vr->max; + else + nr.max = wide_int_to_tree (TREE_TYPE (var), max); nr.equiv = NULL; vrp_intersect_ranges (new_vr, &nr); } @@ -1138,7 +1150,10 @@ operand_less_p (tree val, tree val2) { /* LT is folded faster than GE and others. Inline the common case. */ if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST) - return tree_int_cst_lt (val, val2); + { + if (! is_positive_overflow_infinity (val2)) + return tree_int_cst_lt (val, val2); + } else { tree tcmp; @@ -1422,7 +1437,7 @@ static tree value_range_constant_singleton (value_range *vr) { if (vr->type == VR_RANGE - && operand_equal_p (vr->min, vr->max, 0) + && vrp_operand_equal_p (vr->min, vr->max) && is_gimple_min_invariant (vr->min)) return vr->min; @@ -7028,8 +7043,7 @@ vrp_valueize (tree name) { value_range *vr = get_value_range (name); if (vr->type == VR_RANGE - && (vr->min == vr->max - || operand_equal_p (vr->min, vr->max, 0))) + && vrp_operand_equal_p (vr->min, vr->max)) return vr->min; } return name; @@ -7995,8 +8009,8 @@ union_ranges (enum value_range_type *vr0type, enum value_range_type vr1type, tree vr1min, tree vr1max) { - bool mineq = operand_equal_p (*vr0min, vr1min, 0); - bool maxeq = operand_equal_p (*vr0max, vr1max, 0); + bool mineq = vrp_operand_equal_p (*vr0min, vr1min); + bool maxeq = vrp_operand_equal_p (*vr0max, vr1max); /* [] is vr0, () is vr1 in the following classification comments. */ if (mineq && maxeq) @@ -8266,8 +8280,8 @@ intersect_ranges (enum value_range_type *vr0type, enum value_range_type vr1type, tree vr1min, tree vr1max) { - bool mineq = operand_equal_p (*vr0min, vr1min, 0); - bool maxeq = operand_equal_p (*vr0max, vr1max, 0); + bool mineq = vrp_operand_equal_p (*vr0min, vr1min); + bool maxeq = vrp_operand_equal_p (*vr0max, vr1max); /* [] is vr0, () is vr1 in the following classification comments. */ if (mineq && maxeq) @@ -8725,7 +8739,7 @@ vrp_visit_phi_node (gphi *phi) print_gimple_stmt (dump_file, phi, 0, dump_flags); } - bool may_simulate_again = false; + bool may_simulate_backedge_again = false; edges = 0; for (i = 0; i < gimple_phi_num_args (phi); i++) { @@ -8751,8 +8765,9 @@ vrp_visit_phi_node (gphi *phi) /* See if we are eventually going to change one of the args. */ gimple *def_stmt = SSA_NAME_DEF_STMT (arg); if (! gimple_nop_p (def_stmt) - && prop_simulate_again_p (def_stmt)) - may_simulate_again = true; + && prop_simulate_again_p (def_stmt) + && e->flags & EDGE_DFS_BACK) + may_simulate_backedge_again = true; vr_arg = *(get_value_range (arg)); /* Do not allow equivalences or symbolic ranges to leak in from @@ -8830,13 +8845,12 @@ vrp_visit_phi_node (gphi *phi) edge; this helps us avoid an overflow infinity for conditionals which are not in a loop. If the old value-range was VR_UNDEFINED use the updated range and iterate one more time. If we will not - simulate this PHI again with the same number of edges then iterate - one more time. */ + simulate this PHI again via the backedge allow us to iterate. */ if (edges > 0 && gimple_phi_num_args (phi) > 1 && edges == old_edges && lhs_vr->type != VR_UNDEFINED - && may_simulate_again) + && may_simulate_backedge_again) { /* Compare old and new ranges, fall back to varying if the values are not comparable. */