diff mbox

[v2,2/2] combine successive multiplications by constants

Message ID 20170721155550.5846-2-amonakov@ispras.ru
State New
Headers show

Commit Message

Alexander Monakov July 21, 2017, 3:55 p.m. UTC
Previous revision here: https://gcc.gnu.org/ml/gcc-patches/2017-07/msg01090.html

Reassociate X * CST1 * CST2 to X * (CST1 * CST2).

Changed in this revision:
- remove the check for @2 being 0 or -1

	* match.pd ((X * CST1) * CST2): Simplify to X * (CST1 * CST2).
testsuite:
	* gcc.dg/tree-ssa/assoc-2.c: Enhance.
	* gcc.dg/tree-ssa/slsr-4.c: Adjust.

---
 gcc/match.pd                            | 13 +++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/assoc-2.c | 13 ++++++++++++-
 gcc/testsuite/gcc.dg/tree-ssa/slsr-4.c  |  8 ++------
 3 files changed, 27 insertions(+), 7 deletions(-)

Comments

Richard Biener July 25, 2017, 2:19 p.m. UTC | #1
On Fri, Jul 21, 2017 at 5:55 PM, Alexander Monakov <amonakov@ispras.ru> wrote:
> Previous revision here: https://gcc.gnu.org/ml/gcc-patches/2017-07/msg01090.html
>
> Reassociate X * CST1 * CST2 to X * (CST1 * CST2).
>
> Changed in this revision:
> - remove the check for @2 being 0 or -1

Ok.

Thanks,
Richard.

>         * match.pd ((X * CST1) * CST2): Simplify to X * (CST1 * CST2).
> testsuite:
>         * gcc.dg/tree-ssa/assoc-2.c: Enhance.
>         * gcc.dg/tree-ssa/slsr-4.c: Adjust.
>
> ---
>  gcc/match.pd                            | 13 +++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/assoc-2.c | 13 ++++++++++++-
>  gcc/testsuite/gcc.dg/tree-ssa/slsr-4.c  |  8 ++------
>  3 files changed, 27 insertions(+), 7 deletions(-)
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 39e1e5c..732b80c 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -284,6 +284,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>          || mul != wi::min_value (TYPE_PRECISION (type), SIGNED))
>       { build_zero_cst (type); })))))
>
> +/* Combine successive multiplications.  Similar to above, but handling
> +   overflow is different.  */
> +(simplify
> + (mult (mult @0 INTEGER_CST@1) INTEGER_CST@2)
> + (with {
> +   bool overflow_p;
> +   wide_int mul = wi::mul (@1, @2, TYPE_SIGN (type), &overflow_p);
> +  }
> +  /* Skip folding on overflow: the only special case is @1 * @2 == -INT_MIN,
> +     otherwise undefined overflow implies that @0 must be zero.  */
> +  (if (!overflow_p || TYPE_OVERFLOW_WRAPS (type))
> +   (mult @0 { wide_int_to_tree (type, mul); }))))
> +
>  /* Optimize A / A to 1.0 if we don't care about
>     NaNs or Infinities.  */
>  (simplify
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/assoc-2.c b/gcc/testsuite/gcc.dg/tree-ssa/assoc-2.c
> index a92c882..cc0e9d4 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/assoc-2.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/assoc-2.c
> @@ -5,4 +5,15 @@ int f0(int a, int b){
>    return a * 33 * b * 55;
>  }
>
> -/* { dg-final { scan-tree-dump-times "mult_expr" 2 "gimple" } } */
> +int f1(int a){
> +  a *= 33;
> +  return a * 55;
> +}
> +
> +int f2(int a, int b){
> +  a *= 33;
> +  return a * b * 55;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "mult_expr" 7 "gimple" } } */
> +/* { dg-final { scan-tree-dump-times "mult_expr" 5 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-4.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-4.c
> index 17d7b4c..1e943b7 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-4.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-4.c
> @@ -23,13 +23,9 @@ f (int i)
>    foo (y);
>  }
>
> -/* { dg-final { scan-tree-dump-times "\\* 4" 1 "slsr" } } */
> -/* { dg-final { scan-tree-dump-times "\\* 10" 1 "slsr" } } */
> -/* { dg-final { scan-tree-dump-times "\\+ 20;" 1 "slsr" } } */
> +/* { dg-final { scan-tree-dump-times "\\* 40" 1 "slsr" } } */
>  /* { dg-final { scan-tree-dump-times "\\+ 200" 1 "slsr" } } */
> -/* { dg-final { scan-tree-dump-times "\\- 16;" 1 "slsr" } } */
>  /* { dg-final { scan-tree-dump-times "\\- 160" 1 "slsr" } } */
> -/* { dg-final { scan-tree-dump-times "\\* 4" 1 "optimized" } } */
> -/* { dg-final { scan-tree-dump-times "\\* 10" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "\\* 40" 1 "optimized" } } */
>  /* { dg-final { scan-tree-dump-times "\\+ 200" 1 "optimized" } } */
>  /* { dg-final { scan-tree-dump-times "\\+ 40" 1 "optimized" } } */
> --
> 1.8.3.1
>
diff mbox

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index 39e1e5c..732b80c 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -284,6 +284,19 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	 || mul != wi::min_value (TYPE_PRECISION (type), SIGNED))
      { build_zero_cst (type); })))))
 
