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

    <tr>
        <th>Summary</th>
        <td>
            [AVX-512] `vmovdqu8` constant memory operand not hoisted from loop
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    I have real code using a `@select` statement in Zig like so:
```zig
export fn testLoop(source: [*]@Vector(64, u8)) @Vector(64, u8) {
    var cur_src = source;
    var things: @Vector(64, u8) = @splat(0);

    while (true) {
        const str: @Vector(64, u8) = cur_src[0..64][0];

        const slot: u64 = @bitCast(str == @as(@Vector(64, u8), @splat(16))); // this vector of 16's gets hoisted from the loop
        things = @select(u8,
            @as(@Vector(64, u1), @bitCast(slot)) == @as(@Vector(64, u1), @splat(1)),
 @as(@Vector(64, u8), @splat(22)), // this vector of 22's does not get hoisted from the loop
            things);

        cur_src = cur_src[1..];
        if (cur_src[0][0] == 0) break;
    }

 return things;
}
```

Zen 4 emit:

```asm
.LCPI0_1:
 .zero   64,22
.LCPI0_2:
        .byte   16
testLoop:
 vpbroadcastb    zmm1, byte ptr [rip + .LCPI0_2]
        add     rdi, 64
        vpxor   xmm0, xmm0, xmm0
.LBB0_1:
        vpcmpeqb k1, zmm1, zmmword ptr [rdi - 64]
        cmp     byte ptr [rdi], 0
 lea     rdi, [rdi + 64]
        vmovdqu8        zmm0 {k1}, zmmword ptr [rip + .LCPI0_1]; why aren't we doing a `vpbroadcastb` before the loop?
 jne     .LBB0_1
        ret
```

