diff mbox series

fold x << (n % C) to x << (n & C-1) if C meets power2

Message ID 20201015075201.2911721-1-guojiufu@linux.ibm.com
State New
Headers show
Series fold x << (n % C) to x << (n & C-1) if C meets power2 | expand

Commit Message

Jiufu Guo Oct. 15, 2020, 7:52 a.m. UTC
Hi,

I just had a check on below patch for PR66552.
https://gcc.gnu.org/pipermail/gcc-patches/2020-February/540930.html
It seems this patch works fine now. This patch fixes PR66552 which
request to optimizes (x shift (n mod C)) to
(x shift (n bit_and (C - 1))) when C is a constant and power of two.

As tests, bootstrap and regtests pass on ppc64le. Is it ok for trunk?

Jiufu Guo

gcc/ChangeLog
2020-10-14  Li Jia He  <helijia@linux.ibm.com>

	PR tree-optimization/66552
	* match.pd (x << (n % C) -> x << (n & C-1)): New simplification.

testsuite/ChangeLog
2020-10-14  Li Jia He  <helijia@linux.ibm.com>

	PR tree-optimization/66552
	* testsuite/gcc.dg/pr66552.c: New testcase.
	

---
 gcc/match.pd                   | 11 ++++++++++-
 gcc/testsuite/gcc.dg/pr66552.c | 14 ++++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr66552.c

Comments

Segher Boessenkool Oct. 15, 2020, 1:10 p.m. UTC | #1
Hi!

On Thu, Oct 15, 2020 at 03:52:01PM +0800, guojiufu wrote:
> I just had a check on below patch for PR66552.
> https://gcc.gnu.org/pipermail/gcc-patches/2020-February/540930.html
> It seems this patch works fine now. This patch fixes PR66552 which
> request to optimizes (x shift (n mod C)) to
> (x shift (n bit_and (C - 1))) when C is a constant and power of two.

>  /* Optimize TRUNC_MOD_EXPR by a power of two into a BIT_AND_EXPR,
>     i.e. "X % C" into "X & (C - 1)", if X and C are positive.
>     Also optimize A % (C << N)  where C is a power of 2,
> -   to A & ((C << N) - 1).  */
> +   to A & ((C << N) - 1).  And optimize "A shift (B % C)" where C
> +   is a power of 2, shift operation included "<<" and ">>" and assume
> +   (B % C) will not be negative as shifts negative values would be UB,
> +   to  "A shift (B & (C - 1))".  */

Maybe this can be phrased better?  Not that I have any proposed text :-/

The patch looks good to me, fwiw.


Segher
Richard Biener Oct. 16, 2020, 12:48 p.m. UTC | #2
On Thu, 15 Oct 2020, guojiufu wrote:

> Hi,
> 
> I just had a check on below patch for PR66552.
> https://gcc.gnu.org/pipermail/gcc-patches/2020-February/540930.html
> It seems this patch works fine now. This patch fixes PR66552 which
> request to optimizes (x shift (n mod C)) to
> (x shift (n bit_and (C - 1))) when C is a constant and power of two.
> 
> As tests, bootstrap and regtests pass on ppc64le. Is it ok for trunk?

OK.

Thanks,
Richard.

