GCC C vector extension: How to check if result of ANY element-wise comparison is true, and which?
Clang's vector extension do a good job with the any
function.
#if defined(__clang__)
typedef int64_t vli __attribute__ ((ext_vector_type(VLI_SIZE)));
typedef double vdf __attribute__ ((ext_vector_type(VDF_SIZE)));
#else
typedef int32_t vsi __attribute__ ((vector_size (SIMD_SIZE)));
typedef int64_t vli __attribute__ ((vector_size (SIMD_SIZE)));
#endif
static bool any(vli const & x) {
for(int i=0; i<VLI_SIZE; i++) if(x[i]) return true;
return false;
}
Assembly
any(long __vector(4) const&): # @any(long __vector(4) const&)
vmovdqa ymm0, ymmword ptr [rdi]
vptest ymm0, ymm0
setne al
vzeroupper
ret
Although pmovmskb
might still be a better choice ptest
is still a huge improvement over what GCC does
any(long __vector(4) const&):
cmp QWORD PTR [rdi], 0
jne .L5
cmp QWORD PTR [rdi+8], 0
jne .L5
cmp QWORD PTR [rdi+16], 0
jne .L5
cmp QWORD PTR [rdi+24], 0
setne al
ret
.L5:
mov eax, 1
ret
GCC should fix this. Clang is not optimal for AVX512 though.
The any
function I would argue is a critical vector function so compilers should either provide a builtin like they do for shuffle (e.g. __builtin_shuffle
for GCC and __builtin_shufflevector
for clang) or the compiler should be smart enough to figure out the optimal code like Clang does at least for SSE and AVX but not AVX512.