@@ -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