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