Skip to content

[SYCL][NFCI] Move abs and div to cstdlib header #19671

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 8 commits into from
Aug 4, 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
18 changes: 0 additions & 18 deletions libdevice/cmath_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@

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

DEVICE_EXTERN_C_INLINE
int abs(int x) { return __devicelib_abs(x); }

DEVICE_EXTERN_C_INLINE
long int labs(long int x) { return __devicelib_labs(x); }

DEVICE_EXTERN_C_INLINE
long long int llabs(long long int x) { return __devicelib_llabs(x); }

DEVICE_EXTERN_C_INLINE
float fabsf(float x) { return __devicelib_fabsf(x); }

Expand Down Expand Up @@ -51,15 +42,6 @@ float rsqrtf(float x) { return __devicelib_rsqrtf(x); }
DEVICE_EXTERN_C_INLINE
float exp10f(float x) { return __devicelib_exp10f(x); }

DEVICE_EXTERN_C_INLINE
div_t div(int x, int y) { return __devicelib_div(x, y); }

DEVICE_EXTERN_C_INLINE
ldiv_t ldiv(long x, long y) { return __devicelib_ldiv(x, y); }

DEVICE_EXTERN_C_INLINE
lldiv_t lldiv(long long x, long long y) { return __devicelib_lldiv(x, y); }

DEVICE_EXTERN_C_INLINE
float roundf(float x) { return __devicelib_roundf(x); }

Expand Down
36 changes: 0 additions & 36 deletions libdevice/device_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,6 @@
defined(__AMDGCN__)
#include <cstdint>

typedef struct {
int32_t quot;
int32_t rem;
} __devicelib_div_t_32;

typedef struct {
int64_t quot;
int64_t rem;
} __devicelib_div_t_64;

typedef __devicelib_div_t_32 div_t;
#ifdef _WIN32
typedef __devicelib_div_t_32 ldiv_t;
#else
typedef __devicelib_div_t_64 ldiv_t;
#endif
typedef __devicelib_div_t_64 lldiv_t;

DEVICE_EXTERN_C
int __devicelib_abs(int x);

DEVICE_EXTERN_C
long int __devicelib_labs(long int x);

DEVICE_EXTERN_C
long long int __devicelib_llabs(long long int x);

DEVICE_EXTERN_C
float __devicelib_fabsf(float x);

Expand Down Expand Up @@ -107,15 +80,6 @@ double __devicelib_exp10(double x);
DEVICE_EXTERN_C
float __devicelib_exp10f(float x);

DEVICE_EXTERN_C
div_t __devicelib_div(int x, int y);

DEVICE_EXTERN_C
ldiv_t __devicelib_ldiv(long int x, long int y);

DEVICE_EXTERN_C
lldiv_t __devicelib_lldiv(long long int x, long long int y);

DEVICE_EXTERN_C
double __devicelib_round(double x);

Expand Down
18 changes: 0 additions & 18 deletions libdevice/fallback-cmath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@
// TODO: generate the DeviceLibFuncMap in sycl-post-link.cpp automatically
// during the build based on libdevice to avoid manually sync.

DEVICE_EXTERN_C_INLINE
int __devicelib_abs(int x) { return x < 0 ? -x : x; }

DEVICE_EXTERN_C_INLINE
long int __devicelib_labs(long int x) { return x < 0 ? -x : x; }

DEVICE_EXTERN_C_INLINE
long long int __devicelib_llabs(long long int x) { return x < 0 ? -x : x; }

DEVICE_EXTERN_C_INLINE
float __devicelib_fabsf(float x) { return x < 0 ? -x : x; }

Expand Down Expand Up @@ -62,15 +53,6 @@ float __devicelib_rsqrtf(float x) { return __spirv_ocl_rsqrt(x); }
DEVICE_EXTERN_C_INLINE
float __devicelib_exp10f(float x) { return __spirv_ocl_exp10(x); }

DEVICE_EXTERN_C_INLINE
div_t __devicelib_div(int x, int y) { return {x / y, x % y}; }

DEVICE_EXTERN_C_INLINE
ldiv_t __devicelib_ldiv(long x, long y) { return {x / y, x % y}; }

DEVICE_EXTERN_C_INLINE
lldiv_t __devicelib_lldiv(long long x, long long y) { return {x / y, x % y}; }

