llvm / llvm/llvm-project

[X86] SSE v4f32 isinf/isnan mask result in different ways:

Open
#195,439 3 comments 0 reactions 1 assignee Claimed by @Xinlong-Chen View on GitHub
backend:X86 missed-optimization
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.