llvm / llvm/llvm-project

[X86] suboptimal v64i8SAD codegen

Open
#223,977 1 comment 0 reactions 1 assignee Assigned to @RKSimon View on GitHub
backend:X86 missed-optimization vectorizers
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.