[X86][AVX512] missed fold scalar load > embed broadcast
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
https://godbolt.org/z/4hb7vfz5K
```c++
void foo(int32_t &a , int32_t &b, int32_t &c){
c = a > b ? a : b;
}
void foo2(uint32_t &a , uint32_t &b, uint32_t &c){
c = a < b ? a : b;
}
float foo3(int &a){
return a;
}
```
```asm
foo(int&, int&, int&):
vmovd xmm0, dword ptr [rsi]
vmovd xmm1, dword ptr [rdi]
vpmaxsd xmm0, xmm1, xmm0
vmovd dword ptr [rdx], xmm0
ret
foo2(unsigned int&, unsigned int&, unsigned int&):
vmovd xmm0, dword ptr [rsi]
vmovd xmm1, dword ptr [rdi]
vpminud xmm0, xmm1, xmm0
vmovd dword ptr [rdx], xmm0
ret
foo3(int&):
vcvtsi2ss xmm0, xmm15, dword ptr [rdi]
ret
```
should be
```c++
typedef int32_t i32 [[gnu::vector_size(16)]];
typedef uint32_t u32 [[gnu::vector_size(16)]];
typedef float f32 [[gnu::vector_size(16)]];
void bar(int32_t &a , int32_t &b, int32_t &c){
i32 x = i32{a,0,0,0};
i32 y = i32{b,b,b,b};
i32 z = x > y ? x : y;
c=z[0];
}
void bar2(uint32_t &a , uint32_t &b, uint32_t &c){
u32 x = u32{a,0,0,0};
u32 y = u32{b,b,b,b};
u32 z = x < y ? x : y;
c=z[0];
}
f32 bar3(int32_t &a){
return __builtin_convertvector(i32{a,a,a,a}, f32);
}
```
```asm
bar(int&, int&, int&):
vmovd xmm0, dword ptr [rdi]
vpmaxsd xmm0, xmm0, dword ptr [rsi]{1to4}
vmovd dword ptr [rdx], xmm0
ret
bar2(unsigned int&, unsigned int&, unsigned int&):
vmovd xmm0, dword ptr [rdi]
vpminud xmm0, xmm0, dword ptr [rsi]{1to4}
vmovd dword ptr [rdx], xmm0
ret
bar3(int&):
vcvtdq2ps xmm0, dword ptr [rdi]{1to4}
ret
```
In the first case (min/max/abs), this can save one load instruction.
In the second case (int2float), this can avoid the unnecessary second source operand.
Contributor guide
Research direction
Start with the Godbolt reproducer and compare the generated AVX-512 assembly for foo/bar, foo2/bar2, and foo3/bar3. Investigate the compiler's x86 vector optimization path for scalar-load folding and embedded broadcasts. Done means the first cases use a scalar load with an embedded broadcast, while the integer-to-float case avoids the unnecessary second source operand.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100