]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Use can_open_code_p in gimple-ssa-store-merging
authorRichard Sandiford <rdsandiford@googlemail.com>
Sat, 6 Jun 2026 08:16:13 +0000 (09:16 +0100)
committerRichard Sandiford <rdsandiford@googlemail.com>
Sat, 6 Jun 2026 08:16:13 +0000 (09:16 +0100)
...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.

gcc/gimple-ssa-store-merging.cc
gcc/optabs-query.cc

index 2e5232fa65fff802e69126a679aca9e841d27811..71cb7d8031a77e44c3b1703b0955a35a4dd1d932 100644 (file)
@@ -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:
index e596d8db88131fbf8381c83d505ddeb1053ee7e2..8226356c7d40c3193b9e57681f56e3e8535a0184 100644 (file)
@@ -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;
 }