+/* Combine successive multiplications.  Similar to above, but handling
+   overflow is different.  */
+(simplify
+ (mult (mult @0 INTEGER_CST@1) INTEGER_CST@2)
+ (with {
+   bool overflow_p;
+   wide_int mul = wi::mul (@1, @2, TYPE_SIGN (type), &overflow_p);
+  }
+  /* Skip folding on overflow: the only special case is @1 * @2 == -INT_MIN,
+     otherwise undefined overflow implies that @0 must be zero.  */
+  (if (!overflow_p || TYPE_OVERFLOW_WRAPS (type))
+   (mult @0 { wide_int_to_tree (type, mul); }))))
+
 /* Optimize A / A to 1.0 if we don't care about
    NaNs or Infinities.  */
 (simplify
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/assoc-2.c b/gcc/testsuite/gcc.dg/tree-ssa/assoc-2.c
index a92c882..cc0e9d4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/assoc-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/assoc-2.c
@@ -5,4 +5,15 @@  int f0(int a, int b){
   return a * 33 * b * 55;
 }
 
-/* { dg-final { scan-tree-dump-times "mult_expr" 2 "gimple" } } */
+int f1(int a){
+  a *= 33;
+  return a * 55;
+}
+
+int f2(int a, int b){
+  a *= 33;
+  return a * b * 55;
+}
+
+/* { dg-final { scan-tree-dump-times "mult_expr" 7 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "mult_expr" 5 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-4.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-4.c
index 17d7b4c..1e943b7 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-4.c
@@ -23,13 +23,9 @@  f (int i)
   foo (y);
 }
 
-/* { dg-final { scan-tree-dump-times "\\* 4" 1 "slsr" } } */
-/* { dg-final { scan-tree-dump-times "\\* 10" 1 "slsr" } } */
-/* { dg-final { scan-tree-dump-times "\\+ 20;" 1 "slsr" } } */
+/* { dg-final { scan-tree-dump-times "\\* 40" 1 "slsr" } } */
 /* { dg-final { scan-tree-dump-times "\\+ 200" 1 "slsr" } } */
-/* { dg-final { scan-tree-dump-times "\\- 16;" 1 "slsr" } } */
 /* { dg-final { scan-tree-dump-times "\\- 160" 1 "slsr" } } */
-/* { dg-final { scan-tree-dump-times "\\* 4" 1 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "\\* 10" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\* 40" 1 "optimized" } } */
 /* { dg-final { scan-tree-dump-times "\\+ 200" 1 "optimized" } } */
 /* { dg-final { scan-tree-dump-times "\\+ 40" 1 "optimized" } } */