Message ID | 20231023230348.606997-1-pinskia@gmail.com |
---|---|
State | New |
Headers | show |
Series | match: Fix the `popcnt(a&b) + popcnt(a|b)` patthern for types [PR111913] | expand |
On Tue, Oct 24, 2023 at 1:04 AM Andrew Pinski <pinskia@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 >
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" } } */