gnu/gcc/573600a8073b413ba3946fd0362150690eee1d59 bitintlower: Improve __builtin_{clz,ctz,clrsb,ffs,parity,popcount,bswap,bitreverse}g lowering
I've noticed that we emit terrible code for the following testcase (all
functions). We copy the _BitInt values from memory to a temporary and
perform the bit query or bswap/bitreverse operations on the temporary when
it could be done on the value in memory directly, and for bswap/bitreverse
we can also merge it with a following store to (non-bitfield) memory.
The only exception is that we need some temporary for the
x = __builtin_{bswap,bitreverse}g (x);
cases, when they load from the same memory as they store to. Because the
implementation loops over all the limbs and swaps them, we need one
temporary in that case. This is similar to e.g. multiplication/division.
The bit-query ifns return a small integer scalar, so they don't need any
merging with a store.
The following patch implements this.
2026-06-05 Jakub Jelinek <jakub@redhat.com>
* gimple-lower-bitint.cc (bitint_large_huge::lower_bswap_bitreverse):
Add OBJ argument, use it instead of m_vars[part] if non-NULL. Don't
gsi_remove stmt.
(bitint_large_huge::lower_call): Adjust caller.
(bitint_large_huge::lower_stmt): Handle store of
IFN_BSWAP/IFN_BITREVERSE result.
(stmt_needs_operand_addr): Return true also for
IFN_BSWAP/IFN_BITREVERSE.
(build_bitint_stmt_ssa_conflicts): Formatting fix.
(gimple_lower_bitint): Allow merging IFN_BSWAP/IFN_BITREVERSE with
subsequent non-bitfield store. Allow merging load of
IFN_{CLZ,CTZ,CLRSB,FFS,PARITY,POPCOUNT,BSWAP,BITREVERSE} argument
with the call.
* gcc.dg/bitint-137.c: New test.
Reviewed-by: Richard Biener <rguenth@suse.de>
2 files changed