https://gcc.gnu.org/g:cc58cf0d2f9b255e29d9b7a409c5ab31542604d1
commit r17-1390-gcc58cf0d2f9b255e29d9b7a409c5ab31542604d1 Author: Richard Sandiford <[email protected]> Date: Sat Jun 6 09:16:13 2026 +0100 Use can_open_code_p in gimple-ssa-store-merging ...and extend can_open_code_p to handle bswap. I'm not sure that the removed builtin_decl_explicit_p (BUILT_IN_BSWAP32) calls are necessary, since the code would go on to use a BSWAP64 rather than a BSWAP32. This fixes gcc.dg/optimize-bswapsi-6.c on RISC-V. gcc/ * optabs-query.cc (can_open_code_p): Handle more bswap cases, incorporating logic from... * gimple-ssa-store-merging.cc (maybe_optimize_vector_constructor) (pass_optimize_bswap::execute) (imm_store_chain_info::try_coalesce_bswap): ...here. Use can_open_code_p instead of direct optab_handler checks. Diff: --- gcc/gimple-ssa-store-merging.cc | 30 ++++++------------------------ gcc/optabs-query.cc | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc index 2e5232fa65ff..71cb7d8031a7 100644 --- a/gcc/gimple-ssa-store-merging.cc +++ b/gcc/gimple-ssa-store-merging.cc @@ -1570,10 +1570,7 @@ 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 - /* widen_bswap_or_bitreverse can implement 32-bit bswap - using bswapdi2 and shift. */ - || optab_handler (bswap_optab, DImode) != CODE_FOR_nothing)) + && can_open_code_p (bswap_optab, SImode)) { load_type = uint32_type_node; fndecl = builtin_decl_explicit (BUILT_IN_BSWAP32); @@ -1584,12 +1581,7 @@ maybe_optimize_vector_constructor (gimple *cur_stmt) break; 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))) + && can_open_code_p (bswap_optab, DImode)) { load_type = uint64_type_node; fndecl = builtin_decl_explicit (BUILT_IN_BSWAP64); @@ -1636,16 +1628,9 @@ 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 - /* widen_bswap_or_bitreverse can implement 32-bit bswap - using bswapdi2 and shift. */ - || (optab_handler (bswap_optab, DImode) - != CODE_FOR_nothing))); + && can_open_code_p (bswap_optab, SImode)); 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))); + && can_open_code_p (bswap_optab, DImode)); /* Determine the argument type of the builtins. The code later on assumes that the return and argument type are the same. */ @@ -3145,15 +3130,12 @@ imm_store_chain_info::try_coalesce_bswap (merged_store_group *merged_store, break; case 32: if (builtin_decl_explicit_p (BUILT_IN_BSWAP32) - && optab_handler (bswap_optab, SImode) != CODE_FOR_nothing) + && can_open_code_p (bswap_optab, SImode)) break; return false; case 64: if (builtin_decl_explicit_p (BUILT_IN_BSWAP64) - && (optab_handler (bswap_optab, DImode) != CODE_FOR_nothing - || (word_mode == SImode - && builtin_decl_explicit_p (BUILT_IN_BSWAP32) - && optab_handler (bswap_optab, SImode) != CODE_FOR_nothing))) + && can_open_code_p (bswap_optab, DImode)) break; return false; default: diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc index e596d8db8813..8226356c7d40 100644 --- a/gcc/optabs-query.cc +++ b/gcc/optabs-query.cc @@ -840,6 +840,23 @@ can_open_code_p (optab op, machine_mode mode) && can_implement_p (op == neg_optab ? xor_optab : and_optab, new_mode)) return true; + scalar_int_mode int_mode; + if (op == bswap_optab && is_a<scalar_int_mode> (mode, &int_mode)) + { + /* widen_bswap_or_bitreverse can implement smaller bswaps using + wider bswaps and a shift. */ + opt_scalar_int_mode wider_mode_iter; + FOR_EACH_WIDER_MODE (wider_mode_iter, int_mode) + if (optab_handler (op, wider_mode_iter.require ()) != CODE_FOR_nothing) + return true; + + /* expand_doubleword_bswap_or_bitreverse can use 2 word bswaps to + implement a doubleword bswap. */ + if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD + && optab_handler (op, word_mode) != CODE_FOR_nothing) + return true; + } + return false; }
