Skip to content

Commit fdb07bb

Browse files
authored
Update IsNan tests for -fmath-finite-only scenarios (#184)
1 parent c9a31a6 commit fdb07bb

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

Inc/DirectXMathVector.inl

+51-1
Original file line numberDiff line numberDiff line change
@@ -2172,13 +2172,33 @@ inline XMVECTOR XM_CALLCONV XMVectorIsNaN(FXMVECTOR V) noexcept
21722172
return Control.v;
21732173

21742174
#elif defined(_XM_ARM_NEON_INTRINSICS_)
2175+
#if defined(__clang__) && defined(__FINITE_MATH_ONLY__)
2176+
XMVECTORU32 vResult = { { {
2177+
isnan(vgetq_lane_f32(V, 0)) ? 0xFFFFFFFFU : 0,
2178+
isnan(vgetq_lane_f32(V, 1)) ? 0xFFFFFFFFU : 0,
2179+
isnan(vgetq_lane_f32(V, 2)) ? 0xFFFFFFFFU : 0,
2180+
isnan(vgetq_lane_f32(V, 3)) ? 0xFFFFFFFFU : 0 } } };
2181+
return vResult.v;
2182+
#else
21752183
// Test against itself. NaN is always not equal
21762184
uint32x4_t vTempNan = vceqq_f32(V, V);
21772185
// Flip results
21782186
return vreinterpretq_f32_u32(vmvnq_u32(vTempNan));
2179-
#elif defined(_XM_SSE_INTRINSICS_)
2187+
#endif
2188+
#elif defined(_XM_SSE_INTRINSICS_)
2189+
#if defined(__clang__) && defined(__FINITE_MATH_ONLY__)
2190+
XM_ALIGNED_DATA(16) float tmp[4];
2191+
_mm_store_ps(tmp, V);
2192+
XMVECTORU32 vResult = { { {
2193+
isnan(tmp[0]) ? 0xFFFFFFFFU : 0,
2194+
isnan(tmp[1]) ? 0xFFFFFFFFU : 0,
2195+
isnan(tmp[2]) ? 0xFFFFFFFFU : 0,
2196+
isnan(tmp[3]) ? 0xFFFFFFFFU : 0 } } };
2197+
return vResult.v;
2198+
#else
21802199
// Test against itself. NaN is always not equal
21812200
return _mm_cmpneq_ps(V, V);
2201+
#endif
21822202
#endif
21832203
}
21842204

@@ -6619,16 +6639,26 @@ inline bool XM_CALLCONV XMVector2IsNaN(FXMVECTOR V) noexcept
66196639
return (XMISNAN(V.vector4_f32[0]) ||
66206640
XMISNAN(V.vector4_f32[1]));
66216641
#elif defined(_XM_ARM_NEON_INTRINSICS_)
6642+
#if defined(__clang__) && defined(__FINITE_MATH_ONLY__)
6643+
return isnan(vgetq_lane_f32(V, 0)) || isnan(vgetq_lane_f32(V, 1));
6644+
#else
66226645
float32x2_t VL = vget_low_f32(V);
66236646
// Test against itself. NaN is always not equal
66246647
uint32x2_t vTempNan = vceq_f32(VL, VL);
66256648
// If x or y are NaN, the mask is zero
66266649
return (vget_lane_u64(vreinterpret_u64_u32(vTempNan), 0) != 0xFFFFFFFFFFFFFFFFU);
6650+
#endif
66276651
#elif defined(_XM_SSE_INTRINSICS_)
6652+
#if defined(__clang__) && defined(__FINITE_MATH_ONLY__)
6653+
XM_ALIGNED_DATA(16) float tmp[4];
6654+
_mm_store_ps(tmp, V);
6655+
return isnan(tmp[0]) || isnan(tmp[1]);
6656+
#else
66286657
// Test against itself. NaN is always not equal
66296658
XMVECTOR vTempNan = _mm_cmpneq_ps(V, V);
66306659
// If x or y are NaN, the mask is non-zero
66316660
return ((_mm_movemask_ps(vTempNan) & 3) != 0);
6661+
#endif
66326662
#endif
66336663
}
66346664

