diff options
author | Richard Biener <rguenth@gcc.gnu.org> | 2015-11-11 10:51:31 +0000 |
---|---|---|
committer | Jiong Wang <jiwang@gcc.gnu.org> | 2015-11-11 10:51:31 +0000 |
commit | 35e2b6e1622210481b6c3118f55fc99a049d504b (patch) | |
tree | 3d93e4ac15fc77f974ba640c8472f3c383ec3855 | |
parent | 394b24ea80626c5464f842f574a57547fb024ad6 (diff) | |
download | gcc-35e2b6e1622210481b6c3118f55fc99a049d504b.zip gcc-35e2b6e1622210481b6c3118f55fc99a049d504b.tar.gz gcc-35e2b6e1622210481b6c3118f55fc99a049d504b.tar.bz2 |
[Patch] PR tree-optimization/68234 Improve range info for loop Phi node
2015-11-11 Richard Biener <rguenth@gcc.gnu.org>
Jiong Wang <jiong.wang@arm.com>
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 <jiong.wang@arm.com>
From-SVN: r230150
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr68234.c | 24 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 39 |
4 files changed, 61 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 21ea2f0..ad69a40 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-11-11 Richard Biener <rguenth@gcc.gnu.org> + Jiong Wang <jiong.wang@arm.com> + + 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 <robert.suchanek@imgtec.com> * regname.c (scan_rtx_reg): Check the matching number of consecutive diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9778c94..59cae93 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-11-11 Richard Biener <rguenth@gcc.gnu.org> + Jiong Wang <jiong.wang@arm.com> + + * gcc.dg/tree-ssa/pr68234.c: New testcase. + 2015-11-10 Nathan Sidwell <nathan@codesourcery.com> * 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 0000000..e7c2a95 --- /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 87c0265..e2393e4 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; } |