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 >