From 35e2b6e1622210481b6c3118f55fc99a049d504b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 11 Nov 2015 10:51:31 +0000 Subject: [PATCH] [Patch] PR tree-optimization/68234 Improve range info for loop Phi node 2015-11-11 Richard Biener Jiong Wang gcc/ PR tree-optimization/68234 * tree-vrp.c (vrp_visit_phi_node): Extend SCEV check to those loop PHI node which estimiated to be VR_VARYING initially. gcc/testsuite/ * gcc.dg/tree-ssa/pr68234.c: New testcase. Co-Authored-By: Jiong Wang From-SVN: r230150 --- gcc/ChangeLog | 7 +++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/tree-ssa/pr68234.c | 24 +++++++++++++++ gcc/tree-vrp.c | 39 ++++++++++++++++--------- 4 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr68234.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 21ea2f07d08..ad69a402d51 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-11-11 Richard Biener + Jiong Wang + + PR tree-optimization/68234 + * tree-vrp.c (vrp_visit_phi_node): Extend SCEV check to those loop PHI + node which estimiated to be VR_VARYING initially. + 2015-11-11 Robert Suchanek * regname.c (scan_rtx_reg): Check the matching number of consecutive diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9778c940c25..59cae93a19b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-11-11 Richard Biener + Jiong Wang + + * gcc.dg/tree-ssa/pr68234.c: New testcase. + 2015-11-10 Nathan Sidwell * gcc.dg/goacc/nvptx-opt-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68234.c b/gcc/testsuite/gcc.dg/tree-ssa/pr68234.c new file mode 100644 index 00000000000..e7c2a95aa4c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68234.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp2" } */ + +extern int nc; +void ff (unsigned long long); + +void +f (void) +{ + unsigned char resp[1024]; + int c; + int bl = 0; + unsigned long long *dwords = (unsigned long long *) (resp + 5); + for (c = 0; c < nc; c++) + { + /* PR middle-end/68234, this signed division should be optimized into + right shift as vrp pass should deduct range info of 'bl' falls into + positive number. */ + ff (dwords[bl / 64]); + bl++; + } +} + +/* { dg-final { scan-tree-dump ">> 6" "vrp2" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 87c02654c48..e2393e4d3a0 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; } -- 2.30.2