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;
 }

Reply via email to