[llvm] [X86][CostModel] Add vXi64 divide/remainder-by-constant costs (PR #208491)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 9 09:34:34 PDT 2026
Andarwinux wrote:
v4i64's cost is too high. As discussed previously, v4i64 is also profitable on DQ, but the current cost caused both LV and SLP rejected vectorization.
```c
#include <stdint.h>
void v8i64_udiv(const uint64_t *restrict x, uint64_t *restrict dst) {
for (int i = 0; i < 8; i++) {
dst[i] = x[i] / 7;
}
}
void v4i64_udiv(const uint64_t *restrict x, uint64_t *restrict dst) {
for (int i = 0; i < 4; i++) {
dst[i] = x[i] / 7;
}
}
void v8i64_sdiv(const int64_t *restrict x, int64_t *restrict dst) {
for (int i = 0; i < 8; i++) {
dst[i] = x[i] / 7;
}
}
void v4i64_sdiv(const int64_t *restrict x, int64_t *restrict dst) {
for (int i = 0; i < 4; i++) {
dst[i] = x[i] / 7;
}
}
void v8i64_urem(const uint64_t *restrict x, uint64_t *restrict dst) {
for (int i = 0; i < 8; i++) {
dst[i] = x[i] % 7;
}
}
void v4i64_urem(const uint64_t *restrict x, uint64_t *restrict dst) {
for (int i = 0; i < 4; i++) {
dst[i] = x[i] % 7;
}
}
void v8i64_srem(const int64_t *restrict x, int64_t *restrict dst) {
for (int i = 0; i < 8; i++) {
dst[i] = x[i] % 7;
}
}
void v4i64_srem(const int64_t *restrict x, int64_t *restrict dst) {
for (int i = 0; i < 4; i++) {
dst[i] = x[i] % 7;
}
}
```
SLP:
```asm
<v8i64_udiv>:
vmovdqu64 (%rdi), %zmm0
vpbroadcastq (%rip), %zmm2 # 0x10 <v8i64_udiv+0x10>
vpbroadcastq (%rip), %zmm4 # 0x1a <v8i64_udiv+0x1a>
vpsrlq $0x20, %zmm0, %zmm1
vpmuludq %zmm4, %zmm0, %zmm5
vpmuludq %zmm2, %zmm1, %zmm3
vpmuludq %zmm2, %zmm0, %zmm2
vpmuludq %zmm4, %zmm1, %zmm1
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm3, %zmm2
vpsrlq $0x20, %zmm2, %zmm3
vpandq (%rip){1to8}, %zmm2, %zmm2 # 0x57 <v8i64_udiv+0x57>
vpaddq %zmm3, %zmm1, %zmm1
vpaddq %zmm2, %zmm5, %zmm2
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm1, %zmm1
vpsubq %zmm1, %zmm0, %zmm0
vpsrlq $0x1, %zmm0, %zmm0
vpaddq %zmm1, %zmm0, %zmm0
vpsrlq $0x2, %zmm0, %zmm0
vmovdqu64 %zmm0, (%rsi)
vzeroupper
retq
nopw %cs:(%rax,%rax)
<v4i64_udiv>:
movq (%rdi), %rdx
movabsq $0x2492492492492493, %rax # imm = 0x2492492492492493
mulxq %rax, %rcx, %rcx
subq %rcx, %rdx
shrq %rdx
addq %rcx, %rdx
shrq $0x2, %rdx
movq %rdx, (%rsi)
movq 0x8(%rdi), %rdx
mulxq %rax, %rcx, %rcx
subq %rcx, %rdx
shrq %rdx
addq %rcx, %rdx
shrq $0x2, %rdx
movq %rdx, 0x8(%rsi)
movq 0x10(%rdi), %rdx
mulxq %rax, %rcx, %rcx
subq %rcx, %rdx
shrq %rdx
addq %rcx, %rdx
shrq $0x2, %rdx
movq %rdx, 0x10(%rsi)
movq 0x18(%rdi), %rdx
mulxq %rax, %rax, %rax
subq %rax, %rdx
shrq %rdx
addq %rax, %rdx
shrq $0x2, %rdx
movq %rdx, 0x18(%rsi)
retq
nopw %cs:(%rax,%rax)
<v8i64_sdiv>:
vmovdqu64 (%rdi), %zmm0
vpbroadcastq (%rip), %zmm2 # 0x130 <v8i64_sdiv+0x10>
vpbroadcastq (%rip), %zmm4 # 0x13a <v8i64_sdiv+0x1a>
vpsraq $0x20, %zmm0, %zmm1
vpmuldq %zmm2, %zmm1, %zmm3
vpmuludq %zmm2, %zmm0, %zmm2
vpmuludq %zmm4, %zmm0, %zmm0
vpmuldq %zmm4, %zmm1, %zmm1
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm3, %zmm2
vpsraq $0x20, %zmm2, %zmm3
vpandq (%rip){1to8}, %zmm2, %zmm2 # 0x177 <v8i64_sdiv+0x57>
vpaddq %zmm3, %zmm1, %zmm1
vpaddq %zmm2, %zmm0, %zmm0
vpsraq $0x20, %zmm0, %zmm0
vpaddq %zmm0, %zmm1, %zmm0
vpsrlq $0x3f, %zmm0, %zmm1
vpsraq $0x1, %zmm0, %zmm0
vpaddq %zmm1, %zmm0, %zmm0
vmovdqu64 %zmm0, (%rsi)
vzeroupper
retq
nop
<v4i64_sdiv>:
movabsq $0x4924924924924925, %rcx # imm = 0x4924924924924925
movq %rcx, %rax
imulq (%rdi)
movq %rdx, %rax
shrq $0x3f, %rax
sarq %rdx
addq %rax, %rdx
movq %rcx, %rax
movq %rdx, (%rsi)
imulq 0x8(%rdi)
movq %rdx, %rax
shrq $0x3f, %rax
sarq %rdx
addq %rax, %rdx
movq %rcx, %rax
movq %rdx, 0x8(%rsi)
imulq 0x10(%rdi)
movq %rdx, %rax
shrq $0x3f, %rax
sarq %rdx
addq %rax, %rdx
movq %rcx, %rax
movq %rdx, 0x10(%rsi)
imulq 0x18(%rdi)
movq %rdx, %rax
shrq $0x3f, %rax
sarq %rdx
addq %rax, %rdx
movq %rdx, 0x18(%rsi)
retq
nopl (%rax)
<v8i64_urem>:
vmovdqu64 (%rdi), %zmm0
vpbroadcastq (%rip), %zmm2 # 0x230 <v8i64_urem+0x10>
vpbroadcastq (%rip), %zmm4 # 0x23a <v8i64_urem+0x1a>
vpsrlq $0x20, %zmm0, %zmm1
vpmuludq %zmm4, %zmm0, %zmm5
vpmuludq %zmm2, %zmm1, %zmm3
vpmuludq %zmm2, %zmm0, %zmm2
vpmuludq %zmm4, %zmm1, %zmm1
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm3, %zmm2
vpsrlq $0x20, %zmm2, %zmm3
vpandq (%rip){1to8}, %zmm2, %zmm2 # 0x277 <v8i64_urem+0x57>
vpaddq %zmm3, %zmm1, %zmm1
vpaddq %zmm2, %zmm5, %zmm2
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm1, %zmm1
vpsubq %zmm1, %zmm0, %zmm2
vpsrlq $0x1, %zmm2, %zmm2
vpaddq %zmm1, %zmm2, %zmm1
vpsrlq $0x2, %zmm1, %zmm1
vpsllq $0x3, %zmm1, %zmm2
vpsubq %zmm2, %zmm1, %zmm1
vpaddq %zmm1, %zmm0, %zmm0
vmovdqu64 %zmm0, (%rsi)
vzeroupper
retq
nopw (%rax,%rax)
<v4i64_urem>:
vmovdqu (%rdi), %ymm0
vpbroadcastq (%rip), %ymm2 # 0x2dd <v4i64_urem+0xd>
vpbroadcastq (%rip), %ymm6 # 0x2e6 <v4i64_urem+0x16>
vpxor %xmm4, %xmm4, %xmm4
vpsrlq $0x20, %ymm0, %ymm1
vpmuludq %ymm6, %ymm0, %ymm5
vpmuludq %ymm2, %ymm1, %ymm3
vpmuludq %ymm2, %ymm0, %ymm2
vpmuludq %ymm6, %ymm1, %ymm1
vpsrlq $0x20, %ymm2, %ymm2
vpaddq %ymm2, %ymm3, %ymm2
vpsrlq $0x20, %ymm2, %ymm3
vpblendd $0xaa, %ymm4, %ymm2, %ymm2 # ymm2 = ymm2[0],ymm4[1],ymm2[2],ymm4[3],ymm2[4],ymm4[5],ymm2[6],ymm4[7]
vpaddq %ymm2, %ymm5, %ymm2
vpaddq %ymm3, %ymm1, %ymm1
vpsrlq $0x20, %ymm2, %ymm2
vpaddq %ymm2, %ymm1, %ymm1
vpsubq %ymm1, %ymm0, %ymm2
vpsrlq $0x1, %ymm2, %ymm2
vpaddq %ymm1, %ymm2, %ymm1
vpsrlq $0x2, %ymm1, %ymm1
vpsllq $0x3, %ymm1, %ymm2
vpsubq %ymm2, %ymm1, %ymm1
vpaddq %ymm1, %ymm0, %ymm0
vmovdqu %ymm0, (%rsi)
vzeroupper
retq
nopl (%rax,%rax)
<v8i64_srem>:
vmovdqu64 (%rdi), %zmm0
vpbroadcastq (%rip), %zmm2 # 0x360 <v8i64_srem+0x10>
vpbroadcastq (%rip), %zmm4 # 0x36a <v8i64_srem+0x1a>
vpsraq $0x20, %zmm0, %zmm1
vpmuludq %zmm4, %zmm0, %zmm5
vpmuldq %zmm2, %zmm1, %zmm3
vpmuludq %zmm2, %zmm0, %zmm2
vpmuldq %zmm4, %zmm1, %zmm1
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm3, %zmm2
vpsraq $0x20, %zmm2, %zmm3
vpandq (%rip){1to8}, %zmm2, %zmm2 # 0x3a7 <v8i64_srem+0x57>
vpaddq %zmm3, %zmm1, %zmm1
vpaddq %zmm2, %zmm5, %zmm2
vpsraq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm1, %zmm1
vpsrlq $0x3f, %zmm1, %zmm2
vpsraq $0x1, %zmm1, %zmm1
vpaddq %zmm2, %zmm1, %zmm1
vpsllq $0x3, %zmm1, %zmm2
vpsubq %zmm2, %zmm1, %zmm1
vpaddq %zmm1, %zmm0, %zmm0
vmovdqu64 %zmm0, (%rsi)
vzeroupper
retq
nopw %cs:(%rax,%rax)
<v4i64_srem>:
vmovdqu (%rdi), %ymm0
vpbroadcastq (%rip), %ymm2 # 0x40d <v4i64_srem+0xd>
vpbroadcastq (%rip), %ymm6 # 0x416 <v4i64_srem+0x16>
vpxor %xmm4, %xmm4, %xmm4
vpsraq $0x20, %ymm0, %ymm1
vpmuludq %ymm6, %ymm0, %ymm5
vpmuldq %ymm2, %ymm1, %ymm3
vpmuludq %ymm2, %ymm0, %ymm2
vpmuldq %ymm6, %ymm1, %ymm1
vpsrlq $0x20, %ymm2, %ymm2
vpaddq %ymm2, %ymm3, %ymm2
vpsraq $0x20, %ymm2, %ymm3
vpblendd $0xaa, %ymm4, %ymm2, %ymm2 # ymm2 = ymm2[0],ymm4[1],ymm2[2],ymm4[3],ymm2[4],ymm4[5],ymm2[6],ymm4[7]
vpaddq %ymm2, %ymm5, %ymm2
vpaddq %ymm3, %ymm1, %ymm1
vpsraq $0x20, %ymm2, %ymm2
vpaddq %ymm2, %ymm1, %ymm1
vpsrlq $0x3f, %ymm1, %ymm2
vpsraq $0x1, %ymm1, %ymm1
vpaddq %ymm2, %ymm1, %ymm1
vpsllq $0x3, %ymm1, %ymm2
vpsubq %ymm2, %ymm1, %ymm1
vpaddq %ymm1, %ymm0, %ymm0
vmovdqu %ymm0, (%rsi)
vzeroupper
retq
```
LV (-fno-unroll-loops):
```asm
<v8i64_udiv>:
vmovdqu64 (%rdi), %zmm0
vpbroadcastq (%rip), %zmm2 # 0x10 <v8i64_udiv+0x10>
vpbroadcastq (%rip), %zmm4 # 0x1a <v8i64_udiv+0x1a>
vpsrlq $0x20, %zmm0, %zmm1
vpmuludq %zmm4, %zmm0, %zmm5
vpmuludq %zmm2, %zmm1, %zmm3
vpmuludq %zmm2, %zmm0, %zmm2
vpmuludq %zmm4, %zmm1, %zmm1
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm3, %zmm2
vpsrlq $0x20, %zmm2, %zmm3
vpandq (%rip){1to8}, %zmm2, %zmm2 # 0x57 <v8i64_udiv+0x57>
vpaddq %zmm3, %zmm1, %zmm1
vpaddq %zmm2, %zmm5, %zmm2
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm1, %zmm1
vpsubq %zmm1, %zmm0, %zmm0
vpsrlq $0x1, %zmm0, %zmm0
vpaddq %zmm1, %zmm0, %zmm0
vpsrlq $0x2, %zmm0, %zmm0
vmovdqu64 %zmm0, (%rsi)
vzeroupper
retq
nopw %cs:(%rax,%rax)
<v4i64_udiv>:
movabsq $0x2492492492492493, %r8 # imm = 0x2492492492492493
xorl %ecx, %ecx
nopl (%rax)
movq 0x8(%rdi,%rcx,8), %rdx
movq (%rdi,%rcx,8), %rax
mulxq %r8, %r9, %r9
subq %r9, %rdx
shrq %rdx
addq %r9, %rdx
vmovq %rdx, %xmm0
movq %rax, %rdx
mulxq %r8, %rdx, %rdx
subq %rdx, %rax
shrq %rax
addq %rdx, %rax
vmovq %rax, %xmm1
vpunpcklqdq %xmm0, %xmm1, %xmm0 # xmm0 = xmm1[0],xmm0[0]
vpsrlq $0x2, %xmm0, %xmm0
vmovdqu %xmm0, (%rsi,%rcx,8)
addq $0x2, %rcx
cmpq $0x4, %rcx
jne 0xb0 <v4i64_udiv+0x10>
retq
nopl (%rax,%rax)
<v8i64_sdiv>:
vmovdqu64 (%rdi), %zmm0
vpbroadcastq (%rip), %zmm2 # 0x110 <v8i64_sdiv+0x10>
vpbroadcastq (%rip), %zmm4 # 0x11a <v8i64_sdiv+0x1a>
vpsraq $0x20, %zmm0, %zmm1
vpmuldq %zmm2, %zmm1, %zmm3
vpmuludq %zmm2, %zmm0, %zmm2
vpmuludq %zmm4, %zmm0, %zmm0
vpmuldq %zmm4, %zmm1, %zmm1
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm3, %zmm2
vpsraq $0x20, %zmm2, %zmm3
vpandq (%rip){1to8}, %zmm2, %zmm2 # 0x157 <v8i64_sdiv+0x57>
vpaddq %zmm3, %zmm1, %zmm1
vpaddq %zmm2, %zmm0, %zmm0
vpsraq $0x20, %zmm0, %zmm0
vpaddq %zmm0, %zmm1, %zmm0
vpsrlq $0x3f, %zmm0, %zmm1
vpsraq $0x1, %zmm0, %zmm0
vpaddq %zmm1, %zmm0, %zmm0
vmovdqu64 %zmm0, (%rsi)
vzeroupper
retq
nop
<v4i64_sdiv>:
movabsq $0x4924924924924925, %rcx # imm = 0x4924924924924925
xorl %r8d, %r8d
nopl (%rax)
movq %rcx, %rax
imulq 0x8(%rdi,%r8,8)
movq %rdx, %rax
shrq $0x3f, %rax
sarq %rdx
addq %rax, %rdx
movq %rcx, %rax
vmovq %rdx, %xmm0
imulq (%rdi,%r8,8)
movq %rdx, %rax
shrq $0x3f, %rax
sarq %rdx
addq %rax, %rdx
vmovq %rdx, %xmm1
vpunpcklqdq %xmm0, %xmm1, %xmm0 # xmm0 = xmm1[0],xmm0[0]
vmovdqu %xmm0, (%rsi,%r8,8)
addq $0x2, %r8
cmpq $0x4, %r8
jne 0x1a0 <v4i64_sdiv+0x10>
retq
nopl (%rax,%rax)
<v8i64_urem>:
vmovdqu64 (%rdi), %zmm0
vpbroadcastq (%rip), %zmm2 # 0x200 <v8i64_urem+0x10>
vpbroadcastq (%rip), %zmm4 # 0x20a <v8i64_urem+0x1a>
vpsrlq $0x20, %zmm0, %zmm1
vpmuludq %zmm4, %zmm0, %zmm5
vpmuludq %zmm2, %zmm1, %zmm3
vpmuludq %zmm2, %zmm0, %zmm2
vpmuludq %zmm4, %zmm1, %zmm1
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm3, %zmm2
vpsrlq $0x20, %zmm2, %zmm3
vpandq (%rip){1to8}, %zmm2, %zmm2 # 0x247 <v8i64_urem+0x57>
vpaddq %zmm3, %zmm1, %zmm1
vpaddq %zmm2, %zmm5, %zmm2
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm1, %zmm1
vpsubq %zmm1, %zmm0, %zmm2
vpsrlq $0x1, %zmm2, %zmm2
vpaddq %zmm1, %zmm2, %zmm1
vpsrlq $0x2, %zmm1, %zmm1
vpsllq $0x3, %zmm1, %zmm2
vpsubq %zmm2, %zmm1, %zmm1
vpaddq %zmm1, %zmm0, %zmm0
vmovdqu64 %zmm0, (%rsi)
vzeroupper
retq
nopw (%rax,%rax)
<v4i64_urem>:
movabsq $0x2492492492492493, %r8 # imm = 0x2492492492492493
xorl %ecx, %ecx
nopl (%rax)
movq 0x8(%rdi,%rcx,8), %rdx
movq (%rdi,%rcx,8), %rax
mulxq %r8, %r9, %r9
movq %rdx, %r10
subq %r9, %r10
shrq %r10
addq %r9, %r10
shrq $0x2, %r10
leaq (,%r10,8), %r9
subq %r9, %r10
movq %rax, %r9
addq %rdx, %r10
movq %rax, %rdx
mulxq %r8, %rdx, %rdx
vmovq %r10, %xmm0
subq %rdx, %r9
shrq %r9
addq %rdx, %r9
shrq $0x2, %r9
leaq (,%r9,8), %rdx
subq %rdx, %r9
addq %rax, %r9
vmovq %r9, %xmm1
vpunpcklqdq %xmm0, %xmm1, %xmm0 # xmm0 = xmm1[0],xmm0[0]
vmovdqu %xmm0, (%rsi,%rcx,8)
addq $0x2, %rcx
cmpq $0x4, %rcx
jne 0x2b0 <v4i64_urem+0x10>
retq
<v8i64_srem>:
vmovdqu64 (%rdi), %zmm0
vpbroadcastq (%rip), %zmm2 # 0x330 <v8i64_srem+0x10>
vpbroadcastq (%rip), %zmm4 # 0x33a <v8i64_srem+0x1a>
vpsraq $0x20, %zmm0, %zmm1
vpmuludq %zmm4, %zmm0, %zmm5
vpmuldq %zmm2, %zmm1, %zmm3
vpmuludq %zmm2, %zmm0, %zmm2
vpmuldq %zmm4, %zmm1, %zmm1
vpsrlq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm3, %zmm2
vpsraq $0x20, %zmm2, %zmm3
vpandq (%rip){1to8}, %zmm2, %zmm2 # 0x377 <v8i64_srem+0x57>
vpaddq %zmm3, %zmm1, %zmm1
vpaddq %zmm2, %zmm5, %zmm2
vpsraq $0x20, %zmm2, %zmm2
vpaddq %zmm2, %zmm1, %zmm1
vpsrlq $0x3f, %zmm1, %zmm2
vpsraq $0x1, %zmm1, %zmm1
vpaddq %zmm2, %zmm1, %zmm1
vpsllq $0x3, %zmm1, %zmm2
vpsubq %zmm2, %zmm1, %zmm1
vpaddq %zmm1, %zmm0, %zmm0
vmovdqu64 %zmm0, (%rsi)
vzeroupper
retq
nopw %cs:(%rax,%rax)
<v4i64_srem>:
movabsq $0x4924924924924925, %r10 # imm = 0x4924924924924925
xorl %r9d, %r9d
nopl (%rax)
movq 0x8(%rdi,%r9,8), %r8
movq (%rdi,%r9,8), %rcx
movq %r8, %rax
imulq %r10
movq %rdx, %rax
shrq $0x3f, %rax
sarq %rdx
addq %rax, %rdx
leaq (,%rdx,8), %rax
subq %rax, %rdx
movq %rcx, %rax
addq %r8, %rdx
vmovq %rdx, %xmm0
imulq %r10
movq %rdx, %rax
shrq $0x3f, %rax
sarq %rdx
addq %rax, %rdx
leaq (,%rdx,8), %rax
subq %rax, %rdx
addq %rcx, %rdx
vmovq %rdx, %xmm1
vpunpcklqdq %xmm0, %xmm1, %xmm0 # xmm0 = xmm1[0],xmm0[0]
vmovdqu %xmm0, (%rsi,%r9,8)
addq $0x2, %r9
cmpq $0x4, %r9
jne 0x3e0 <v4i64_srem+0x10>
retq
```
https://github.com/llvm/llvm-project/pull/208491
More information about the llvm-commits
mailing list