[X86] Consider not emitting `pext`/`pdep` for constant masks with `slow-pdep`
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
```llvm
define i32 @test(i32 %a) {
%r = call i32 @llvm.pdep.i32(i32 %a, i32 61680) ; 0xf0f0
ret i32 %r
}
```
With `-mattr=+bmi2,+slow-pdep` (https://godbolt.org/z/fv9a8cbrf):
```asm
test: # @test
mov eax, 61680
pdep eax, edi, eax
ret
```
This output seems extremely suspicious because `pext` and `pdep` on Zen 1/2 are known to be extremely slow, which is what the `slow-pdep` flag is for. Removing the `bmi2` flag yields:
```asm
test: # @test
mov ecx, edi
shl ecx, 8
and ecx, 61440
shl edi, 4
movzx eax, dil
or eax, ecx
ret
```
This seems "obviously" better and boils down to
```cpp
((a >> 8) & 0xf0) | ((a >> 4) & 0xf)
```
I haven't done any benchmarking yet, but the latter code may be an order of magnitude faster. It's still somewhat reasonable to use `pdep` directly in the case of runtime masks because the difference would shrink and because it has vastly lower code size, but for constant masks, it's hard to justify using `pext` and `pdep` on Zen 2.
CC @RKSimon
Contributor guide
Assessment
This issue has not been assessed yet.