<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/54658>54658</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Sub-optimal code generation for consecutive shuffles on x86 AVX512
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          daniellustig
      </td>
    </tr>
</table>

<pre>
    Two more patterns of back-to-back shuffles that generate sub-optimal code for AVX512, similar to #54562

Both compiled with
```
clang++ <file.ll> -c -o <file.o> -O3 -march=skylake-avx512 -mprefer-vector-width=512
```

Case 1: back to back shuffles cause sub-optimal code generation
[two_shuffles.ll.txt](https://github.com/llvm/llvm-project/files/8384329/two_shuffles.ll.txt)

```
define external <16 x i32> @both(<64 x i8> %a) #0 {
BB0:
  %0 = shufflevector <64 x i8> %a, <64 x i8> poison,
       <64 x i32> <i32 1, i32 3, i32 2, i32 5, i32 7, i32 6, i32 9, i32 11, i32 10, i32 13, i32 15, i32 14, i32 undef, i32 undef, i32 undef, i32 undef,
                   i32 17, i32 19, i32 18, i32 21, i32 23, i32 22, i32 25, i32 27, i32 26, i32 29, i32 31, i32 30, i32 undef, i32 undef, i32 undef, i32 undef,
                   i32 33, i32 35, i32 34, i32 37, i32 39, i32 38, i32 41, i32 43, i32 42, i32 45, i32 47, i32 46, i32 undef, i32 undef, i32 undef, i32 undef,
                   i32 49, i32 51, i32 50, i32 53, i32 55, i32 54, i32 57, i32 59, i32 58, i32 61, i32 63, i32 62, i32 undef, i32 undef, i32 undef, i32 undef>
  %1 = bitcast <64 x i8> %0 to <16 x i32>
  %2 = shufflevector <16 x i32> %1, <16 x i32> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 4, i32 5, i32 6, i32 8, i32 9, i32 10, i32 12, i32 13, i32 14, i32 0, i32 0, i32 0, i32 0>
  ret <16 x i32> %2
}
```

```
0000000000000000 <both>:
   0: 62 f3 fd 48 3b c1 01  vextracti64x4 ymm1,zmm0,0x1
   7: c4 e2 71 00 15 00 00  vpshufb xmm2,xmm1,XMMWORD PTR [rip+0x0]        # 10 <both+0x10>
   e: 00 00
  10: c4 e3 75 46 d8 21     vperm2i128 ymm3,ymm1,ymm0,0x21
  16: c4 e2 65 00 1d 00 00  vpshufb ymm3,ymm3,YMMWORD PTR [rip+0x0]        # 1f <both+0x1f>
  1d: 00 00
  1f: c4 e3 65 02 d2 01     vpblendd ymm2,ymm3,ymm2,0x1
  25: c4 e2 71 00 0d 00 00  vpshufb xmm1,xmm1,XMMWORD PTR [rip+0x0]        # 2e <both+0x2e>
  2c: 00 00
  2e: c4 e3 7d 39 c3 01     vextracti128 xmm3,ymm0,0x1
  34: c4 e2 61 00 1d 00 00  vpshufb xmm3,xmm3,XMMWORD PTR [rip+0x0]        # 3d <both+0x3d>
  3b: 00 00
  3d: c4 e3 7d 38 c9 01     vinserti128 ymm1,ymm0,xmm1,0x1
  43: c4 e2 7d 00 05 00 00  vpshufb ymm0,ymm0,YMMWORD PTR [rip+0x0]        # 4c <both+0x4c>
  4a: 00 00
  4c: c4 e3 7d 02 c3 08     vpblendd ymm0,ymm0,ymm3,0x8
  52: c4 e3 7d 02 c1 c0     vpblendd ymm0,ymm0,ymm1,0xc0
  58: 62 f3 fd 48 3a c2 01  vinserti64x4 zmm0,zmm0,ymm2,0x1
  5f: c3                    ret

0000000000000060 <first>:
  60: 62 f2 7d 48 00 05 00  vpshufb zmm0,zmm0,ZMMWORD PTR [rip+0x0]        # 6a <first+0xa>
  67: 00 00 00
  6a: c3                    ret
  6b: 0f 1f 44 00 00        nop    DWORD PTR [rax+rax*1+0x0]

0000000000000070 <second>:
  70: 62 f1 7c 48 28 0d 00  vmovaps zmm1,ZMMWORD PTR [rip+0x0]        # 7a <second+0xa>
  77: 00 00 00
  7a: 62 f2 75 48 16 c0     vpermps zmm0,zmm1,zmm0
  80: c3                    ret
```

Case 2: replacing the `store <64 x i8>` with `ret <64 x i8>` causes a sub-optimal shuffle pattern.
[ret_store.ll.txt](https://github.com/llvm/llvm-project/files/8384330/ret_store.ll.txt)

```
define external void @using_store(<64 x i8>* nocapture nonnull readonly align 512 dereferenceable(512) %a,
                                  <64 x i8>* nocapture nonnull readonly align 512 dereferenceable(512) %b,
                                  <64 x i8>* nocapture nonnull align 512 dereferenceable(512) %c) #0 {
BB0:
  %0 = load <64 x i8>, <64 x i8>* %a, align 512
  %1 = load <64 x i8>, <64 x i8>* %b, align 512
  %2 = shufflevector <64 x i8> %0, <64 x i8> poison,
        <64 x i32> <i32 1, i32 3, i32 2, i32 5, i32 7, i32 6, i32 9, i32 11, i32 10, i32 13, i32 15, i32 14, i32 undef, i32 undef, i32 undef, i32 undef,
                    i32 17, i32 19, i32 18, i32 21, i32 23, i32 22, i32 25, i32 27, i32 26, i32 29, i32 31, i32 30, i32 undef, i32 undef, i32 undef, i32 undef,
                    i32 33, i32 35, i32 34, i32 37, i32 39, i32 38, i32 41, i32 43, i32 42, i32 45, i32 47, i32 46, i32 undef, i32 undef, i32 undef, i32 undef,
                    i32 49, i32 51, i32 50, i32 53, i32 55, i32 54, i32 57, i32 59, i32 58, i32 61, i32 63, i32 62, i32 undef, i32 undef, i32 undef, i32 undef>
  %3 = shufflevector <64 x i8> %1, <64 x i8> poison,
       <64 x i32> <i32 1, i32 0, i32 2, i32 5, i32 4, i32 6, i32 9, i32 8, i32 10, i32 13, i32 12, i32 14, i32 undef, i32 undef, i32 undef, i32 undef,
                   i32 17, i32 16, i32 18, i32 21, i32 20, i32 22, i32 25, i32 24, i32 26, i32 29, i32 28, i32 30, i32 undef, i32 undef, i32 undef, i32 undef,
                   i32 33, i32 32, i32 34, i32 37, i32 36, i32 38, i32 41, i32 40, i32 42, i32 45, i32 44, i32 46, i32 undef, i32 undef, i32 undef, i32 undef,
                   i32 49, i32 48, i32 50, i32 53, i32 52, i32 54, i32 57, i32 56, i32 58, i32 61, i32 60, i32 62, i32 undef, i32 undef, i32 undef, i32 undef>
  %4 = or <64 x i8> %2, %3
  %5 = bitcast <64 x i8> %4 to <16 x i32>
  %6 = shufflevector <16 x i32> %5, <16 x i32> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 4, i32 5, i32 6, i32 8, i32 9, i32 10, i32 12, i32 13, i32 14, i32 0, i32 0, i32 0, i32 0>
  %7 = bitcast <16 x i32> %6 to <64 x i8>

  store <64 x i8> %7, <64 x i8>* %c, align 512
  ret void
}
```

```
0000000000000000 <using_store>:
   0: 62 f1 fd 48 6f 07     vmovdqa64 zmm0,ZMMWORD PTR [rdi]
   6: 62 f1 fd 48 6f 0e     vmovdqa64 zmm1,ZMMWORD PTR [rsi]
   c: 62 f2 7d 48 00 05 00  vpshufb zmm0,zmm0,ZMMWORD PTR [rip+0x0]        # 16 <using_store+0x16>
  13: 00 00 00
  16: 62 f2 75 48 00 0d 00  vpshufb zmm1,zmm1,ZMMWORD PTR [rip+0x0]        # 20 <using_store+0x20>
  1d: 00 00 00
  20: 62 f1 f5 48 eb c0     vporq  zmm0,zmm1,zmm0
  26: 62 f1 fd 48 6f 0d 00  vmovdqa64 zmm1,ZMMWORD PTR [rip+0x0]        # 30 <using_store+0x30>
  2d: 00 00 00
  30: 62 f2 75 48 36 c0     vpermd zmm0,zmm1,zmm0
  36: 62 f1 fd 48 7f 02     vmovdqa64 ZMMWORD PTR [rdx],zmm0
  3c: c5 f8 77              vzeroupper
  3f: c3                    ret

0000000000000040 <using_ret>:
  40: c5 f9 6f 47 20        vmovdqa xmm0,XMMWORD PTR [rdi+0x20]
  45: c4 e2 79 00 0d 00 00  vpshufb xmm1,xmm0,XMMWORD PTR [rip+0x0]        # 4e <using_ret+0xe>
  4c: 00 00
  4e: c5 fd 6f 17           vmovdqa ymm2,YMMWORD PTR [rdi]
  52: c4 e3 6d 46 5f 20 03  vperm2i128 ymm3,ymm2,YMMWORD PTR [rdi+0x20],0x3
  59: c4 e2 65 00 1d 00 00  vpshufb ymm3,ymm3,YMMWORD PTR [rip+0x0]        # 62 <using_ret+0x22>
  60: 00 00
  62: c4 e3 65 02 c9 01     vpblendd ymm1,ymm3,ymm1,0x1
  68: c4 e2 79 00 05 00 00  vpshufb xmm0,xmm0,XMMWORD PTR [rip+0x0]        # 71 <using_ret+0x31>
  6f: 00 00
  71: c5 f9 6f 5f 10        vmovdqa xmm3,XMMWORD PTR [rdi+0x10]
  76: c4 e2 61 00 1d 00 00  vpshufb xmm3,xmm3,XMMWORD PTR [rip+0x0]        # 7f <using_ret+0x3f>
  7d: 00 00
  7f: c4 e3 7d 38 c0 01     vinserti128 ymm0,ymm0,xmm0,0x1
  85: c4 e2 6d 00 15 00 00  vpshufb ymm2,ymm2,YMMWORD PTR [rip+0x0]        # 8e <using_ret+0x4e>
  8c: 00 00
  8e: c4 e3 6d 02 d3 08     vpblendd ymm2,ymm2,ymm3,0x8
  94: c4 e3 6d 02 c0 c0     vpblendd ymm0,ymm2,ymm0,0xc0
  9a: 62 f3 fd 48 3a c1 01  vinserti64x4 zmm0,zmm0,ymm1,0x1
  a1: c5 f9 6f 4e 20        vmovdqa xmm1,XMMWORD PTR [rsi+0x20]
  a6: c4 e2 71 00 15 00 00  vpshufb xmm2,xmm1,XMMWORD PTR [rip+0x0]        # af <using_ret+0x6f>
  ad: 00 00
  af: c5 fd 6f 1e           vmovdqa ymm3,YMMWORD PTR [rsi]
  b3: c4 e3 65 46 66 20 03  vperm2i128 ymm4,ymm3,YMMWORD PTR [rsi+0x20],0x3
  ba: c4 e2 5d 00 25 00 00  vpshufb ymm4,ymm4,YMMWORD PTR [rip+0x0]        # c3 <using_ret+0x83>
  c1: 00 00
  c3: c4 e2 71 00 0d 00 00  vpshufb xmm1,xmm1,XMMWORD PTR [rip+0x0]        # cc <using_ret+0x8c>
  ca: 00 00
  cc: c4 e3 5d 02 d2 01     vpblendd ymm2,ymm4,ymm2,0x1
  d2: c4 e3 7d 38 c9 01     vinserti128 ymm1,ymm0,xmm1,0x1
  d8: c5 f9 6f 66 10        vmovdqa xmm4,XMMWORD PTR [rsi+0x10]
  dd: c4 e2 59 00 25 00 00  vpshufb xmm4,xmm4,XMMWORD PTR [rip+0x0]        # e6 <using_ret+0xa6>
  e4: 00 00
  e6: c4 e2 65 00 1d 00 00  vpshufb ymm3,ymm3,YMMWORD PTR [rip+0x0]        # ef <using_ret+0xaf>
  ed: 00 00
  ef: c4 e3 65 02 dc 08     vpblendd ymm3,ymm3,ymm4,0x8
  f5: c4 e3 65 02 c9 c0     vpblendd ymm1,ymm3,ymm1,0xc0
  fb: 62 f3 f5 48 3a ca 01  vinserti64x4 zmm1,zmm1,ymm2,0x1
 102: 62 f1 f5 48 eb c0     vporq  zmm0,zmm1,zmm0
 108: c3                    ret
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzdWkuTozgS_jWui8IVevHwoQ71mLlNzMbsxO7sXiaEEFVsY-MB7Hb3r9-UACGQqHb1Vh22HQ4bI0jl9-UDZcpZnX-5-_1zjfZ1o9BRdJ1qDi2qC5QJ-Wnb1Vv9jdqXU1FUqkXdi-jQszqoRnQKtadsWx-7ci8qJOtcoaJu0P0__ogI3dBH1Jb7shIN6mq0oSziUUw3-GmD7_vPh7p7gdv2x7JSOfpcdi_DaIyHt_kpK3F43tAHeKMNeyzg6tuq2rCf0FaibW3P1ebUrwxt96KRLxv21H76UolPaivOF9AIzh8bVahme1ayq5vt5zLv9GVa29DE_eejaBUiG3ZvGNFY5oxIcWoDTAwclfVhEBY9dJ_rP8fbAMFtd-k20dOGpi9dd2xhhg39Gd7PQMQpuwVi4EdVncev7bGp_wOaw0-Nt4XvlKWc0R0chWTDgINjAS5XRXlQSF20wUFpYJHE6IJKRjWPG44zMA8oBwMx1wOpOU8jAYK1PTHaJA-DJR-wVt8cI30NjLGnkaOebhQS9Lg4e6zLFhijj6Ms87LXDLqxRzgCm8Dt-oCNB3Q8iMaDZDyIx4PdeEDs_QTbIyuKWBGEj0enA5B2_Y8ZBPdlpFrNyKRRaoFY3egEzqKjVjdqpVALkFp5bGIIfwQGZnVjViNm2WJWNzZpZBFyqxu3UrhFyK08bqXw-CMwcKtbZDWKLFuR1S2yGkUWYWR1iyYpFmFs5cVWSky_CwP7yQktYkIrKzsp2s4PKmyy7SyYnZtpOC5nkU97JhanbWR61_fROMWQF40TYV40WramIJgEWQFOWFpZ-LWDCXOjugDAMd8nT68k_sVJvHhpsSZFwmRT7tOT34OdUcFQkSOeIpYhSRAmCJ0h2TZCdmXMLxx92e81VV_3e604vhArItEiJEcK8hfciSEZ6U94o_NR2y5Dl_1es3PpZfzxyy___PW3J_S3339D8JxpyiM8K_EFw9Nl9HXI10Ct1VkPE5cnpPSkZpbxFMGjHgwlEcQfylPITEbc-aiaPS0JTTUObZ4BzpcRDrV4SDzhiQ0Ski_xTEL017-uxFPM8biBQnIfTzHh0XpQlFNjF4Mnq9Qhz7UidFJk-OUYB3LvwjjYAzNY5W3GoWoGhioHDJUeGKoc4-SQYpFkFszoZ9o8F4tk4WaQqSezkLBZhpuHryuRsHyGhOUOEpZ5SFg-R5IiubNIykOrmm70M8fBBnIdPPAcmSzTI_HCZrh5-LrSzbic4eHSwcOFh4fLGR5wM22Z1HMzR5HB2_AlHYVAhloKIUjibwjpGZFWFXgYLZORQLJ3-pFak4uGJPTVSlp4fdSHDgs8RHWGdbPmPEnGuF-eN203z5OxzZPGWqCaNZi11lyrf19nrVhMM-px4VgrTqy1HIPF4gpwcFnvuoVOO5yPntW_DvVRfz3NFBQXUMB83hOr6jpViaGqVbI-5HOuEssVQYnUXEE49GkHnff1WRxbzRW5nqREOHMtWUqCLCXCMViklYBnqvVIeBr0SgwGs0-24e4UX-NAq-WXiYZGHSshy8MzFKGQLGPcdrpmna2A4KwpJPXw8OifD5pqrUViVrAN66Gx_L21FRuI-NPM8o7lml6L_-wJflOtdq7LXFdopxbY6OUsCzVwOvBKKY7dCTg61IfDqaqAQpHXh-oLElX5fEC6KM6VqYnVQSoBeQXkmOJ9NxZoq6vnxev9Z8_ed_brJpVXF7dVLfLlvI--ImOda6f3lvLXC8rWBK0s6xeVwbXl9o9Wb_8QBfcPUXH_n5bc7JrwGovm_7WbZZnwo8vS4EeX5SAYXFMl_dHNLKtZMLYmbKHYsrqFYotaeR_ezLK6BUPL6hYMLatbMLSsvI9uZnGrWzCyJtcKRZbVLRhZVt57RBY3kRUKJyNcx55zdfR664u_2vqKr2p9RUMU_wCtL0CTLAlboI0HxpyVhrMKRSiwwjZivVQ3LFCkHvAWKHohrpes79R0c1e9K703MpS7cYFwYsJD10n5XyK2te6yUspLW53B5XFIkvIlhWqudiZJflCdS-IlF6YHFrs9MBYq5Ei8LORsE8vVaKjg3lBUUs86ppHluqTTlXN7Wa7djEYqm0rLuvkLvVJZ0qCppuL4VVOtdbCCSJiLhAaRMLzkls2L5PwVJMxDkhS68zN3Os9vL6YonUvqW1ARKkBGMn9OnL-qpj4dQRl79fc2d7hDk75wFowcjzrstEV4ov1j1KFHo9uLmotlXxFCcfCcKY6423fdfavvGpK61t1TcxD6Grf3yv3eK1cjtFxDIy7DI7Shh7ZsMc6yjNvki3PdYI8KzRJmKw32FYkTWbppZx-YsEL-mL57TH3KqPu07Zt78yabi9U0350ur9PQJBu3-b5o8cap5wShnRH8ZidIiI8IijkHUeEhSsjMwcF0JOTgocb5YDPiOnji7pK8Zzs-KQLY3GVY4m-VJM5WydCTxys9eacDffH2GFInauM8vJU17biE3HsFVBqIWu6GbeqHbapm4ab3f4KNeUcbvzG_40shwMx6Y55unK2XqTG_s81UtzFPrmjMLyJCzJ0Qklkwy4b2odpAlhWOE77r1qMIOGHsOqHwnVAU8zSrwmk2lLhmS7CMzVIPpNk4DqdZvp4K29U0m4mJs8j4OA35-CCbX-_jkvmcpczhTBKPM8mWBnyn7UkpA8q4O2HS3wmTzk5YlH9zw5VvQltPOfVS0XdtD-bpLFLABYLpmq9Hyixd57lj9V3Y6oO4FakrRKvYJ1q4q3rFPaLVR-2wq0DYCjdslR-2yt9ml6E062gzGN9Js0UUWC4E0mxouTCl2SJz0mw0plkRTLNOveM5IcH0-ysUgtO37H3d5Hcs37GduOnKrlJ3f1__Y6H5t6WsAYc8deVZTf9JhLFLGg__xLw5NdXdm_esyrY9mU2riMdRevNylwucZVIKQkWSUymLhGSZwjyJSBFTUdxUIlNVewfuBF50U95RTClmDFPCccRuBSNS7JSEmxlNwcAcq70oq1s98W3dPN80d0aH7PTcwmBVtl07DYq2LZ8PSo3yxal7qRvQ6lCqqjq1Xfl8Y3S-Mwr_Fzqx3k8">