diff mbox series

MATCH: Simplify `a rrotate (32-b) -> a lrotate b` [PR109906]

Message ID 20240918062157.29060-1-quic_eikagupt@quicinc.com
State New
Headers show
Series MATCH: Simplify `a rrotate (32-b) -> a lrotate b` [PR109906] | expand

Commit Message

Eikansh Gupta Sept. 18, 2024, 6:21 a.m. UTC
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

Comments

Andrew Pinski Sept. 18, 2024, 6:26 a.m. UTC | #1
On Tue, Sep 17, 2024 at 11:23 PM Eikansh Gupta
<quic_eikagupt@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
>
diff mbox series

Patch

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