> Jiufu Guo
> 
> gcc/ChangeLog
> 2020-10-14  Li Jia He  <helijia@linux.ibm.com>
> 
> 	PR tree-optimization/66552
> 	* match.pd (x << (n % C) -> x << (n & C-1)): New simplification.
> 
> testsuite/ChangeLog
> 2020-10-14  Li Jia He  <helijia@linux.ibm.com>
> 
> 	PR tree-optimization/66552
> 	* testsuite/gcc.dg/pr66552.c: New testcase.
> 	
> 
> ---
>  gcc/match.pd                   | 11 ++++++++++-
>  gcc/testsuite/gcc.dg/pr66552.c | 14 ++++++++++++++
>  2 files changed, 24 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/pr66552.c
> 
> diff --git a/gcc/match.pd b/gcc/match.pd
> index c3b88168ac4..9070812fe7b 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -607,12 +607,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>  /* Optimize TRUNC_MOD_EXPR by a power of two into a BIT_AND_EXPR,
>     i.e. "X % C" into "X & (C - 1)", if X and C are positive.
>     Also optimize A % (C << N)  where C is a power of 2,
> -   to A & ((C << N) - 1).  */
> +   to A & ((C << N) - 1).  And optimize "A shift (B % C)" where C
> +   is a power of 2, shift operation included "<<" and ">>" and assume
> +   (B % C) will not be negative as shifts negative values would be UB,
> +   to  "A shift (B & (C - 1))".  */
>  (match (power_of_two_cand @1)
>   INTEGER_CST@1)
>  (match (power_of_two_cand @1)
>   (lshift INTEGER_CST@1 @2))
>  (for mod (trunc_mod floor_mod)
> + (for shift (lshift rshift)
> +  (simplify
> +   (shift @0 (mod @1 (power_of_two_cand@2 @3)))
> +   (if (integer_pow2p (@3) && tree_int_cst_sgn (@3) > 0)
> +    (shift @0 (bit_and @1 (minus @2 { build_int_cst (TREE_TYPE (@2),
> +						      1); }))))))
>   (simplify
>    (mod @0 (convert?@3 (power_of_two_cand@1 @2)))
>    (if ((TYPE_UNSIGNED (type)
> diff --git a/gcc/testsuite/gcc.dg/pr66552.c b/gcc/testsuite/gcc.dg/pr66552.c
> new file mode 100644
> index 00000000000..7583c9ad25a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr66552.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-lower" } */
> +
> +unsigned a(unsigned x, int n)
> +{
> +  return x >> (n % 32);
> +}
> +
> +unsigned b(unsigned x, int n)
> +{
> +  return x << (n % 32);
> +}
> +
> +/* { dg-final { scan-tree-dump-not " % " "lower" } } */
>
diff mbox series

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index c3b88168ac4..9070812fe7b 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -607,12 +607,21 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* Optimize TRUNC_MOD_EXPR by a power of two into a BIT_AND_EXPR,
    i.e. "X % C" into "X & (C - 1)", if X and C are positive.
    Also optimize A % (C << N)  where C is a power of 2,
-   to A & ((C << N) - 1).  */
+   to A & ((C << N) - 1).  And optimize "A shift (B % C)" where C
+   is a power of 2, shift operation included "<<" and ">>" and assume
+   (B % C) will not be negative as shifts negative values would be UB,
+   to  "A shift (B & (C - 1))".  */
 (match (power_of_two_cand @1)
  INTEGER_CST@1)
 (match (power_of_two_cand @1)
  (lshift INTEGER_CST@1 @2))
 (for mod (trunc_mod floor_mod)
+ (for shift (lshift rshift)
+  (simplify
+   (shift @0 (mod @1 (power_of_two_cand@2 @3)))
+   (if (integer_pow2p (@3) && tree_int_cst_sgn (@3) > 0)
+    (shift @0 (bit_and @1 (minus @2 { build_int_cst (TREE_TYPE (@2),
+						      1); }))))))
  (simplify
   (mod @0 (convert?@3 (power_of_two_cand@1 @2)))
   (if ((TYPE_UNSIGNED (type)
diff --git a/gcc/testsuite/gcc.dg/pr66552.c b/gcc/testsuite/gcc.dg/pr66552.c
new file mode 100644
index 00000000000..7583c9ad25a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr66552.c
@@ -0,0 +1,14 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-lower" } */
+
+unsigned a(unsigned x, int n)
+{
+  return x >> (n % 32);
+}
+
+unsigned b(unsigned x, int n)
+{
+  return x << (n % 32);
+}
+
+/* { dg-final { scan-tree-dump-not " % " "lower" } } */