On 8/8/2026 9:24 AM, Roger Sayle wrote:
My recent patch to improve bitreverse support on cris, posted at https://gcc.gnu.org/pipermail/gcc-patches/2026-August/726384.html revealed an optimization opportunity. If you look closely GCC's expansion of bitreverse (in optabs.cc) generates a left shift followed by an IOR in several places. In these instances, its possible to use "any_or_plus", and in fact using PLUS would allow cris to use its addi instruction, and the x86 to use its lea instruction. I believe PLUS is always as efficient as IOR for SImode/wordmode, even on processors that have to use add with carry, i.e. addc[qh]i3. For other (longer) modes (such as vector modes), it's better to use IOR, and for shorter modes I'm not sure there's any advantage to using PLUS. If I'm wrong for some targets, we can make aop_optab a real optab. Previously on x86_64, with -O2 the following function: unsigned int foo(unsigned int x) { return __builtin_bitreverse32 (x); } used to generate: foo: movl %edi, %eax bswap %eax movl %eax, %edi andl $252645135, %eax shrl $4, %edi sall $4, %eax andl $252645135, %edi orl %eax, %edi movl %edi, %edx andl $858993459, %edi shrl $2, %edx sall $2, %edi andl $858993459, %edx orl %edi, %edx movl %edx, %eax andl $1431655765, %edx shrl $1, %eax addl %edx, %edx andl $1431655765, %eax orl %edx, %eax ret with this patch we instead generate: foo: bswap %edi movl %edi, %eax andl $252645135, %edi shrl $4, %eax sall $4, %edi andl $252645135, %eax addl %edi, %eax movl %eax, %edx andl $858993459, %eax shrl $2, %edx andl $858993459, %edx leal (%rdx,%rax,4), %eax movl %eax, %edx andl $1431655765, %eax shrl $1, %edx andl $1431655765, %edx leal (%rdx,%rax,2), %eax ret which is three instructions shorter. This patch also contains another transformation (to help bitreverse on cris) which is for simplify-rtx and combine to canonicalize bswap(bitreverse x) as bitreverse(bswap x). The two forms are equivalent, so canonicalizing simplifies machine descriptions. The (otherwise arbitrary) choice to perform BSWAP first, is (1) to aid targets like powerpc that can perform bswap on load and (2) to place bswap next to bswap on targets that RTL split bitreverse in a similar order to GCC's default optab expansion above. This patch has been tested on x86_64-pc-linux-gnu with make bootstrap and make -k check, both with and without --target_board=unix{-m32} with no new failures. Ok for mainline? 2026-08-08 Roger Sayle <[email protected]> gcc/ChangeLog * optab.cc (expand_bitreverse): Use PLUS instead of IOR when composing swapped bits and nibbles (allows use of shift_add). * simplify-rtx.cc (simplify_unary_operation_1) <case BSWAP>: Canonicalize (BSWAP (BITREVERSE x)) as (BITREVERSE (BSWAP x)). gcc/testsuite/ChangeLog * gcc.target/i386/builtin-bitreverse-1.c: New test case.
So the only concern I have is the special casing of SImode in the optabs.cc change. I wonder if we could query if we have addsi?
FWIW, it saves an instruction on RISC-V as well as the new sequence exposes a sh2add instead of slliw+or. Which means this likely helps other targets with shNadd insns.
jeff
