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

    <tr>
        <th>Summary</th>
        <td>
            SLP vectorization causes 1.75x slowdown with march=skylake-avx512 due to vgatherdps
        </td>
    </tr>

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

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

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

<pre>
    I think the SLP cost model might be wrong for vector gathers on skylake.

Consider the following code which repeatedly permutes an array:

```
void f(const float *__restrict__ src, const int *__restrict__ idx, float *__restrict__ dst, int n) {
    for (int i = 0; i < n; i += 8) {
        dst[i] = src[idx[i]];
        dst[i + 1] = src[idx[i + 1]];
        dst[i + 2] = src[idx[i + 2]];
        dst[i + 3] = src[idx[i + 3]];
        dst[i + 4] = src[idx[i + 4]];
 dst[i + 5] = src[idx[i + 5]];
        dst[i + 6] = src[idx[i + 6]];
 dst[i + 7] = src[idx[i + 7]];
    }
}

int main(int argc, char **argv) {
    const int n = 16 * 1024;
    float src[n], dst[n];
    int idx[n];
    for (int i = 0; i < n; i++) {
        // Some arbitrary permutation
        idx[i] = (i * 17 + 37) % n;
 src[i] = dst[i] = 0;
    }
    src[17] = 17.0f;

    for (int i = 0; i < 100000; i++) {
        f(&src[0], &idx[0], &dst[0], n);
 f(&dst[0], &idx[0], &src[0], n);
    }

    // Introduce a dependence on the output
    return dst[0] == 17.0f ? 1 : 0;
}
```

Compiled with top of tree clang with `-march=skylake -O3` it takes about 4.2 seconds to run on my i9-9960X. Compiled with `-march=skylake -O3 -fno-slp-vectorization` it takes 2.4 seconds.

The only salient difference in the assembly is that slp vectorization has packed the eight stores in `f` into a gather intrinsic. Here's the inner loop assembly with slp vectorization on (with unrolling off for brevity):

```
.LBB1_4:                                # %for.body.i
                                        #   Parent Loop BB1_3 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
        vmovups 32(%rsp,%rcx,4), %ymm0
        vpxor   %xmm1, %xmm1, %xmm1
        vpcmpeqd        %ymm2, %ymm2, %ymm2
        vgatherdps      %ymm2, (%r14,%ymm0,4), %ymm1
        vmovups %ymm1, 65568(%rsp,%rcx,4)
        addq    $8, %rcx
        cmpq    $16376, %rcx                    # imm = 0x3FF8
        jb      .LBB1_4

```

and here it is with slp vectorization off:

```
.LBB1_4:                                # %for.body.i
                                        #   Parent Loop BB1_3 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
        movslq  131104(%rsp,%rcx,4), %rdx
        vmovss  65536(%rsp,%rdx,4), %xmm0       # xmm0 = mem[0],zero,zero,zero
        vmovss  %xmm0, 32(%rsp,%rcx,4)
        movslq  131108(%rsp,%rcx,4), %rdx
        vmovss  65536(%rsp,%rdx,4), %xmm0       # xmm0 = mem[0],zero,zero,zero
        vmovss  %xmm0, 36(%rsp,%rcx,4)
        movslq  131112(%rsp,%rcx,4), %rdx
        vmovss  65536(%rsp,%rdx,4), %xmm0       # xmm0 = mem[0],zero,zero,zero
        vmovss  %xmm0, 40(%rsp,%rcx,4)
        movslq  131116(%rsp,%rcx,4), %rdx
        vmovss  65536(%rsp,%rdx,4), %xmm0       # xmm0 = mem[0],zero,zero,zero
        vmovss  %xmm0, 44(%rsp,%rcx,4)
        movslq  131120(%rsp,%rcx,4), %rdx
        vmovss  65536(%rsp,%rdx,4), %xmm0       # xmm0 = mem[0],zero,zero,zero
        vmovss  %xmm0, 48(%rsp,%rcx,4)
        movslq  131124(%rsp,%rcx,4), %rdx
        vmovss  65536(%rsp,%rdx,4), %xmm0       # xmm0 = mem[0],zero,zero,zero
        vmovss  %xmm0, 52(%rsp,%rcx,4)
        movslq  131128(%rsp,%rcx,4), %rdx
        vmovss  65536(%rsp,%rdx,4), %xmm0       # xmm0 = mem[0],zero,zero,zero
        vmovss  %xmm0, 56(%rsp,%rcx,4)
        movslq  131132(%rsp,%rcx,4), %rdx
        vmovd   65536(%rsp,%rdx,4), %xmm0       # xmm0 = mem[0],zero,zero,zero
        vmovd   %xmm0, 60(%rsp,%rcx,4)
        addq    $8, %rcx
        cmpq    $16376, %rcx                    # imm = 0x3FF8
        jb      .LBB1_4

```

