+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
--- /dev/null
+/* { 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" } } */
/* 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
/* 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;
}