https://gcc.gnu.org/g:74bca21db31e3f4ab6543b56c3f26b4dfe586fef

commit r14-9453-g74bca21db31e3f4ab6543b56c3f26b4dfe586fef
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Mar 13 15:34:59 2024 +0100

    store-merging: Match bswap64 on 32-bit targets with bswapsi2 [PR114319]
    
    gimple-ssa-store-merging.cc tests bswap_optab in 3 different places,
    in 2 of them it has special exception for double-word bswap using pair
    of word-mode bswap optabs, but in the last one it doesn't.
    
    The following patch changes even the last spot.
    We don't handle 128-bit bswaps in the passes at all, because currently we
    just use uint64_t to represent the byte reshuffling (we'd need to use
    offset_int or something like that instead) and we don't have
    __builtin_bswap128 nor type-generic __builtin_bswap, so there is nothing
    for 64-bit targets there.
    
    2024-03-13  Jakub Jelinek  <ja...@redhat.com>
    
            PR middle-end/114319
            * gimple-ssa-store-merging.cc
            (imm_store_chain_info::try_coalesce_bswap): For 32-bit targets
            allow matching __builtin_bswap64 if there is bswapsi2 optab.
    
            * gcc.target/i386/pr114319.c: New test.

Diff:
---
 gcc/gimple-ssa-store-merging.cc          |  5 ++++-
 gcc/testsuite/gcc.target/i386/pr114319.c | 19 +++++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc
index 42b68abf61b..cb0cb5f42f6 100644
--- a/gcc/gimple-ssa-store-merging.cc
+++ b/gcc/gimple-ssa-store-merging.cc
@@ -3051,7 +3051,10 @@ imm_store_chain_info::try_coalesce_bswap 
(merged_store_group *merged_store,
        return false;
       case 64:
        if (builtin_decl_explicit_p (BUILT_IN_BSWAP64)
-           && optab_handler (bswap_optab, DImode) != CODE_FOR_nothing)
+           && (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)))
          break;
        return false;
       default:
diff --git a/gcc/testsuite/gcc.target/i386/pr114319.c 
b/gcc/testsuite/gcc.target/i386/pr114319.c
new file mode 100644
index 00000000000..75175f4b2ac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr114319.c
@@ -0,0 +1,19 @@
+/* PR middle-end/114319 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att -mno-movbe" } */
+/* { dg-additional-options "-march=i486" { target ia32 } } */
+/* { dg-final { scan-assembler-times "\tbswap\t%r" 1 { target { ! ia32 } } } } 
*/
+/* { dg-final { scan-assembler-times "\tbswap\t%\[er]" 2 { target ia32 } } } */
+
+void
+foo (unsigned long long x, unsigned char *y)
+{
+  y[0] = x >> 56;
+  y[1] = x >> 48;
+  y[2] = x >> 40;
+  y[3] = x >> 32;
+  y[4] = x >> 24;
+  y[5] = x >> 16;
+  y[6] = x >> 8;
+  y[7] = x;
+}

Reply via email to