From: Jakub Jelinek Date: Fri, 5 Jun 2026 15:16:59 +0000 (+0200) Subject: store-merging, riscv: Consider widen_bswap_or_bitreverse in store-merging decisions... X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=997a8a9bb85b615e9c1ec7fed802e203a6aaa4a3;p=thirdparty%2Fgcc.git store-merging, riscv: Consider widen_bswap_or_bitreverse in store-merging decisions and fix up riscv build On Fri, Jun 05, 2026 at 02:22:25PM +0200, Andreas Schwab wrote: > This breaks riscv: > > ../../gcc/config/riscv/riscv.md:5297:14: error: bswapsi2 cannot FAIL > ../../gcc/config/riscv/bitmanip.md:543:5: note: in expansion of macro 'FAIL' > 543 | FAIL; > | ^~~~ wtw mentioned that on IRC. In the way IFN_BSWAP/IFN_BITREVERSE are used currently (i.e. only used for large/huge _BitInt or in the C++ FE, but not making it to expansion) there is no reason why FAIL wouldn't be allowed (like before my changes), though I find the riscv hack really ugly. Instead of adding a workaround, this patch removes the riscv hack and instead adjusts store-merging pass to take into account widen_bswap_or_bitreverse; currently it already takes into account expand_doubleword_bswap_or_bitreverse (on 32-bit word targets which have bswapsi2 expanders expects __builtin_bswap64 to be cheap). With this patch, it expects __builtin_bswap32 to be cheap if bswapdi2 expander is present, because widen_bswap_or_bitreverse will handle it as (subreg:SI (lshiftrt:DI (bswap:DI (subreg:DI (arg:SI) 0)) (const_int 32)) low) 2026-06-05 Jakub Jelinek * 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. Reviewed-by: Richard Sandiford Reviewed-by: Richard Biener --- diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 05559405fcc..bd2aaf0587e 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -533,16 +533,7 @@ (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; -}) - + "(!TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)) || TARGET_XTHEADBB") (define_insn "*bswap2" [(set (match_operand:X 0 "register_operand" "=r") diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc index 96fd9fa73a3..2e5232fa65f 100644 --- a/gcc/gimple-ssa-store-merging.cc +++ b/gcc/gimple-ssa-store-merging.cc @@ -1570,7 +1570,10 @@ maybe_optimize_vector_constructor (gimple *cur_stmt) break; case 32: if (builtin_decl_explicit_p (BUILT_IN_BSWAP32) - && optab_handler (bswap_optab, SImode) != CODE_FOR_nothing) + && (optab_handler (bswap_optab, SImode) != CODE_FOR_nothing + /* widen_bswap_or_bitreverse can implement 32-bit bswap + using bswapdi2 and shift. */ + || optab_handler (bswap_optab, DImode) != CODE_FOR_nothing)) { load_type = uint32_type_node; fndecl = builtin_decl_explicit (BUILT_IN_BSWAP32); @@ -1582,6 +1585,8 @@ maybe_optimize_vector_constructor (gimple *cur_stmt) case 64: if (builtin_decl_explicit_p (BUILT_IN_BSWAP64) && (optab_handler (bswap_optab, DImode) != CODE_FOR_nothing + /* expand_doubleword_bswap_or_bitreverse can use 2 bswapsi2 + expanders on 32-bit targets. */ || (word_mode == SImode && builtin_decl_explicit_p (BUILT_IN_BSWAP32) && optab_handler (bswap_optab, SImode) != CODE_FOR_nothing))) @@ -1631,9 +1636,15 @@ pass_optimize_bswap::execute (function *fun) tree bswap32_type = NULL_TREE, bswap64_type = NULL_TREE; bswap32_p = (builtin_decl_explicit_p (BUILT_IN_BSWAP32) - && optab_handler (bswap_optab, SImode) != CODE_FOR_nothing); + && (optab_handler (bswap_optab, SImode) != CODE_FOR_nothing + /* widen_bswap_or_bitreverse can implement 32-bit bswap + using bswapdi2 and shift. */ + || (optab_handler (bswap_optab, DImode) + != CODE_FOR_nothing))); bswap64_p = (builtin_decl_explicit_p (BUILT_IN_BSWAP64) && (optab_handler (bswap_optab, DImode) != CODE_FOR_nothing + /* expand_doubleword_bswap_or_bitreverse can use 2 bswapsi2 + expanders on 32-bit targets. */ || (bswap32_p && word_mode == SImode))); /* Determine the argument type of the builtins. The code later on