Simple mask operations with AVX512 degrade to scalar operations
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
I have two masks, 127 and one calculated using `_mm_cmpeq_epi8_mask`... If I try to compare them, Clang generates
```asm
mov ax, 127
kmovd k1, eax
vpcmpeqb k0 {k1}, xmm0, xmmword ptr [rip + .LCPI0_0]
kmovd ecx, k0
mov eax, -1
cmp cx, 127
je .LBB0_1
```
Which contains two moves across execution units, when GCC can avoid the second one. Masks like 127, which is essentially sequence of 1 bits should be able to be generated inside the mask register itself (NOT 0 = 65535, shift right by 9 bits = 127).
GCC generates:
```asm
mov eax, 127
kmovw k1, eax
vpcmpeqb k0, xmm0, XMMWORD PTR .LC1[rip]
kandw k0, k0, k1
kxorw k1, k0, k1
kortestw k1, k1
jne .L3
```
The relevant C code is:
```c
__mmask16 target_mask = (1U << (best_len + 1)) - 1;
__mmask16 match_mask = _mm_cmpeq_epi8_mask(scan_vec, cand_vec);
__mmask16 mask = _kand_mask16(match_mask, target_mask);
if (_kxor_mask16(mask, target_mask) == (__mmask16)0) {
...
}
```
Contributor guide
Research direction
Start from the provided C mask operations and compare the emitted Clang and GCC AVX512 assembly. Investigate the compiler path handling mask comparisons and logical operations; done means Clang avoids the scalar moves and produces mask-register operations comparable to the GCC sequence.
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
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100