[1/3] MATCH: first of the value replacement moving from phiopt

Message ID 20231029164049.994454-2-pinskia@gmail.com
State Accepted
Headers
Series start of moving value replacement from phiopt to match |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Andrew Pinski Oct. 29, 2023, 4:40 p.m. UTC
  This moves a few simple patterns that are done in value replacement
in phiopt over to match.pd. Just the simple ones which might show up
in other code.

This allows some optimizations to happen even without depending
on sinking from happening and in some cases where phiopt is not
invoked (cond-1.c is an example there).

Changes since v1:
* v2: Add an extra testcase to showcase improvements at -O1.

Bootstrapped and tested on x86_64-linux-gnu with no regressions.

gcc/ChangeLog:

	* match.pd: (`a == 0 ? b : b + a`,
	`a == 0 ? b : b - a`): New patterns.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/cond-1.c: New test.
	* gcc.dg/tree-ssa/phi-opt-value-1.c: New test.
	* gcc.dg/tree-ssa/phi-opt-value-1a.c: New test.
	* gcc.dg/tree-ssa/phi-opt-value-2.c: New test.
---
 gcc/match.pd                                  | 14 ++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/cond-1.c        | 17 +++++++++++++++++
 .../gcc.dg/tree-ssa/phi-opt-value-1.c         | 17 +++++++++++++++++
 .../gcc.dg/tree-ssa/phi-opt-value-1a.c        | 19 +++++++++++++++++++
 .../gcc.dg/tree-ssa/phi-opt-value-2.c         | 19 +++++++++++++++++++
 5 files changed, 86 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cond-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c
  

Comments

Richard Biener Oct. 30, 2023, 9:32 a.m. UTC | #1
On Sun, Oct 29, 2023 at 5:41 PM Andrew Pinski <pinskia@gmail.com> wrote:
>
> This moves a few simple patterns that are done in value replacement
> in phiopt over to match.pd. Just the simple ones which might show up
> in other code.
>
> This allows some optimizations to happen even without depending
> on sinking from happening and in some cases where phiopt is not
> invoked (cond-1.c is an example there).
>
> Changes since v1:
> * v2: Add an extra testcase to showcase improvements at -O1.
>
> Bootstrapped and tested on x86_64-linux-gnu with no regressions.

OK.

> gcc/ChangeLog:
>
>         * match.pd: (`a == 0 ? b : b + a`,
>         `a == 0 ? b : b - a`): New patterns.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/cond-1.c: New test.
>         * gcc.dg/tree-ssa/phi-opt-value-1.c: New test.
>         * gcc.dg/tree-ssa/phi-opt-value-1a.c: New test.
>         * gcc.dg/tree-ssa/phi-opt-value-2.c: New test.
> ---
>  gcc/match.pd                                  | 14 ++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/cond-1.c        | 17 +++++++++++++++++
>  .../gcc.dg/tree-ssa/phi-opt-value-1.c         | 17 +++++++++++++++++
>  .../gcc.dg/tree-ssa/phi-opt-value-1a.c        | 19 +++++++++++++++++++
>  .../gcc.dg/tree-ssa/phi-opt-value-2.c         | 19 +++++++++++++++++++
>  5 files changed, 86 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cond-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 7d651a6582d..22899c51a2f 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -4145,6 +4145,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>         && (INTEGRAL_TYPE_P (TREE_TYPE (@0))))
>         (op (mult (convert:type @0) @2) @1))))
>
> +/* ?: Value replacement. */
> +/* a == 0 ? b : b + a  -> b + a */
> +(for op (plus bit_ior bit_xor)
> + (simplify
> +  (cond (eq @0 integer_zerop) @1 (op:c@2 @1 @0))
> +   @2))
> +/* a == 0 ? b : b - a  -> b - a */
> +/* a == 0 ? b : b ptr+ a  -> b ptr+ a */
> +/* a == 0 ? b : b shift/rotate a -> b shift/rotate a */
> +(for op (lrotate rrotate lshift rshift minus pointer_plus)
> + (simplify
> +  (cond (eq @0 integer_zerop) @1 (op@2 @1 @0))
> +   @2))
> +
>  /* Simplifications of shift and rotates.  */
>
>  (for rotate (lrotate rrotate)
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cond-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cond-1.c
> new file mode 100644
> index 00000000000..478a818b206
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/cond-1.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-optimized-raw" } */
> +
> +int sub(int a, int b, int c, int d) {
> +  int e = (a == 0);
> +  int f = !e;
> +  c = b;
> +  d = b - a ;
> +  return ((-e & c) | (-f & d));
> +}
> +
> +/* In the end we end up with `(a == 0) ? (b - a) : b`
> +   which then can be optimized to just `(b - a)`. */
> +
> +/* { dg-final { scan-tree-dump-not "cond_expr," "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "eq_expr," "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "minus_expr," 1 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c
> new file mode 100644
> index 00000000000..a90de8926c6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* Phi-OPT should be able to optimize this without sinking being invoked. */
> +/* { dg-options "-O -fdump-tree-phiopt2 -fdump-tree-optimized -fno-tree-sink" } */
> +
> +char *f(char *a, __SIZE_TYPE__ b) {
> +  char *d = a + b;
> +  if (b == 0) return a;
> +  return d;
> +}
> +int sub(int a, int b, int c) {
> +  int d = a - b;
> +  if (b == 0) return a;
> +  return d;
> +}
> +
> +/* { dg-final { scan-tree-dump-not "goto" "phiopt2" } } */
> +/* { dg-final { scan-tree-dump-not "goto" "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c
> new file mode 100644
> index 00000000000..b884f94ddd2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c
> @@ -0,0 +1,19 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +[[gnu::const]]
> +int constcall(int);
> +
> +int f(int a, int b)
> +{
> +  int c = b+a;
> +  int t = constcall(c);
> +  int d;
> +  if (a == 0) d= b; else d= c;
> +  return constcall(d) + t;
> +}
> +
> +/* There should be no if statement and 2 calls to call1. */
> +/* { dg-final { scan-tree-dump-not "if " "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "constcall " 1 "optimized" } } */
> +
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c
> new file mode 100644
> index 00000000000..809ccfe1479
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c
> @@ -0,0 +1,19 @@
> +/* { dg-do compile } */
> +/* Phi-OPT should be able to optimize this without sinking being invoked. */
> +/* { dg-options "-O -fdump-tree-phiopt2 -fdump-tree-optimized -fno-tree-sink" } */
> +
> +int f(int a, int b, int c) {
> +  int d = a + b;
> +  if (c > 5) return c;
> +  if (a == 0) return b;
> +  return d;
> +}
> +
> +unsigned rot(unsigned x, int n) {
> +  const int bits = __CHAR_BIT__ * __SIZEOF_INT__;
> +  int t = ((x << n) | (x >> (bits - n)));
> +  return (n == 0) ? x : t;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "goto" 2 "phiopt2" } } */
> +/* { dg-final { scan-tree-dump-times "goto" 2 "optimized" } } */
> --
> 2.39.3
>
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index 7d651a6582d..22899c51a2f 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4145,6 +4145,20 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && (INTEGRAL_TYPE_P (TREE_TYPE (@0))))
        (op (mult (convert:type @0) @2) @1))))
 
