Skip to content

Commit 757e4a7

Browse files
authored
[SYCL] Correctly handle special values in fast math mode (#9278)
This PR fixes [stream](https://github.com/intel/llvm/blob/sycl/sycl/test-e2e/Basic/stream/stream.cpp#L1) tests that resulted in hangs for CUDA. An implication of using `-ffast-math` is that the compiler is not required to honour `nan` and `inf`. As a result calls to [checkForInfNan](https://github.com/intel/llvm/blob/sycl/sycl/include/sycl/stream.hpp#L378) were optimized away breaking the logic of `ScalarToStr`. The patch provides a manual way of detecting `nan` and `inf` when in fast math mode.
1 parent e3fc16f commit 757e4a7

File tree

1 file changed

+68
-2
lines changed

1 file changed

+68
-2
lines changed

sycl/include/sycl/stream.hpp

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,80 @@ inline unsigned append(char *Dst, const char *Src) {
226226
return Len;
227227
}
228228

229+
static inline unsigned F2I32(float Val) {
230+
union {
231+
float FVal;
232+
unsigned I32Val;
233+
} Internal;
234+
Internal.FVal = Val;
235+
return Internal.I32Val;
236+
}
237+
238+
static inline unsigned long long D2I64(double Val) {
239+
union {
240+
double DVal;
241+
unsigned long long I64Val;
242+
} Internal;
243+
Internal.DVal = Val;
244+
return Internal.I64Val;
245+
}
246+
247+
template <typename T>
248+
inline typename detail::enable_if_t<
249+
std::is_same<T, float>::value || std::is_same<T, double>::value, bool>
250+
isFastMathInf(T Val) {
251+
if constexpr (sizeof(Val) == 4) {
252+
return (F2I32(Val) & 0x7fffffff) == 0x7f800000;
253+
} else if constexpr (sizeof(Val) == 8) {
254+
return (D2I64(Val) & -1ULL >> 1) == 0x7ffULL << 52;
255+
}
256+
257+
return false;
258+
}
259+
229260
template <typename T>
230-
inline typename std::enable_if_t<
231-
std::is_same_v<T, float> || std::is_same_v<T, double>, unsigned>
261+
inline typename detail::enable_if_t<
262+
std::is_same<T, float>::value || std::is_same<T, double>::value, bool>
263+
isFastMathNan(T Val) {
264+
if constexpr (sizeof(Val) == 4) {
265+
return (F2I32(Val) & 0x7fffffff) > 0x7f800000;
266+
} else if constexpr (sizeof(Val) == 8) {
267+
return (D2I64(Val) & -1ULL >> 1) > 0x7ffULL << 52;
268+
}
269+
270+
return false;
271+
}
272+
273+
template <typename T>
274+
inline typename detail::enable_if_t<
275+
std::is_same<T, float>::value || std::is_same<T, double>::value, bool>
276+
isFastMathSignBit(T Val) {
277+
if constexpr (sizeof(Val) == 4) {
278+
return F2I32(Val) >> 31;
279+
} else if constexpr (sizeof(Val) == 8) {
280+
return D2I64(Val) >> 63;
281+
}
282+
283+
return false;
284+
}
285+
286+
template <typename T>
287+
typename detail::enable_if_t<
288+
std::is_same<T, float>::value || std::is_same<T, double>::value, unsigned>
232289
checkForInfNan(char *Buf, T Val) {
290+
#ifdef __FAST_MATH__
291+
if (isFastMathNan(Val))
292+
#else
233293
if (isnan(Val))
294+
#endif
234295
return append(Buf, "nan");
296+
#ifdef __FAST_MATH__
297+
if (isFastMathInf(Val)) {
298+
if (isFastMathSignBit(Val))
299+
#else
235300
if (isinf(Val)) {
236301
if (signbit(Val))
302+
#endif
237303
return append(Buf, "-inf");
238304
return append(Buf, "inf");
239305
}

0 commit comments

Comments
 (0)