DEVICE_EXTERN_C_INLINE
float __devicelib_scalbnf(float x, int n) { return __spirv_ocl_ldexp(x, n); }

Expand Down
27 changes: 0 additions & 27 deletions sycl/include/sycl/stl_wrappers/__sycl_cmath_wrapper_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,6 @@ using __sycl_promote_t =
return __spirv_ocl_##NAME((type)x, (type)y); \
}

/// <cstdlib>
// FIXME: Move this to a cstdlib fallback header.

__SYCL_DEVICE_C div_t div(int x, int y) { return {x / y, x % y}; }
__SYCL_DEVICE_C ldiv_t ldiv(long x, long y) { return {x / y, x % y}; }
__SYCL_DEVICE_C lldiv_t lldiv(long long x, long long y) {
return {x / y, x % y};
}

__SYCL_DEVICE int abs(int n) { return n < 0 ? -n : n; }
__SYCL_DEVICE_C long labs(long n) { return n < 0 ? -n : n; }
__SYCL_DEVICE_C long long llabs(long long n) { return n < 0 ? -n : n; }

/// Basic operations
//

Expand Down Expand Up @@ -299,20 +286,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
#endif

// <cstdlib>
using ::abs;
__SYCL_DEVICE long abs(long n) { return n < 0 ? -n : n; }
__SYCL_DEVICE long long abs(long long n) { return n < 0 ? -n : n; }

using ::div;
__SYCL_DEVICE ldiv_t div(long x, long y) { return {x / y, x % y}; }
__SYCL_DEVICE lldiv_t div(long long x, long long y) { return {x / y, x % y}; }

using ::labs;
using ::ldiv;
using ::llabs;
using ::lldiv;

// Basic operations
// using ::abs is already pulled in above
__SYCL_DEVICE float abs(float x) { return x < 0 ? -x : x; }
Expand Down
7 changes: 0 additions & 7 deletions sycl/include/sycl/stl_wrappers/cmath
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@

