On Sun, Oct 29, 2023 at 5:41 PM Andrew Pinski <pins...@gmail.com> wrote: > > This moves a few more value_replacements simplifications to match. > /* a == 1 ? b : a * b -> a * b */ > /* a == 1 ? b : b / a -> b / a */ > /* a == -1 ? b : a & b -> a & b */ > > Also adds a testcase to show can we catch these where value_replacement would > not > (but other passes would). > > Bootstrapped and tested on x86_64-linux-gnu with no regressions.
OK. > gcc/ChangeLog: > > * match.pd (`a == 1 ? b : a OP b`): New pattern. > (`a == -1 ? b : a & b`): New pattern. > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/phi-opt-value-4.c: New test. > --- > gcc/match.pd | 18 ++++++++++ > .../gcc.dg/tree-ssa/phi-opt-value-4.c | 36 +++++++++++++++++++ > 2 files changed, 54 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index 9bc945ccada..6efa97cc6ae 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -4159,6 +4159,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (cond (eq @0 integer_zerop) @1 (op@2 @1 @0)) > @2)) > > +/* a == 1 ? b : b / a -> b / a */ > +(for op (trunc_div ceil_div floor_div round_div exact_div) > + (simplify > + (cond (eq @0 integer_onep) @1 (op@2 @1 @0)) > + @2)) > + > +/* a == 1 ? b : a * b -> a * b */ > +(for op (mult) > + (simplify > + (cond (eq @0 integer_onep) @1 (op:c@2 @1 @0)) > + @2)) > + > +/* a == -1 ? b : a & b -> a & b */ > +(for op (bit_and) > + (simplify > + (cond (eq @0 integer_all_onesp) @1 (op:c@2 @1 @0)) > + @2)) > + > /* PTR == 0 ? 0 : &PTR->field -> PTR if field offset was 0. */ > (simplify > (cond (eq @0 integer_zerop) integer_zerop ADDR_EXPR@1) > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c > b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c > new file mode 100644 > index 00000000000..380082cb463 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c > @@ -0,0 +1,36 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O1 -fdump-tree-fre3 -fdump-tree-phiopt1 > -fdump-tree-optimized" } */ > + > +[[gnu::const]] > +int constcall(int); > + > +int fdiv(int a, int b) > +{ > + int c = b/a; > + int t = constcall(c); > + int d; > + if (a == 1) d = b; else d = c; > + return constcall(d) + t; > +} > +int fmult(int a, int b) > +{ > + int c = b*a; > + int t = constcall(c); > + int d; > + if (a == 1) d = b; else d = c; > + return constcall(d) + t; > +} > +int fand(int a, int b) > +{ > + int c = b&a; > + int t = constcall(c); > + int d; > + if (a == -1) d = b; else d = c; > + return constcall(d) + t; > +} > + > +/* Should be able to optimize away the if statements in phiopt1. */ > +/* { dg-final { scan-tree-dump-not "if " "phiopt1" } } */ > +/* fre3 should be optimize each function to just `return constcall(a OP b) * > 2;`. */ > +/* { dg-final { scan-tree-dump-times "constcall " 3 "fre3" } } */ > +/* { dg-final { scan-tree-dump-times "constcall " 3 "optimized" } } */ > -- > 2.39.3 >