On 6/5/2026 7:50 AM, Jakub Jelinek wrote:
On Fri, Jun 05, 2026 at 02:06:44PM +0100, Richard Sandiford wrote:
Yeah, agreed. Namely:
(define_expand "bswapsi2"
[(set (match_operand:SI 0 "register_operand")
(bswap:SI (match_operand:SI 1 "register_operand")))]
"TARGET_ZBB || TARGET_ZBKB || TARGET_XTHEADBB"
{
/* Expose bswapsi2 on TARGET_64BIT so that the gimple store
merging pass will create suitable bswap insns. We can actually
just FAIL that case when generating RTL and let the generic code
handle it. */
if (TARGET_64BIT && !TARGET_XTHEADBB)
FAIL;
})
I don't think that's a good enough justification for an exception
like this. Even a target hook that says "is bswap cheap?" would IMO
be better than the above (and could default to "is bswap implemented?").
But hopefully the hook could be generalised a bit. For example, maybe
the hook could be a wrapper around:
/* Return true if we can implement OP for mode MODE directly, without resorting
to a libfunc. This usually means that OP will be implemented inline.
Note that this function cannot tell whether the target pattern chooses to
use libfuncs internally. */
bool
can_open_code_p (optab op, machine_mode mode)
and additionally test for "cheapness".
In this particular case it is about widen_bswap_or_bitreverse (or e.g. for
clz/clrsb also for widen_leading).
Now, store merging already has hacks which consider
expand_doubleword_bswap_or_bitreverse implementing for 32-bit targets
bswapdi2 using 2 bswapsi2 expanders, so I think we can do the same for
bswapsi2 using bswapdi2 and right shift.
I don't have setup to test this on riscv, but can test on x86_64/i686.
2026-06-05 Jakub Jelinek <[email protected]>
* gimple-ssa-store-merging.cc (maybe_optimize_vector_constructor):
Also support bswap32 if bswapdi2 expander is present. Add comment
about bswap64 support on 32-bit targets with bswapsi2 expander.
(pass_optimize_bswap::execute): Likewise.
* config/riscv/bitmanip.md (bswapsi2): Change condition to disable
the expander on TARGET_64BIT without TARGET_XTHEADBB, never FAIL.
Mostly OK. THough it does fail pretty miserably on optimize-bswapsi-6.c
when compiled with -march=rv64gcb (rv64gcb is common these days):
jlaw@x11-dpi:~/test/obj/rv/gcc/gcc$ make check-gcc
RUNTESTFLAGS="--target_board=unix/-march=rv64gcb
dg.exp=optimize-bswapsi-6.c"
rm -rf testsuite/gcc-parallel
make[1]: Entering directory '/home/jlaw/test/obj/rv/gcc/gcc'
(rootme=`${PWDCMD-pwd}`; export rootme; \
srcdir=`cd /home/jlaw/test/gcc/gcc; ${PWDCMD-pwd}` ; export srcdir ; \
if [ -n "" ] \
&& [ -n "$GCC_RUNTEST_PARALLELIZE_DIR" ] \
&& [ -f testsuite/gcc-parallel/finished ]; then \
rm -rf testsuite/gcc; \
else \
cd testsuite/gcc; \
rm -f tmp-site.exp; \
sed '/set tmpdir/ s|testsuite$|testsuite/gcc|' \
< ../../site.exp > tmp-site.exp; \
/bin/bash ${srcdir}/../move-if-change tmp-site.exp site.exp; \
EXPECT=expect ; export EXPECT ; \
if [ -f ${rootme}/../expect/expect ] ; then \
TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWDCMD-pwd}` ; \
export TCL_LIBRARY ; \
fi ; \
`if [ -f ${srcdir}/../dejagnu/runtest ] ; then echo
${srcdir}/../dejagnu/runtest ; else echo runtest; fi` --tool gcc
--target_board=unix/-march=rv64gcb dg.exp=optimize-bswapsi-6.c; \
if [ -n "$GCC_RUNTEST_PARALLELIZE_DIR" ] ; then \
touch ${rootme}/testsuite/gcc-parallel/finished; \
fi ; \
fi )
Using /home/jlaw/test/gcc/gcc/testsuite/lib/gcc.exp as tool init file.
Test run by jlaw on Fri Jun 5 11:27:04 2026
Target is riscv64-unknown-elf
Host is x86_64-pc-linux-gnu
=== gcc tests ===
Schedule of variations:
unix/-march=rv64gcb
Running target unix/-march=rv64gcb
Using /usr/share/dejagnu/baseboards/unix.exp as board description file
for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for
target.
Using /home/jlaw/test/gcc/gcc/testsuite/config/default.exp as
tool-and-target-specific interface file.
WARNING: Assuming target board is the local machine (which is probably
wrong).
You may need to set your DEJAGNU environment variable.
Running /home/jlaw/test/gcc/gcc/testsuite/gcc.dg/dg.exp ...
FAIL: gcc.dg/optimize-bswapsi-6.c scan-tree-dump store-merging "32 bit
bswap implementation found at"
=== gcc Summary ===
# of expected passes 1
# of unexpected failures 1
/home/jlaw/test/obj/rv/gcc/gcc/xgcc version 17.0.0 20260604
(experimental) (GCC)
The net difference on the assembly for this case looks like:
! rev8 a0,a0
! srai a0,a0,32
Turns into:
! srli a5,a0,16
! rev8 a4,a0
! andi a5,a5,255
! srliw a0,a0,24
! slli a5,a5,8
! srli a4,a4,48
! or a5,a5,a0
! slliw a0,a4,16
! or a0,a0,a5