#ifdef __SYCL_DEVICE_ONLY__
extern "C" {
extern __DPCPP_SYCL_EXTERNAL_LIBC int abs(int x);
extern __DPCPP_SYCL_EXTERNAL_LIBC long int labs(long int x);
extern __DPCPP_SYCL_EXTERNAL_LIBC long long int llabs(long long int x);

extern __DPCPP_SYCL_EXTERNAL_LIBC div_t div(int x, int y);
extern __DPCPP_SYCL_EXTERNAL_LIBC ldiv_t ldiv(long int x, long int y);
extern __DPCPP_SYCL_EXTERNAL_LIBC lldiv_t lldiv(long long int x, long long int y);
extern __DPCPP_SYCL_EXTERNAL_LIBC float scalbnf(float x, int n);
extern __DPCPP_SYCL_EXTERNAL_LIBC double scalbn(double x, int n);
extern __DPCPP_SYCL_EXTERNAL_LIBC float logf(float x);
Expand Down
65 changes: 65 additions & 0 deletions sycl/include/sycl/stl_wrappers/cstdlib
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//==- cstdlib --------------------------------------------------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#pragma once

// Include real STL <cstdlib> header - the next one from the include search
// directories.
#if defined(__has_include_next)
// GCC/clang support go through this path.
#include_next <cstdlib>
#else
// MSVC doesn't support "#include_next", so we have to be creative.
// Our header is located in "stl_wrappers/cstdlib" so it won't be picked by the
// following include. MSVC's installation, on the other hand, has the layout
// where the following would result in the <cstdlib> we want. This is obviously
// hacky, but the best we can do...
#include <../include/cstdlib>
#endif

#ifdef __SYCL_DEVICE_ONLY__
extern "C" {
[[clang::sycl_device_only, clang::always_inline]] div_t div(int x, int y) { return {x / y, x % y}; }
[[clang::sycl_device_only, clang::always_inline]] ldiv_t ldiv(long x, long y) { return {x / y, x % y}; }
[[clang::sycl_device_only, clang::always_inline]] lldiv_t lldiv(long long x, long long y) { return {x / y, x % y}; }

[[clang::sycl_device_only, clang::always_inline]] int abs(int n) { return n < 0 ? -n : n; }
[[clang::sycl_device_only, clang::always_inline]] long labs(long n) { return n < 0 ? -n : n; }
[[clang::sycl_device_only, clang::always_inline]] long long llabs(long long n) { return n < 0 ? -n : n; }
}

#ifdef _LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_BEGIN_NAMESPACE_STD
#else
namespace std {
#ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
#endif

using ::div;
[[clang::sycl_device_only, clang::always_inline]] ldiv_t div(long x, long y) { return {x / y, x % y}; }
[[clang::sycl_device_only, clang::always_inline]] lldiv_t div(long long x, long long y) { return {x / y, x % y}; }
using ::ldiv;
using ::lldiv;

using ::abs;
[[clang::sycl_device_only, clang::always_inline]] long abs(long n) { return n < 0 ? -n : n; }
[[clang::sycl_device_only, clang::always_inline]] long long abs(long long n) { return n < 0 ? -n : n; }
using ::labs;
using ::llabs;

#ifdef _LIBCPP_END_NAMESPACE_STD
_LIBCPP_END_NAMESPACE_STD
#else
#ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
#endif
} // namespace std
#endif
#endif // __SYCL_DEVICE_ONLY__
1 change: 1 addition & 0 deletions sycl/test-e2e/DeviceLib/cmath_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "math_utils.hpp"
#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <std/experimental/simd.hpp>
#include <sycl/detail/core.hpp>
Expand Down
28 changes: 28 additions & 0 deletions sycl/test/check_device_code/math-builtins/cstdlib.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// RUN: %clangxx -fsycl -fsyntax-only %s

#include <type_traits>

#include <cstdlib>

int i = 1;
long l = 1;
long long ll = 1;

// Unqualified calls should resolve to the `int` overloads
static_assert(std::is_same_v<decltype(abs(i)), int>);
static_assert(std::is_same_v<decltype(div(i, i)), div_t>);
// NOTE: Windows Universal C Runtime defines C++ overloads for `long` and
// `long long` types in global name space. See
// https://github.com/huangqinjin/ucrt/blob/d6e817a4cc90f6f1fe54f8a0aa4af4fff0bb647d/include/stdlib.h#L360-L383.
#ifndef _WIN32
static_assert(std::is_same_v<decltype(abs(l)), int>);
static_assert(std::is_same_v<decltype(abs(ll)), int>);
static_assert(std::is_same_v<decltype(div(i, l)), div_t>);
static_assert(std::is_same_v<decltype(div(i, ll)), div_t>);
static_assert(std::is_same_v<decltype(div(l, i)), div_t>);
static_assert(std::is_same_v<decltype(div(l, l)), div_t>);
static_assert(std::is_same_v<decltype(div(l, ll)), div_t>);
static_assert(std::is_same_v<decltype(div(ll, i)), div_t>);
static_assert(std::is_same_v<decltype(div(ll, l)), div_t>);
static_assert(std::is_same_v<decltype(div(ll, ll)), div_t>);
#endif // _WIN32
1 change: 1 addition & 0 deletions sycl/test/include_deps/sycl_accessor.hpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// CHECK-NEXT: detail/defines_elementary.hpp
// CHECK-NEXT: buffer.hpp
// CHECK-NEXT: backend_types.hpp
// CHECK-NEXT: stl_wrappers/cstdlib
// CHECK-NEXT: detail/array.hpp
// CHECK-NEXT: exception.hpp
// CHECK-NEXT: detail/export.hpp
Expand Down
1 change: 1 addition & 0 deletions sycl/test/include_deps/sycl_buffer.hpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// CHECK-NEXT: access/access.hpp
// CHECK-NEXT: detail/defines_elementary.hpp
// CHECK-NEXT: backend_types.hpp
// CHECK-NEXT: stl_wrappers/cstdlib
// CHECK-NEXT: detail/array.hpp
// CHECK-NEXT: exception.hpp
// CHECK-NEXT: detail/export.hpp
Expand Down
1 change: 1 addition & 0 deletions sycl/test/include_deps/sycl_detail_core.hpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
// CHECK-NEXT: detail/defines_elementary.hpp
// CHECK-NEXT: buffer.hpp
// CHECK-NEXT: backend_types.hpp
// CHECK-NEXT: stl_wrappers/cstdlib
// CHECK-NEXT: detail/array.hpp
// CHECK-NEXT: exception.hpp
// CHECK-NEXT: detail/export.hpp
Expand Down
4 changes: 0 additions & 4 deletions sycl/test/self-contained-headers/lit.local.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,4 @@ 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"
),
]
Loading