Jakub Jelinek <[email protected]> writes:
> On Fri, Jun 05, 2026 at 07:09:39PM +0100, Richard Sandiford wrote:
>> Since this is kind-of my fault for pushing back against Jakub's
>> original fix, how about the attached?  It seems to fix the testcase
>> above but I've still to check whether that's through fair means or foul.
>> 
>> 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.
>> 
>> Untested except for the testcase above, but I've cc:ed the patch checker.
>> 
>> Richard
>> 
>> 
>> 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 | 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 2e5232fa65f..bd16489f30e 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_implement_p (bswap_optab, SImode))
>
> I think we really want can_open_code_p in all the
> gimple-ssa-store-merging.cc spots.  Libcall isn't going to be a good idea
> compared to just multiple loads/stores IMHO.

Oops, yes.  As per the change-log, that's what I'd intended.  Guess in
the rush I must have copy-&-pasted the wrong name :(

Sorry for the mix-up.

>> --- 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))
>
> Not related to this patch, but I wonder if the above shouldn't actually be
> can_open_code_p rather than can_implement_p...

Yeah, probably, but I'll look at it when it isn't Friday evening.

>
>>      return true;
>>  
>> +  scalar_int_mode int_mode;
>> +  if (op == bswap_optab && is_a<scalar_int_mode> (mode, &int_mode))
>
> Why not (op == bswap_optab || op == bitreverse_optab) when we are at it?

I'd wondered about that, but in the circumstances, it seemed better
not to start adding things that wouldn't be tested.

I can add it if you prefer though.

Anyway, here's the patch again with the right function name.
I've changed the subject line because I think the patch checker
might have ignored the last version.

Richard


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 | 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 2e5232fa65f..71cb7d8031a 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 e596d8db881..8226356c7d4 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;
 }
 
-- 
2.54.0

Reply via email to