On Tue, Sep 17, 2024 at 11:23 PM Eikansh Gupta <quic_eikag...@quicinc.com> wrote: > > The pattern `a rrotate (32-b)` should be optimized to `a lrotate b`. > The same is also true for `a lrotate (32-b)`. It can be optimized to > `a rrotate b`. > > This patch adds following patterns: > a rrotate (32-b) -> a lrotate b > a lrotate (32-b) -> a rrotate b > > PR tree-optimization/109906 > > gcc/ChangeLog: > > * match.pd (a rrotate (32-b) -> a lrotate b): New pattern > (a lrotate (32-b) -> a rrotate b): New pattern > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/pr109906.c: New test. > --- > gcc/match.pd | 10 ++++++ > gcc/testsuite/gcc.dg/tree-ssa/pr109906.c | 40 ++++++++++++++++++++++++ > 2 files changed, 50 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr109906.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index 5566c0e4c41..77cb3f8060a 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -4759,6 +4759,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > build_int_cst (TREE_TYPE (@1), > element_precision (type)), @1); })) > > +/* a rrotate (32-b) -> a lrotate b */ > +/* a lrotate (32-b) -> a rrotate b */ > +(for rotate (lrotate rrotate) > + (simplify > + (rotate @0 (minus INTEGER_CST@1 @2)) > + (if (TYPE_PRECISION (TREE_TYPE (@0)) == wi::to_wide (@1)) > + (if (rotate == RROTATE_EXPR) > + (lrotate @0 @2) > + (rrotate @0 @2)))))
I just noticed this can be simplified to: ``` (for rotate (lrotate rrotate) orotate (rrotate lrotate) (simplify (rotate @0 (minus INTEGER_CST@1 @2)) (if (TYPE_PRECISION (TREE_TYPE (@0)) == wi::to_wide (@1)) (orotate @0 @2)))) ``` Sorry for not noticing that in the internal review. Thanks, Andrew Pinski > + > /* Turn (a OP c1) OP c2 into a OP (c1+c2). */ > (for op (lrotate rrotate rshift lshift) > (simplify > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109906.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr109906.c > new file mode 100644 > index 00000000000..fe576d7ce3a > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109906.c > @@ -0,0 +1,40 @@ > +/* PR tree-optimization/109906 */ > +/* { dg-do compile } */ > +/* { dg-options "-O1 -fdump-tree-optimized-raw" } */ > + > +/* Implementation of rotate right operation */ > +static inline > +unsigned rrotate(unsigned x, int t) > +{ > + if (t >= 32) __builtin_unreachable(); > + unsigned tl = x >> (t); > + unsigned th = x << (32-t); > + return tl | th; > +} > + > +/* Here rotate left is achieved by doing rotate right by (32 - x) */ > +unsigned rotateleft(unsigned t, int x) > +{ > + return rrotate (t, 32-x); > +} > + > +/* Implementation of rotate left operation */ > +static inline > +unsigned lrotate(unsigned x, int t) > +{ > + if (t >= 32) __builtin_unreachable(); > + unsigned tl = x << (t); > + unsigned th = x >> (32-t); > + return tl | th; > +} > + > +/* Here rotate right is achieved by doing rotate left by (32 - x) */ > +unsigned rotateright(unsigned t, int x) > +{ > + return lrotate (t, 32-x); > +} > + > +/* Shouldn't have instruction for (32 - x). */ > +/* { dg-final { scan-tree-dump-not "minus_expr" "optimized" } } */ > +/* { dg-final { scan-tree-dump "rrotate_expr" "optimized" } } */ > +/* { dg-final { scan-tree-dump "lrotate_expr" "optimized" } } */ > -- > 2.17.1 >