Interestingly, llvm-mca has the right idea. It says the version with SLP vectorization on is 2310 cycles per 100 iterations, and the version with it off is 813 cycles per 100 iterations.


</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWMtu6zgS_Rp6U7AhUZZsL7zIY4wOcIG5wO3F7AJaLFnsSKSapBy7v35QlBxHfsTJZpALjGE4Elmnqk7x8BXhnNpoxCVL71n6OBKtL41dirWQonajtZH75RP4UukX8CXCrx8_ITfOQ20kVlCrTelhjfBqjd5AYSxsMffGwkb4Eq0Do8G97CvxghMWPbLorvt9MNopiTY4LUxVmVelN5AbifBaqrwEiw0Kj7LaQ4O2bj06EBqEtWLPkrv3zlgW9d_wujVKQsH4PDfaeSgqIzwwfvf8bNF5q3L__AzO5ow_QGei9LmBkjsyuIyWzlMn4TTjC2Cz-y42AIQqMD6nTgUseYSIJffh8QF0_8jvqWN-hqUPOU_vFUsfA5oyTe8pna6RvsllCPmF-CLwresWnF-H80_Ak-vw5BPw6XX49BT-Hpdex6WfCJtdh2cfhZ1dx80uhGWzx16xbw_hl6RSC6V71Qi76cRZClLSHeN3wm62Z2I5ileHJOKMrCGO-HQQttNwl6KmnPhDz0KfZhhEG1icdd2WNamavhc0zfiK8RX8MjWCsGvlrbCHiS28MnpoflR7iERhO2qzTkmzEISnIXAP7YfggDmZRdHlgaCXDhi_jWU8m0TFm_nnChBH9LlVBVqUGM-6gFE_EoxnHd13DV3yhwZaYo7p906GJpecDMMMnQzEeGzqRulJe2tkmyMIkNiglqhzpKWcVmvT-qb1R5BF31oNx3yoNm91BJasIAaW3L0bgmPo4cp92BvqRlUo4VX5ErxpwBTgLSLkldCbrpll0bgWNi9Z8thvMDD-d8KyCJQHL15ou1ib1sN0wsFhbrR04A3YVhOTeg9qMV4ssug_ExhGvOIaxoU2Y1c1426LU_90wn0fkU-mh1iD7e5Pqpuu9uBEpVB7kKoo0Iayqq6swjms19UelANf0nytGhhEglI4aET-gjIgMGy-zhuLjrywLCpCNtobEP0OTG9WaafyCfyBFhmfuYBWWqOFypjmGDrQP49rNOk-dLbamqqirdoURZgRa4tb5fdBXR_typMf9_fx85SEcOPDeEJzuzB2QuePiRpOos_AAX4KS3X-QfwocAKP2Hga0vjr7oKg_wXwZ6kcPIXCBcd_oJBoidLBOT9UYLGtzbZtHIsWCQ8zNrWuYfyBHnI6WkypZGGmpvu6jo7AZmcsixaMp7u6jnuT08ejdV43-LfsAPu65kefg8c3QKcLGVIb2IUc42mXY0jpNMn4ArtDD3-ALE2z-XWuB6yQ8u8AnM5712R06M3rpu-Ns2SWHS2uDY6q62413iWr1fzNz19rFi0Oorsuy-5XaAklWqSZrNzVeVAU_9f4e43XZusqGq04ieNoekvmVu4GAnKknyxNk-wUKU-Qu7qO3uUaXmnMa6yPW9w_aM3Jn7NovS9y-9G0vEzwA21_S4JnUW8QjG8uVN-L4DT6KsEPKvItCX4wpS4S5B9U5FsS_MR2MST4my0y6VcXGf6bLTLpVxeZ26ehU4Lyf8lPDulln1hivuF55kl7tOi80ptqTyGraluP61yEOwQd_224PCiJYgJPHpzYd-1btI7OOuEI9OvHz_OrgHLAkziCfJ9X6OgOT7dfUB5tsHEUjw5UZ-6UD7cG5WAeJ9fxg5vTSC4TuUgWYoTLOFvM-SzKOB-Vy7nMkzyZ8-liXsikSBDnQiSLeYQoF-soHqkljyhRnvI4jTif5AXP5DqK81wm0Xwes2mEtVDVhIozMXYzUs61uJxFPF2MKrHGyh3-L2qXoYLrduPYNKqU8-4I88pXuDwvVi5ahw7iySzdgavMqzSvfSlO7pdjsd2lMQfZIt1Rj2f0UWurZel94-jkGa7nG-XLdj3JTc34inLo_4wba_7C3DO-Cjwc46tA5b8BAAD___5Z3k0">