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
>

Reply via email to