Set bound/cmp/control for until wrap loop.

In patch r12-3136, niter->control, niter->bound and niter->cmp are
derived from number_of_iterations_lt.  While for 'until wrap condition',
the calculation in number_of_iterations_lt is not align the requirements
on the define of them and requirements in determine_exit_conditions.

This patch calculate niter->control, niter->bound and niter->cmp in
number_of_iterations_until_wrap.

gcc/ChangeLog:

2021-09-22  Jiufu Guo  <guojiufu@linux.ibm.com>

	PR tree-optimization/102087
	* tree-ssa-loop-niter.c (number_of_iterations_until_wrap):
	Update bound/cmp/control for niter.

gcc/testsuite/ChangeLog:

2021-09-22  Jiufu Guo  <guojiufu@linux.ibm.com>

	* gcc.dg/pr102087.c: New test.
	PR tree-optimization/102087
This commit is contained in:
Jiufu Guo 2021-09-22 13:20:29 +08:00
parent fec75ab8c0
commit 3087d1b0a2
2 changed files with 50 additions and 1 deletions

View File

@ -0,0 +1,35 @@
/* { dg-do compile } */
/* { dg-options "-O3" } */
unsigned __attribute__ ((noinline))
foo (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n)
{
while (n < ++l)
*a++ = *b++ + 1;
return l;
}
volatile int a[1];
unsigned b;
int c;
int
check ()
{
int d;
for (; b > 1; b++)
for (c = 0; c < 2; c++)
for (d = 0; d < 2; d++)
a[0];
return 0;
}
char **clip_image_gfi_0;
int clip_image_y, clip_image_shift;
void
clip_image ()
{
for (; clip_image_y >= clip_image_shift; clip_image_y++)
clip_image_gfi_0[clip_image_shift]
= clip_image_gfi_0[clip_image_y];
}

View File

@ -1482,7 +1482,7 @@ number_of_iterations_until_wrap (class loop *, tree type, affine_iv *iv0,
affine_iv *iv1, class tree_niter_desc *niter)
{
tree niter_type = unsigned_type_for (type);
tree step, num, assumptions, may_be_zero;
tree step, num, assumptions, may_be_zero, span;
wide_int high, low, max, min;
may_be_zero = fold_build2 (LE_EXPR, boolean_type_node, iv1->base, iv0->base);
@ -1557,6 +1557,20 @@ number_of_iterations_until_wrap (class loop *, tree type, affine_iv *iv0,
niter->control.no_overflow = false;
/* Update bound and exit condition as:
bound = niter * STEP + (IVbase - STEP).
{ IVbase - STEP, +, STEP } != bound
Here, biasing IVbase by 1 step makes 'bound' be the value before wrap.
*/
niter->control.base = fold_build2 (MINUS_EXPR, niter_type,
niter->control.base, niter->control.step);
span = fold_build2 (MULT_EXPR, niter_type, niter->niter,
fold_convert (niter_type, niter->control.step));
niter->bound = fold_build2 (PLUS_EXPR, niter_type, span,
fold_convert (niter_type, niter->control.base));
niter->bound = fold_convert (type, niter->bound);
niter->cmp = NE_EXPR;
return true;
}