[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
This commit is contained in:
Richard Biener 2015-11-11 10:51:31 +00:00 committed by Jiong Wang
parent 394b24ea80
commit 35e2b6e162
4 changed files with 60 additions and 13 deletions

View file

@ -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

View file

@ -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.

View file

@ -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" } } */

View file

@ -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);
goto scev_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 ((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 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;
}