+/* ?: Value replacement. */
+/* a == 0 ? b : b + a  -> b + a */
+(for op (plus bit_ior bit_xor)
+ (simplify
+  (cond (eq @0 integer_zerop) @1 (op:c@2 @1 @0))
+   @2))
+/* a == 0 ? b : b - a  -> b - a */
+/* a == 0 ? b : b ptr+ a  -> b ptr+ a */
+/* a == 0 ? b : b shift/rotate a -> b shift/rotate a */
+(for op (lrotate rrotate lshift rshift minus pointer_plus)
+ (simplify
+  (cond (eq @0 integer_zerop) @1 (op@2 @1 @0))
+   @2))
+
 /* Simplifications of shift and rotates.  */
 
 (for rotate (lrotate rrotate)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cond-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cond-1.c
new file mode 100644
index 00000000000..478a818b206
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cond-1.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized-raw" } */
+
+int sub(int a, int b, int c, int d) {
+  int e = (a == 0);
+  int f = !e;
+  c = b;
+  d = b - a ;
+  return ((-e & c) | (-f & d));
+}
+
+/* In the end we end up with `(a == 0) ? (b - a) : b`
+   which then can be optimized to just `(b - a)`. */
+
+/* { dg-final { scan-tree-dump-not "cond_expr," "optimized" } } */
+/* { dg-final { scan-tree-dump-not "eq_expr," "optimized" } } */
+/* { dg-final { scan-tree-dump-times "minus_expr," 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c
new file mode 100644
index 00000000000..a90de8926c6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* Phi-OPT should be able to optimize this without sinking being invoked. */
+/* { dg-options "-O -fdump-tree-phiopt2 -fdump-tree-optimized -fno-tree-sink" } */
+
+char *f(char *a, __SIZE_TYPE__ b) {
+  char *d = a + b;
+  if (b == 0) return a;
+  return d;
+}
+int sub(int a, int b, int c) {
+  int d = a - b;
+  if (b == 0) return a;
+  return d;
+}
+
+/* { dg-final { scan-tree-dump-not "goto" "phiopt2" } } */
+/* { dg-final { scan-tree-dump-not "goto" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c
new file mode 100644
index 00000000000..b884f94ddd2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-1a.c
@@ -0,0 +1,19 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+[[gnu::const]]
+int constcall(int);
+
+int f(int a, int b)
+{
+  int c = b+a;
+  int t = constcall(c);
+  int d;
+  if (a == 0) d= b; else d= c;
+  return constcall(d) + t;
+}
+
+/* There should be no if statement and 2 calls to call1. */
+/* { dg-final { scan-tree-dump-not "if " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "constcall " 1 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c
new file mode 100644
index 00000000000..809ccfe1479
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-2.c
@@ -0,0 +1,19 @@ 
+/* { dg-do compile } */
+/* Phi-OPT should be able to optimize this without sinking being invoked. */
+/* { dg-options "-O -fdump-tree-phiopt2 -fdump-tree-optimized -fno-tree-sink" } */
+
+int f(int a, int b, int c) {
+  int d = a + b;
+  if (c > 5) return c;
+  if (a == 0) return b;
+  return d;
+}
+
+unsigned rot(unsigned x, int n) {
+  const int bits = __CHAR_BIT__ * __SIZEOF_INT__;
+  int t = ((x << n) | (x >> (bits - n)));
+  return (n == 0) ? x : t;
+}
+
+/* { dg-final { scan-tree-dump-times "goto" 2 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times "goto" 2 "optimized" } } */