[X86] suboptimal v64i8SAD codegen
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
found from https://github.com/gcc-mirror/gcc/commit/50be38676af8ed32744b856ad6864302f7b400bc
https://godbolt.org/z/h4s7Mnc4h
```c
#define N 32
unsigned char upix1[N], upix2[N];
signed char spix1[N], spix2[N];
int
ufoo (void)
{
int sum = 0;
int i;
for (i = 0; i < N; ++i)
sum += __builtin_abs (upix1[i] - upix2[i]);
return sum;
}
```
gcc:
```asm
ufoo():
vmovdqa upix1(%rip), %ymm1
vpsadbw upix2(%rip), %ymm1, %ymm1
vextracti32x4 $0x1, %ymm1, %xmm0
vpaddd %xmm1, %xmm0, %xmm0
vpsrldq $8, %xmm0, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vpsrldq $4, %xmm0, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vmovd %xmm0, %eax
vzeroupper
ret
spix2:
.zero 32
spix1:
.zero 32
upix2:
.zero 32
upix1:
.zero 32
```
clang:
```asm
ufoo():
vmovdqa upix1(%rip), %ymm0
vpsadbw upix2(%rip), %ymm0, %ymm0
vextracti128 $1, %ymm0, %xmm1
vpaddq %xmm1, %xmm0, %xmm0
vpshufd $238, %xmm0, %xmm1
vpaddq %xmm1, %xmm0, %xmm0
vmovd %xmm0, %eax
vzeroupper
retq
upix1:
.zero 32
upix2:
.zero 32
spix1:
.zero 32
spix2:
.zero 32
```
but
```c
#define N 64
unsigned char upix1[N], upix2[N];
signed char spix1[N], spix2[N];
int
ufoo (void)
{
int sum = 0;
int i;
for (i = 0; i < N; ++i)
sum += __builtin_abs (upix1[i] - upix2[i]);
return sum;
}
```
gcc:
```asm
ufoo():
vmovdqa64 upix1(%rip), %zmm0
vpsadbw upix2(%rip), %zmm0, %zmm0
vextracti32x8 $0x1, %zmm0, %ymm1
vpaddd %ymm0, %ymm1, %ymm1
vextracti32x4 $0x1, %ymm1, %xmm0
vpaddd %xmm1, %xmm0, %xmm0
vpsrldq $8, %xmm0, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vpsrldq $4, %xmm0, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vmovd %xmm0, %eax
vzeroupper
ret
spix2:
.zero 64
spix1:
.zero 64
upix2:
.zero 64
upix1:
.zero 64
```
clang -mllvm -vectorizer-maximize-bandwidth:
```asm
.LCPI0_1:
.zero 4,1
ufoo():
vmovdqa64 upix1(%rip), %zmm0
vmovdqa64 upix2(%rip), %zmm1
vpminub %zmm1, %zmm0, %zmm2
vpmaxub %zmm1, %zmm0, %zmm0
vpsubb %zmm2, %zmm0, %zmm0
vpxor %xmm1, %xmm1, %xmm1
vpdpbuud .LCPI0_1(%rip){1to16}, %zmm0, %zmm1
vextracti64x4 $1, %zmm1, %ymm0
vpaddd %zmm0, %zmm1, %zmm0
vextracti128 $1, %ymm0, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vpshufd $238, %xmm0, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vpshufd $85, %xmm0, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vmovd %xmm0, %eax
vzeroupper
retq
upix1:
.zero 64
upix2:
.zero 64
spix1:
.zero 64
spix2:
.zero 64
```
clang -mllvm -vectorizer-maximize-bandwidth=false
```asm
ufoo():
vmovdqa upix1+48(%rip), %xmm0
vpsadbw upix2+48(%rip), %xmm0, %xmm0
vmovdqa upix1+32(%rip), %xmm1
vpsadbw upix2+32(%rip), %xmm1, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vmovdqa upix1+16(%rip), %xmm1
vpsadbw upix2+16(%rip), %xmm1, %xmm1
vmovdqa upix1(%rip), %xmm2
vpsadbw upix2(%rip), %xmm2, %xmm2
vpaddd %xmm2, %xmm1, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vpshufd $238, %xmm0, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vpshufd $85, %xmm0, %xmm1
vpaddd %xmm1, %xmm0, %xmm0
vmovd %xmm0, %eax
retq
upix1:
.zero 64
upix2:
.zero 64
spix1:
.zero 64
spix2:
.zero 64
```
Contributor guide
Research direction
Start by reproducing the N=32 and N=64 C examples from the issue in Clang and inspecting the generated x86 assembly, using the linked Godbolt case for comparison. Compare the default output with the two vectorizer-maximize-bandwidth modes; done means the reported suboptimal v64i8 SAD code generation is improved without regressing the shown cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100