From 82e3552f42380db76826dccbdc2f55e4de594aa3 Mon Sep 17 00:00:00 2001 From: Yvan Roux Date: Wed, 2 Dec 2015 11:30:24 +0100 Subject: gcc/ Backport from trunk r230150. 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. gcc/testsuite/ Backport from trunk r230150. 2015-11-11 Richard Biener Jiong Wang * gcc.dg/tree-ssa/pr68234.c: New testcase. Change-Id: Id0e4ece65bdb060513995d88572eb52dd67ddb6f --- gcc/testsuite/gcc.dg/tree-ssa/pr68234.c | 24 ++++++++++++++++++++ gcc/tree-vrp.c | 39 +++++++++++++++++++++------------ 2 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr68234.c 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 877b7d580a7..ec43bc64729 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -8977,20 +8977,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 @@ -9016,8 +9007,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; } -- cgit v1.2.3