[X86] SSE v4f32 isinf/isnan mask result in different ways:
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
https://godbolt.org/z/svGY5EceY
```cpp
#include
__m128i _mm_isnan_ps(__m128 x) {
return _mm_setr_epi32(
__builtin_isnan(x[0]),
__builtin_isnan(x[1]),
__builtin_isnan(x[2]),
__builtin_isnan(x[3])
);
}
__m128i _mm_isinf_ps(__m128 x) {
return _mm_setr_epi32(
__builtin_isinf(x[0]),
__builtin_isinf(x[1]),
__builtin_isinf(x[2]),
__builtin_isinf(x[3])
);
}
```
```ll
define <2 x i64> @_mm_isnan_ps(<4 x float> %x) {
entry:
%0 = fcmp uno <4 x float> %x, zeroinitializer
%1 = zext <4 x i1> %0 to <4 x i32>
%2 = bitcast <4 x i32> %1 to <2 x i64>
ret <2 x i64> %2
}
define <2 x i64> @_mm_isinf_ps(<4 x float> %x) {
entry:
%0 = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
%1 = fcmp oeq <4 x float> %0, splat (float 0x7FF0000000000000)
%2 = zext <4 x i1> %1 to <4 x i32>
%3 = bitcast <4 x i32> %2 to <2 x i64>
ret <2 x i64> %3
}
```
```asm
_mm_isnan_ps(float vector[4]):
vxorps %xmm1, %xmm1, %xmm1
vcmpunordps %xmm1, %xmm0, %xmm0
vandps .LCPI0_0(%rip), %xmm0, %xmm0
retq
_mm_isinf_ps(float vector[4]):
vpand .LCPI1_0(%rip), %xmm0, %xmm0
vpcmpeqd .LCPI1_1(%rip), %xmm0, %xmm0
vpsrld $31, %xmm0, %xmm0
retq
```
Both have allbits (-1/0 cmp results) - but isnan choses to AND the result (costing an extra constant pool load), while isinf uses vpsrld to shift.
Contributor guide
Assessment
This issue has not been assessed yet.