[Zig godbolt link](https://zig.godbolt.org/z/4aT4o17b5)

In my opinion, it should be:

```diff
.LCPI0_1:
        .byte   22
.LCPI0_2:
 .byte   16
testLoop:
        vpbroadcastb    zmm1, byte ptr [rip + .LCPI0_2]
+       vpbroadcastb    zmm2, byte ptr [rip + .LCPI0_1]
 add     rdi, 64
        vpxor   xmm0, xmm0, xmm0
.LBB0_1:
 vpcmpeqb        k1, zmm1, zmmword ptr [rdi - 64]
        cmp     byte ptr [rdi], 0
        lea     rdi, [rdi + 64]
-       vmovdqu8        zmm0 {k1}, zmmword ptr [rip + .LCPI0_1]
+       vmovdqu8        zmm0 {k1}, zmm2
        jne     .LBB0_1
        ret
```

Here is the LLVM IR emitted by Zig:

(I ran `zig build-obj ./src/llvmbadloop.zig -O ReleaseFast -target x86_64-linux -mcpu znver4 -femit-llvm-ir -fstrip`, then erased the unnecessary `target triple` and other config stuff)

```llvm
define dso_local <64 x i8> @testLoop(ptr nocapture nonnull readonly align 64 %0) local_unnamed_addr #0 {
Entry:
  %scevgep = getelementptr i8, ptr %0, i64 64
  br label %Loop

Loop: ; preds = %Loop, %Entry
  %lsr.iv = phi ptr [ %scevgep5, %Loop ], [ %scevgep, %Entry ]
  %.sroa.03.0 = phi <64 x i8> [ zeroinitializer, %Entry ], [ %3, %Loop ]
  %scevgep6 = getelementptr i8, ptr %lsr.iv, i64 -64
  %1 = load <64 x i8>, ptr %scevgep6, align 64
  %2 = icmp eq <64 x i8> %1, <i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16, i8 16>
  %3 = select <64 x i1> %2, <64 x i8> <i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22, i8 22>, <64 x i8> %.sroa.03.0
 %4 = load i8, ptr %lsr.iv, align 64
  %5 = icmp eq i8 %4, 0
  %scevgep5 = getelementptr i8, ptr %lsr.iv, i64 64
  br i1 %5, label %Then, label %Loop

Then:                                             ; preds = %Loop
  ret <64 x i8> %3
}
```

[LLVM IR dump Godbolt link](https://godbolt.org/z/TerKEGK5f)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWEtv4zgS_jX0pWBBoh6WDz7ETns2mCx2MWg0FnMJKJG22ZFINUk5j1-_KEqyJSeedGN6bi0EkUwVqz4Wv3pQzFq5V0KsSLom6e2Mte6gzeoLqyRn5nFWaP6yuoMDOwowglVQai6gtVLtgQHJQpKEVlSidCQLwTrmRC2UA6ngT7mHSj4KsJrENyS8JeENTvB_r3LfjYjnRhsHOwVOWHevdUNobnVrSkHiG0BY9IaktyQJv4jSaUNoniWEbqDNCV0SuoQrr4As1p0NAIAjM1C25sGaEkh8C4OJCxF3kGpvveVrWuNbfGebijlC8xBBDFrOup4OshJAaO5MK96AwavUyjqwznxkrEdN0nUYBFmCvkjXId7emh0prrRDzW2WDJAL6TbMImjrDA7248wSml_172a82ijrfN4tGgjdErpFp1k4-tmgd4BCCwt74SwctLROcNgZXYM7CKhwhyd4O5ef_NqRieZofjOVxOsv8EZnvKOloh96nny44uidFQ8LHrD8mMMoPc2_4i2UWFjgWlhQ2qHbvsdrZ8-9T0DPhBHfzyyKgmBMnkFY7pCuI7KdiTZ4DrkOhRHscTKbLG4n1o1wrVGnUBqgnaSGHDCe9KdQkICopTvniqk0s3U3Etxv_nsXPkQnQQhehdEA4LeB0okYPYv1V1C8OAGANPXjp7xzEjw2hdGMl8y6Ame81nWEG-gnNhg76drIBghdw8lMejs1wzj3d8Mlzs2S6etj86wNADzXdYjvJ_d-Aev1ZJmnmWXdiG8FPHpQA7jXun7Shp_wcQlz6NLFlBR14--TxXCJcnQDvW2oBBuj7xXigt9Reaz1kX9r8-H3a12HmPAeI9z0d7BNfRd1dISnwwswIxShCwdPArg-VZnxjmChKcROG3EOjXjbI_qqRLfJvfMmOI1wf0FBkq6xZO01L3TloJLq0TslPzjXYEno4vdV7oNeJtBmjyOEbhP2OdHRokgxGkdK7xTUL6AbqaRW6ArpwB50W3EoxDWqc7nbXeP6BYmvs_1jmp_49DfYjoNX1dAP1ERnJv38aDmFSX_9k9HSX98VNPOfGDSXW_AdKukU8t-Il38JI0BaH4T391_-DXd_-ASOhat4wfbvkt80vwPDFHT9HxStrPhcF18hIHSLVYduq-pYF4xjUAcoM_8P_CEqwazYMutg7pjBAvmcZw9ZMq-kap9hXpdNC6_qKEwC8x1imKOeuTQw31lnZIPQ6QahKhCGWcE97FYpUQprmXlBUL1ynFAJTDNMcdDuIAw2VTu5B-va3e4ixE_OQZvdEBc7qQRwqx8qXbIKSLzJEngGmZP4E_YHo2YX91fpkjWuNQKUVqqtKmy2uVbVC7BK7hVgF0dTX4C9xodWKVYL_sA4N0BoHJ47zE_KmZdRmBOa2lIc96LxncBeOFH5Lh0tS2yzOo55_RuQWTKKv8JAxQpR4ev7UxfS_e_TCWDybozgfRPXC_qOJ-3AnJFU1gTy6AWbgxzIPcKY9hNRB_RxNpUYa4ZRxBKaBtZoFoRxEJ4sXLg-XQN2C1JJJ1klX4V5o-5sML7E8saj2Ucu7dY7-HV-diyhaeQnV5rxKcrR9MEMDg1MGGmgXoPELCW-XS6Vpj7VkXgjc9-Ub-DXw6-HH32IP40IF3eHZ39IO_Mt6vlGe76NWejZR2mv79fDr4cfeuiy4ZvMdk70w7Gcpsk5nV5Jwe9k0HSSQWXuFZFxbzcqTT-W7CdFVEbeGr471dPPB6EmA5cF1gvEkzP_h9f7xbgHYoR768v4ew7oJF0PTR5v6wZ---CY9PaI9FmY3z_99nuK_dOMr2K-jJdsJlbRgsaLZRJH6eywChkvlnGZFzRMsmwR5lnIEs4Wi3gZ7_JlOJMrGtIkzKMsXCRplAZZznjMo6Rky7JMIk6SUNRMVgG2Y2h-Jq1txSoKkzQLZ97X1n_upFSJJ_BvCcUjzcysfN9YtHtLkrCS1tmzGidd5b-T3nz53zyNqP8wkoVD0439ov_0xpSDWtTa4LlPGOwhlb74poP97aw11erCadId2iIodd23wv1t3hj91X8W23q4ltBtv57jiv4_AAD__4d-sL0">