@@ -2172,13 +2172,33 @@ inline XMVECTOR XM_CALLCONV XMVectorIsNaN(FXMVECTOR V) noexcept
2172
2172
return Control.v;
2173
2173
2174
2174
#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
2175
2183
// Test against itself. NaN is always not equal
2176
2184
uint32x4_t vTempNan = vceqq_f32(V, V);
2177
2185
// Flip results
2178
2186
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
2180
2199
// Test against itself. NaN is always not equal
2181
2200
return _mm_cmpneq_ps(V, V);
2201
+ #endif
2182
2202
#endif
2183
2203
}
2184
2204
@@ -6619,16 +6639,26 @@ inline bool XM_CALLCONV XMVector2IsNaN(FXMVECTOR V) noexcept
6619
6639
return (XMISNAN(V.vector4_f32[0]) ||
6620
6640
XMISNAN(V.vector4_f32[1]));
6621
6641
#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
6622
6645
float32x2_t VL = vget_low_f32(V);
6623
6646
// Test against itself. NaN is always not equal
6624
6647
uint32x2_t vTempNan = vceq_f32(VL, VL);
6625
6648
// If x or y are NaN, the mask is zero
6626
6649
return (vget_lane_u64(vreinterpret_u64_u32(vTempNan), 0) != 0xFFFFFFFFFFFFFFFFU);
6650
+ #endif
6627
6651
#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
6628
6657
// Test against itself. NaN is always not equal
6629
6658
XMVECTOR vTempNan = _mm_cmpneq_ps(V, V);
6630
6659
// If x or y are NaN, the mask is non-zero
6631
6660
return ((_mm_movemask_ps(vTempNan) & 3) != 0);
6661
+ #endif
6632
6662
#endif
6633
6663
}
6634
6664
@@ -9374,17 +9404,27 @@ inline bool XM_CALLCONV XMVector3IsNaN(FXMVECTOR V) noexcept
9374
9404
XMISNAN(V.vector4_f32[2]));
9375
9405
9376
9406
#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
9377
9410
// Test against itself. NaN is always not equal
9378
9411
uint32x4_t vTempNan = vceqq_f32(V, V);
9379
9412
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vreinterpretq_u8_u32(vTempNan)), vget_high_u8(vreinterpretq_u8_u32(vTempNan)));
9380
9413
uint16x4x2_t vTemp2 = vzip_u16(vreinterpret_u16_u8(vTemp.val[0]), vreinterpret_u16_u8(vTemp.val[1]));
9381
9414
// If x or y or z are NaN, the mask is zero
9382
9415
return ((vget_lane_u32(vreinterpret_u32_u16(vTemp2.val[1]), 1) & 0xFFFFFFU) != 0xFFFFFFU);
9416
+ #endif
9383
9417
#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
9384
9423
// Test against itself. NaN is always not equal
9385
9424
XMVECTOR vTempNan = _mm_cmpneq_ps(V, V);
9386
9425
// If x or y or z are NaN, the mask is non-zero
9387
9426
return ((_mm_movemask_ps(vTempNan) & 7) != 0);
9427
+ #endif
9388
9428
#endif
9389
9429
}
9390
9430
@@ -13255,17 +13295,27 @@ inline bool XM_CALLCONV XMVector4IsNaN(FXMVECTOR V) noexcept
13255
13295
XMISNAN(V.vector4_f32[2]) ||
13256
13296
XMISNAN(V.vector4_f32[3]));
13257
13297
#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
13258
13301
// Test against itself. NaN is always not equal
13259
13302
uint32x4_t vTempNan = vceqq_f32(V, V);
13260
13303
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vreinterpretq_u8_u32(vTempNan)), vget_high_u8(vreinterpretq_u8_u32(vTempNan)));
13261
13304
uint16x4x2_t vTemp2 = vzip_u16(vreinterpret_u16_u8(vTemp.val[0]), vreinterpret_u16_u8(vTemp.val[1]));
13262
13305
// If any are NaN, the mask is zero
13263
13306
return (vget_lane_u32(vreinterpret_u32_u16(vTemp2.val[1]), 1) != 0xFFFFFFFFU);
13307
+ #endif
13264
13308
#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
13265
13314
// Test against itself. NaN is always not equal
13266
13315
XMVECTOR vTempNan = _mm_cmpneq_ps(V, V);
13267
13316
// If any are NaN, the mask is non-zero
13268
13317
return (_mm_movemask_ps(vTempNan) != 0);
13318
+ #endif
13269
13319
#endif
13270
13320
}
13271
13321
0 commit comments