aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2015-12-02 11:30:24 +0100
committerLinaro Code Review <review@review.linaro.org>2015-12-03 12:54:05 +0000
commit82e3552f42380db76826dccbdc2f55e4de594aa3 (patch)
tree9f4f38e00ac4b097ef8f4da94a92601094a5937c
parent507ad575ca6703818f78bbf56a2427708fa6aab1 (diff)
gcc/
Backport from trunk r230150. 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. gcc/testsuite/ Backport from trunk r230150. 2015-11-11 Richard Biener <rguenth@gcc.gnu.org> Jiong Wang <jiong.wang@arm.com> * gcc.dg/tree-ssa/pr68234.c: New testcase. Change-Id: Id0e4ece65bdb060513995d88572eb52dd67ddb6f
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr68234.c24
-rw-r--r--gcc/tree-vrp.c39
2 files changed, 49 insertions, 14 deletions
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;
}