On Sun, Oct 29, 2023 at 5:41 PM Andrew Pinski <pins...@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
>

Reply via email to