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. --- 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
