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 <jakub@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.
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:
--- /dev/null
+/* 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;
+}