diff mbox series

[V2] Set bound/cmp/control for until wrap loop.

Message ID 7epmtri1il.fsf_-_@pike.rch.stglabs.ibm.com
State New
Headers show
Series [V2] Set bound/cmp/control for until wrap loop. | expand

Commit Message

Jiufu Guo Sept. 2, 2021, 12:51 p.m. UTC
Changes on V1:
* Add more test case
* Add comment for exit-condition transform
* Removing duplicate setting on niter->control

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

Bootstrap and test pass on ppc64 and x86, and pass the test cases
in PR.  Is this ok for trunk?

One thing, in this patch, the IVbase is still keep as biasing by 1 step.


BR.
Jiufu Guo

gcc/ChangeLog:

2021-09-02  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-02  Jiufu Guo  <guojiufu@linux.ibm.com>

        PR tree-optimization/102087
        * gcc.dg/pr102087.c: New test.

---
 gcc/tree-ssa-loop-niter.c       | 16 ++++++++++++++-
 gcc/testsuite/gcc.dg/pr102087.c | 35 +++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr102087.c

Comments

Jiufu Guo Sept. 15, 2021, 8:50 a.m. UTC | #1
Jiufu Guo <guojiufu@linux.ibm.com> writes:

I may want to have a gentle ping on this.
https://gcc.gnu.org/pipermail/gcc-patches/2021-September/578680.html

BR,
Jiufu

> Changes on V1:
> * Add more test case
> * Add comment for exit-condition transform
> * Removing duplicate setting on niter->control
>
> This patch reset niter->control, niter->bound and niter->cmp in
> number_of_iterations_until_wrap.
>
> Bootstrap and test pass on ppc64 and x86, and pass the test cases
> in PR.  Is this ok for trunk?
>
> One thing, in this patch, the IVbase is still keep as biasing by 1 step.
>
>
> BR.
> Jiufu Guo
>
> gcc/ChangeLog:
>
> 2021-09-02  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-02  Jiufu Guo  <guojiufu@linux.ibm.com>
>
>         PR tree-optimization/102087
>         * gcc.dg/pr102087.c: New test.
>
> ---
>  gcc/tree-ssa-loop-niter.c       | 16 ++++++++++++++-
>  gcc/testsuite/gcc.dg/pr102087.c | 35 +++++++++++++++++++++++++++++++++
>  2 files changed, 50 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/pr102087.c
>
> diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
> index 7af92d1c893..75109407124 100644
> --- a/gcc/tree-ssa-loop-niter.c
> +++ b/gcc/tree-ssa-loop-niter.c
> @@ -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;
>  }
>  
> diff --git a/gcc/testsuite/gcc.dg/pr102087.c b/gcc/testsuite/gcc.dg/pr102087.c
> new file mode 100644
> index 00000000000..fc60cbda066
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr102087.c
> @@ -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 **Gif_ClipImage_gfi_0;
> +int Gif_ClipImage_y, Gif_ClipImage_shift;
> +void
> +Gif_ClipImage ()
> +{
> +  for (; Gif_ClipImage_y >= Gif_ClipImage_shift; Gif_ClipImage_y++)
> +    Gif_ClipImage_gfi_0[Gif_ClipImage_shift]
> +      = Gif_ClipImage_gfi_0[Gif_ClipImage_y];
> +}
Richard Biener Sept. 17, 2021, 8:16 a.m. UTC | #2
On Thu, 2 Sep 2021, Jiufu Guo wrote:

> 
> Changes on V1:
> * Add more test case
> * Add comment for exit-condition transform
> * Removing duplicate setting on niter->control
> 
> This patch reset niter->control, niter->bound and niter->cmp in
> number_of_iterations_until_wrap.
> 
> Bootstrap and test pass on ppc64 and x86, and pass the test cases
> in PR.  Is this ok for trunk?

OK.

Thanks,
Richard.

> One thing, in this patch, the IVbase is still keep as biasing by 1 step.
> 
> 
> BR.
> Jiufu Guo
> 
> gcc/ChangeLog:
> 
> 2021-09-02  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-02  Jiufu Guo  <guojiufu@linux.ibm.com>
> 
>         PR tree-optimization/102087
>         * gcc.dg/pr102087.c: New test.
> 
> ---
>  gcc/tree-ssa-loop-niter.c       | 16 ++++++++++++++-
>  gcc/testsuite/gcc.dg/pr102087.c | 35 +++++++++++++++++++++++++++++++++
>  2 files changed, 50 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/pr102087.c
> 
> diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
> index 7af92d1c893..75109407124 100644
> --- a/gcc/tree-ssa-loop-niter.c
> +++ b/gcc/tree-ssa-loop-niter.c
> @@ -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;
>  }
>  
> diff --git a/gcc/testsuite/gcc.dg/pr102087.c b/gcc/testsuite/gcc.dg/pr102087.c
> new file mode 100644
> index 00000000000..fc60cbda066
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr102087.c
> @@ -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 **Gif_ClipImage_gfi_0;
> +int Gif_ClipImage_y, Gif_ClipImage_shift;
> +void
> +Gif_ClipImage ()
> +{
> +  for (; Gif_ClipImage_y >= Gif_ClipImage_shift; Gif_ClipImage_y++)
> +    Gif_ClipImage_gfi_0[Gif_ClipImage_shift]
> +      = Gif_ClipImage_gfi_0[Gif_ClipImage_y];
> +}
>
diff mbox series

Patch

diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 7af92d1c893..75109407124 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -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;
 }
 
diff --git a/gcc/testsuite/gcc.dg/pr102087.c b/gcc/testsuite/gcc.dg/pr102087.c
new file mode 100644
index 00000000000..fc60cbda066
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr102087.c
@@ -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 **Gif_ClipImage_gfi_0;
+int Gif_ClipImage_y, Gif_ClipImage_shift;
+void
+Gif_ClipImage ()
+{
+  for (; Gif_ClipImage_y >= Gif_ClipImage_shift; Gif_ClipImage_y++)
+    Gif_ClipImage_gfi_0[Gif_ClipImage_shift]
+      = Gif_ClipImage_gfi_0[Gif_ClipImage_y];
+}