Skip to content

[SYCL][NVPTX][AMDGCN] Move MSVC math functions to headers #19718

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libdevice/msvc_math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//

#if defined(__SPIR__) || defined(__SPIRV__) || defined(__NVPTX__)
#if defined(__SPIR__) || defined(__SPIRV__)

#include "device.h"
#include <math.h>
Expand Down Expand Up @@ -281,4 +281,4 @@ float _FSinh(float x, float y) { // compute y * sinh(x), |y| <= 1
return neg ? -x : x;
}
}
#endif // __SPIR__ || __SPIRV__ || __NVPTX__
#endif // __SPIR__ || __SPIRV__
38 changes: 31 additions & 7 deletions sycl/include/sycl/stl_wrappers/__sycl_cmath_wrapper_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

// The 'sycl_device_only' attribute enables device-side overloading.
#define __SYCL_DEVICE __attribute__((sycl_device_only, always_inline))
#define __SYCL_DEVICE_C \
extern "C" __attribute__((sycl_device_only, always_inline))
#define __SYCL_DEVICE_C extern "C" __SYCL_DEVICE

#include <type_traits>

Expand Down Expand Up @@ -259,9 +258,16 @@ __SYCL_SPIRV_MAP_BINARY_C(nextafter);
__SYCL_SPIRV_MAP_BINARY_C(copysign);

/// Classification and comparison
//

// unsupported: fpclassify
__SYCL_DEVICE_C int fpclassify(float x) {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
FP_ZERO, x);
}
__SYCL_DEVICE_C int fpclassify(double x) {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
FP_ZERO, x);
}

// unsupported: isfinite
// unsupported: isinf
// unsupported: isnan
Expand Down Expand Up @@ -460,7 +466,7 @@ template <typename T> __SYCL_DEVICE __sycl_promote_t<T> scalbn(T x, int exp) {
__SYCL_SPIRV_MAP_BINARY_CXX(copysign);

// Classification and comparison
// using ::fpclassify;
using ::fpclassify;
// using ::isfinite;
// using ::isgreater;
// using ::isgreaterequal;
Expand All @@ -482,11 +488,29 @@ _GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

#if defined(_WIN32)
__SYCL_DEVICE_C double _Cosh(double x, double y) { return cosh(x) * y; }
__SYCL_DEVICE_C float _FCosh(float x, float y) { return coshf(x) * y; }
__SYCL_DEVICE_C short _Dtest(double *p) { return fpclassify(*p); }
__SYCL_DEVICE_C short _FDtest(float *p) { return fpclassify(*p); }
__SYCL_DEVICE_C double _Sinh(double x, double y) { return sinh(x) * y; }
__SYCL_DEVICE_C float _FSinh(float x, float y) { return sinhf(x) * y; }
__SYCL_DEVICE_C short _Exp(double *px, double y, short eoff) {
return exp(*px) * ldexp(y, eoff);
}
__SYCL_DEVICE_C short _FExp(float *px, float y, short eoff) {
return exp(*px) * ldexp(y, eoff);
}
__SYCL_DEVICE_C float _hypotf(float x, float y) { return hypotf(x, y); }
__SYCL_DEVICE_C int _fdsign(float x) { return __builtin_signbit(x); }
__SYCL_DEVICE_C int _dsign(double x) { return __builtin_signbit(x); }
#endif // defined(_WIN32)

#undef __SYCL_SPIRV_MAP_BINARY_C
#undef __SYCL_SPIRV_MAP_BINARY_CXX
#undef __SYCL_SPIRV_MAP_UNARY_C
#undef __SYCL_SPIRV_MAP_UNARY_CXX
#undef __SYCL_DEVICE_C
#undef __SYCL_DEVICE
#endif
#endif
#endif // __SYCL_DEVICE_ONLY__
#endif // __SYCL_CMATH_WRAPPER_IMPL_HPP__
11 changes: 11 additions & 0 deletions sycl/include/sycl/stl_wrappers/cmath
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@

#pragma once

#if defined(__SYCL_DEVICE_ONLY__) && defined(_WIN32)
#if defined(__NVPTX__) || defined(__AMDGCN__)
// Forward declare device _*dsign functions before including cmath to enable
// compilation of math functions defined in UCRT headers.
extern "C" __attribute__((sycl_device_only, always_inline)) int
_fdsign(float x);
extern "C" __attribute__((sycl_device_only, always_inline)) int
_dsign(double x);
#endif // defined(__NVPTX__) || defined(__AMDGCN__)
#endif // defined(__SYCL_DEVICE_ONLY__) && defined(_WIN32)

// Include real STL <cmath> header - the next one from the include search
// directories.
#if defined(__has_include_next)
Expand Down
4 changes: 4 additions & 0 deletions sycl/test/self-contained-headers/lit.local.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ config.test_format = SYCLHeadersTest()
# standalone. `os.path.join` is required here so the filtering works
# cross-platform
config.sycl_headers_xfail = [
# FIXME: remove this rule when the header is moved to the clang project
os.path.join(
"sycl", "stl_wrappers", "__sycl_cmath_wrapper_impl.hpp"
),
]