On Sat, May 16, 2026 at 1:37 AM Jakub Jelinek <[email protected]> wrote:
>
> Hi!
>
> Most of the bswap optimizations equally apply also to bitreverse builtins.
> The following patch enables those.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2026-05-16 Jakub Jelinek <[email protected]>
>
> PR target/50481
> * match.pd (BITREVERSE): New define_operator_list. Use it next to
> BSWAP for a subset of bswap simplifications.
>
> * gcc.dg/builtin-bitreverse-4.c: New test.
Ok.
>
> --- gcc/match.pd.jj 2026-05-14 09:51:59.594625313 +0200
> +++ gcc/match.pd 2026-05-15 11:53:24.990684990 +0200
> @@ -55,6 +55,8 @@ (define_operator_list simple_comparison
> (define_operator_list swapped_simple_comparison gt ge eq ne le lt)
> (define_operator_list BSWAP BUILT_IN_BSWAP16 BUILT_IN_BSWAP32
> BUILT_IN_BSWAP64 BUILT_IN_BSWAP128)
> +(define_operator_list BITREVERSE BUILT_IN_BITREVERSE16 BUILT_IN_BITREVERSE32
> + BUILT_IN_BITREVERSE64 BUILT_IN_BITREVERSE128)
>
> #include "cfn-operators.pd"
>
> @@ -5712,7 +5714,7 @@ (define_operator_list SYNC_FETCH_AND_AND
> (complex (convert:itype @0) (negate (convert:itype @1)))))
>
> /* BSWAP simplifications, transforms checked by gcc.dg/builtin-bswap-8.c. */
> -(for bswap (BSWAP)
> +(for bswap (BSWAP BITREVERSE)
> (simplify
> (bswap (bswap @0))
> @0)
> @@ -5731,7 +5733,8 @@ (define_operator_list SYNC_FETCH_AND_AND
> (simplify
> (cmp (bswap @0) INTEGER_CST@1)
> (with { tree ctype = TREE_TYPE (@1); }
> - (cmp (convert:ctype @0) (bswap! @1)))))
> + (cmp (convert:ctype @0) (bswap! @1))))))
> +(for bswap (BSWAP)
> /* (bswap(x) >> C1) & C2 can sometimes be simplified to (x >> C3) & C2. */
> (simplify
> (bit_and (convert1? (rshift@0 (convert2? (bswap@4 @1)) INTEGER_CST@2))
> --- gcc/testsuite/gcc.dg/builtin-bitreverse-4.c.jj 2026-05-15
> 11:56:13.129812194 +0200
> +++ gcc/testsuite/gcc.dg/builtin-bitreverse-4.c 2026-05-15 11:58:28.975498650
> +0200
> @@ -0,0 +1,54 @@
> +/* { dg-do compile { target int32 } } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +#define BS(X) __builtin_bitreverse32 (X)
> +
> +unsigned
> +foo1 (unsigned a)
> +{
> + return BS (~ BS (a));
> +}
> +
> +unsigned
> +foo2 (unsigned a)
> +{
> + return BS (BS (a) & 0xA0000);
> +}
> +
> +unsigned
> +foo3 (unsigned a)
> +{
> + return BS (BS (a) | 0xA0000);
> +}
> +
> +unsigned
> +foo4 (unsigned a)
> +{
> + return BS (BS (a) ^ 0xA0000);
> +}
> +
> +unsigned
> +foo5 (unsigned a, unsigned b)
> +{
> + return BS (BS (a) & BS (b));
> +}
> +
> +unsigned
> +foo6 (unsigned a, unsigned b)
> +{
> + return BS (BS (a) | BS (b));
> +}
> +
> +unsigned
> +foo7 (unsigned a, unsigned b)
> +{
> + return BS (BS (a) ^ BS (b));
> +}
> +
> +unsigned
> +foo8 (unsigned a)
> +{
> + return BS (BS (BS (BS (a))));
> +}
> +
> +/* { dg-final { scan-tree-dump-not "__builtin_bitreverse" "optimized" } } */
>
> Jakub
>