On Tue, Oct 24, 2023 at 1:04 AM Andrew Pinski <pins...@gmail.com> wrote: > > So this pattern needs a little help on the gimple side of things to know what > the type popcount should be. For most builtins, the type is the same as the > input > but popcount and others are not. And when using it with another outer > expression, > genmatch needs some slight help to know that the return type was type rather > than > the argument type. > > Bootstrapped and tested on x86_64-linux-gnu with no regressions.
OK. > PR tree-optimization/111913 > > gcc/ChangeLog: > > * match.pd (`popcount(X&Y) + popcount(X|Y)`): Add the resulting > type for popcount. > > gcc/testsuite/ChangeLog: > > * gcc.c-torture/compile/fold-popcount-1.c: New test. > * gcc.dg/fold-popcount-8a.c: New test. > --- > gcc/match.pd | 2 +- > .../gcc.c-torture/compile/fold-popcount-1.c | 13 ++++++++ > gcc/testsuite/gcc.dg/fold-popcount-8a.c | 33 +++++++++++++++++++ > 3 files changed, 47 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c > create mode 100644 gcc/testsuite/gcc.dg/fold-popcount-8a.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index ce8d159d260..f725a685863 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -8600,7 +8600,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > /* popcount(X&Y) + popcount(X|Y) is popcount(x) + popcount(Y). */ > (simplify > (plus:c (POPCOUNT:s (bit_and:s @0 @1)) (POPCOUNT:s (bit_ior:cs @0 @1))) > - (plus (POPCOUNT @0) (POPCOUNT @1))) > + (plus (POPCOUNT:type @0) (POPCOUNT:type @1))) > > /* popcount(X) + popcount(Y) - popcount(X&Y) is popcount(X|Y). */ > /* popcount(X) + popcount(Y) - popcount(X|Y) is popcount(X&Y). */ > diff --git a/gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c > b/gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c > new file mode 100644 > index 00000000000..d3d3a2976e0 > --- /dev/null > +++ b/gcc/testsuite/gcc.c-torture/compile/fold-popcount-1.c > @@ -0,0 +1,13 @@ > +/* PR tree-optimization/111913 */ > + > +int f(unsigned int x, unsigned int y) > +{ > + return __builtin_popcount (x&y) + __builtin_popcount (y|x--); > +} > + > +int f2(unsigned int x, unsigned int y) > +{ > + int t = __builtin_popcount (x&y); > + int t1 = __builtin_popcount (x|y); > + return t + t1; > +} > diff --git a/gcc/testsuite/gcc.dg/fold-popcount-8a.c > b/gcc/testsuite/gcc.dg/fold-popcount-8a.c > new file mode 100644 > index 00000000000..3001522f259 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/fold-popcount-8a.c > @@ -0,0 +1,33 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > + > +int foo1(unsigned int x, unsigned int y) > +{ > + int t = __builtin_popcount (x&y); > + int t1 = __builtin_popcount (x|y); > + return t + t1; > +} > + > +int foo2(unsigned int x, unsigned int y) > +{ > + int t1 = __builtin_popcount (x|y); > + int t = __builtin_popcount (x&y); > + return t + t1; > +} > + > +int foo3(unsigned int y, unsigned int x) > +{ > + int t = __builtin_popcount (x&y); > + int t1 = __builtin_popcount (x|y); > + return t + t1; > +} > + > +int foo4(unsigned int y, unsigned int x) > +{ > + int t1 = __builtin_popcount (x|y); > + int t = __builtin_popcount (x&y); > + return t + t1; > +} > + > +/* { dg-final { scan-tree-dump-not " & " "optimized" } } */ > +/* { dg-final { scan-tree-dump-not " \\| " "optimized" } } */ > -- > 2.39.3 >