@@ -9374,17 +9404,27 @@ inline bool XM_CALLCONV XMVector3IsNaN(FXMVECTOR V) noexcept
93749404
XMISNAN(V.vector4_f32[2]));
93759405

93769406
#elif defined(_XM_ARM_NEON_INTRINSICS_)
9407+
#if defined(__clang__) && defined(__FINITE_MATH_ONLY__)
9408+
return isnan(vgetq_lane_f32(V, 0)) || isnan(vgetq_lane_f32(V, 1)) || isnan(vgetq_lane_f32(V, 2));
9409+
#else
93779410
// Test against itself. NaN is always not equal
93789411
uint32x4_t vTempNan = vceqq_f32(V, V);
93799412
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vreinterpretq_u8_u32(vTempNan)), vget_high_u8(vreinterpretq_u8_u32(vTempNan)));
93809413
uint16x4x2_t vTemp2 = vzip_u16(vreinterpret_u16_u8(vTemp.val[0]), vreinterpret_u16_u8(vTemp.val[1]));
93819414
// If x or y or z are NaN, the mask is zero
93829415
return ((vget_lane_u32(vreinterpret_u32_u16(vTemp2.val[1]), 1) & 0xFFFFFFU) != 0xFFFFFFU);
9416+
#endif
93839417
#elif defined(_XM_SSE_INTRINSICS_)
9418+
#if defined(__clang__) && defined(__FINITE_MATH_ONLY__)
9419+
XM_ALIGNED_DATA(16) float tmp[4];
9420+
_mm_store_ps(tmp, V);
9421+
return isnan(tmp[0]) || isnan(tmp[1]) || isnan(tmp[2]);
9422+
#else
93849423
// Test against itself. NaN is always not equal
93859424
XMVECTOR vTempNan = _mm_cmpneq_ps(V, V);
93869425
// If x or y or z are NaN, the mask is non-zero
93879426
return ((_mm_movemask_ps(vTempNan) & 7) != 0);
9427+
#endif
93889428
#endif
93899429
}
93909430

@@ -13255,17 +13295,27 @@ inline bool XM_CALLCONV XMVector4IsNaN(FXMVECTOR V) noexcept
1325513295
XMISNAN(V.vector4_f32[2]) ||
1325613296
XMISNAN(V.vector4_f32[3]));
1325713297
#elif defined(_XM_ARM_NEON_INTRINSICS_)
13298+
#if defined(__clang__) && defined(__FINITE_MATH_ONLY__)
13299+
return isnan(vgetq_lane_f32(V, 0)) || isnan(vgetq_lane_f32(V, 1)) || isnan(vgetq_lane_f32(V, 2)) || isnan(vgetq_lane_f32(V, 3));
13300+
#else
1325813301
// Test against itself. NaN is always not equal
1325913302
uint32x4_t vTempNan = vceqq_f32(V, V);
1326013303
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vreinterpretq_u8_u32(vTempNan)), vget_high_u8(vreinterpretq_u8_u32(vTempNan)));
1326113304
uint16x4x2_t vTemp2 = vzip_u16(vreinterpret_u16_u8(vTemp.val[0]), vreinterpret_u16_u8(vTemp.val[1]));
1326213305
// If any are NaN, the mask is zero
1326313306
return (vget_lane_u32(vreinterpret_u32_u16(vTemp2.val[1]), 1) != 0xFFFFFFFFU);
13307+
#endif
1326413308
#elif defined(_XM_SSE_INTRINSICS_)
13309+
#if defined(__clang__) && defined(__FINITE_MATH_ONLY__)
13310+
XM_ALIGNED_DATA(16) float tmp[4];
13311+
_mm_store_ps(tmp, V);
13312+
return isnan(tmp[0]) || isnan(tmp[1]) || isnan(tmp[2]) || isnan(tmp[3]);
13313+
#else
1326513314
// Test against itself. NaN is always not equal
1326613315
XMVECTOR vTempNan = _mm_cmpneq_ps(V, V);
1326713316
// If any are NaN, the mask is non-zero
1326813317
return (_mm_movemask_ps(vTempNan) != 0);
13318+
#endif
1326913319
#endif
1327013320
}
1327113321

0 commit comments

Comments
 (0)