DPC++ Runtime
Runtime libraries for oneAPI DPC++
relational_functions.cpp
Go to the documentation of this file.
1 //==------------------- relational_functions.cpp ---------------------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "host_helper_macros.hpp"
12 
13 #include <bitset>
14 #include <cmath>
15 
16 namespace sycl {
17 inline namespace _V1 {
18 
19 template <typename T> static auto process_arg_for_macos(T x) {
20  // Workaround for MacOS that doesn't provide some std::is* functions as
21  // overloads over FP types (e.g., isfinite)
22  if constexpr (std::is_same_v<T, half>)
23  return static_cast<float>(x);
24  else
25  return x;
26 }
27 
28 #if defined(__GNUC__) && !defined(__clang__)
29 // sycl::vec has UB in operator[] (aliasing violation) that causes the following
30 // warning here. Note that the way this #pragma works is that we have to put it
31 // around the macro definition, not where the macro is instantiated.
32 #pragma GCC diagnostic push
33 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
34 #endif
35 
36 #define REL_BUILTIN_CUSTOM(NUM_ARGS, NAME, ...) \
37  template <typename... Ts> static auto NAME##_host_impl(Ts... xs) { \
38  using namespace detail; \
39  if constexpr ((... || is_vec_v<Ts>)) { \
40  return builtin_delegate_rel_impl( \
41  [](auto... xs) { return NAME##_host_impl(xs...); }, xs...); \
42  } else { \
43  return __VA_ARGS__(xs...); \
44  } \
45  } \
46  EXPORT_SCALAR_AND_VEC_1_16(NUM_ARGS, NAME, FP_TYPES)
47 #define REL_BUILTIN(NUM_ARGS, NAME) \
48  REL_BUILTIN_CUSTOM(NUM_ARGS, NAME, [](auto... xs) { \
49  return std::NAME(process_arg_for_macos(xs)...); \
50  })
51 
52 #if defined(__GNUC__) && !defined(__clang__)
53 #pragma GCC diagnostic pop
54 #endif
55 
56 REL_BUILTIN_CUSTOM(TWO_ARGS, isequal, ([](auto x, auto y) { return x == y; }))
58  ([](auto x, auto y) { return x != y; }))
59 REL_BUILTIN_CUSTOM(TWO_ARGS, isgreater, ([](auto x, auto y) { return x > y; }))
61  ([](auto x, auto y) { return x >= y; }))
62 REL_BUILTIN_CUSTOM(TWO_ARGS, isless, ([](auto x, auto y) { return x < y; }))
64  ([](auto x, auto y) { return x <= y; }))
65 REL_BUILTIN_CUSTOM(TWO_ARGS, islessgreater,
66  ([](auto x, auto y) { return x < y || x > y; }))
67 REL_BUILTIN(ONE_ARG, isfinite)
68 REL_BUILTIN(ONE_ARG, isinf)
69 REL_BUILTIN(ONE_ARG, isnan)
70 REL_BUILTIN(ONE_ARG, isnormal)
71 REL_BUILTIN(TWO_ARGS, isunordered)
73  ([](auto x, auto y) { return !sycl::isunordered(x, y); }))
74 
75 #define _SYCL_BUILTINS_GCC_VER \
76  (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
77 
78 #if defined(__GNUC__) && !defined(__clang__) && \
79  ((_SYCL_BUILTINS_GCC_VER >= 100000 && _SYCL_BUILTINS_GCC_VER < 110000) || \
80  (_SYCL_BUILTINS_GCC_VER >= 110000 && _SYCL_BUILTINS_GCC_VER < 110500) || \
81  (_SYCL_BUILTINS_GCC_VER >= 120000 && _SYCL_BUILTINS_GCC_VER < 120400) || \
82  (_SYCL_BUILTINS_GCC_VER >= 130000 && _SYCL_BUILTINS_GCC_VER < 130300))
83 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112816
84 // The reproducers in that ticket only affect GCCs 10 to 13. Release
85 // branches 11.5, 12.4, and 13.3 have been updated with the fix; release branch
86 // 10 hasn't, so all GCCs 10.x are considered affected.
87 #define GCC_PR112816_DISABLE_OPT \
88  _Pragma("GCC push_options") _Pragma("GCC optimize(\"-O1\")")
89 #define GCC_PR112816_RESTORE_OPT _Pragma("GCC pop_options")
90 #else
91 #define GCC_PR112816_DISABLE_OPT
92 #define GCC_PR112816_RESTORE_OPT
93 #endif
94 
96 
97 REL_BUILTIN(ONE_ARG, signbit)
98 
100 
101 #undef GCC_PR112816_RESTORE_OPT
102 #undef GCC_PR112816_DISABLE_OPT
103 #undef _SYCL_BUILTINS_GCC_VER
104 
105 HOST_IMPL(bitselect, [](auto x, auto y, auto z) {
106  using T0 = decltype(x);
107  using T1 = decltype(y);
108  using T2 = decltype(z);
109  constexpr size_t N = sizeof(T0) * 8;
110  using bitset = std::bitset<N>;
111 
112  static_assert(std::is_same_v<T0, T1> && std::is_same_v<T1, T2> &&
113  detail::is_scalar_arithmetic_v<T0>);
114 
115  using utype = detail::make_type_t<
116  T0, detail::type_list<unsigned char, unsigned short, unsigned int,
117  unsigned long, unsigned long long>>;
118  static_assert(sizeof(utype) == sizeof(T0));
119  bitset bx(bit_cast<utype>(x)), by(bit_cast<utype>(y)), bz(bit_cast<utype>(z));
120  bitset res = (bz & by) | (~bz & bx);
121  unsigned long long ures = res.to_ullong();
122  assert((ures & std::numeric_limits<utype>::max()) == ures);
123  return bit_cast<T0>(static_cast<utype>(ures));
124 })
125 FOR_EACH2(EXPORT_SCALAR, THREE_ARGS, bitselect, INTEGER_TYPES, FP_TYPES)
126 EXPORT_VEC_1_16(THREE_ARGS, bitselect, FIXED_WIDTH_INTEGER_TYPES, FP_TYPES)
127 } // namespace _V1
128 } // namespace sycl
#define FIXED_WIDTH_INTEGER_TYPES
#define INTEGER_TYPES
#define FP_TYPES
#define FOR_EACH2(BASE_CASE, FIXED1, FIXED2,...)
#define EXPORT_SCALAR(NUM_ARGS, NAME, TYPE)
#define HOST_IMPL(NAME,...)
#define EXPORT_VEC_1_16(NUM_ARGS, NAME,...)
boost::mp11::mp_list< T... > type_list
Definition: type_list.hpp:22
typename make_type_impl< T, TL >::type make_type_t
std::enable_if_t< std::is_same_v< T, bfloat16 >, bool > isnan(T x)
auto auto autodecltype(x) z
static auto process_arg_for_macos(T x)
autodecltype(x) x
REL_BUILTIN_CUSTOM(TWO_ARGS, isequal,([](auto x, auto y) { return x==y;})) REL_BUILTIN_CUSTOM(TWO_ARGS
Definition: access.hpp:18
#define REL_BUILTIN(NUM_ARGS, NAME)
#define GCC_PR112816_RESTORE_OPT
#define GCC_PR112816_DISABLE_OPT