Skip to content

Commit fd2aa65

Browse files
[SYCL] Fix return type of relational functions on scalars (#5975)
This fix updates scalar versions of relation functions that now return "bool" instead of a signed integer in SYCL 2020 mode. The fix is ABI-breaking and is put under SYCL2020_CONFORMANT_APIS guard.
1 parent b1b4e68 commit fd2aa65

File tree

4 files changed

+396
-80
lines changed

4 files changed

+396
-80
lines changed

sycl/include/CL/sycl/builtins.hpp

Lines changed: 19 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,198 +1109,138 @@ fast_normalize(T p) __NOEXC {
11091109
return __sycl_std::__invoke_fast_normalize<T>(p);
11101110
}
11111111

1112-
/* --------------- 4.13.7 Relational functions. Device version --------------*/
1113-
// int isequal (half x, half y)
1114-
// shortn isequal (halfn x, halfn y)
1115-
// igeninteger32bit isequal (genfloatf x, genfloatf y)
1116-
// int isequal (double x,double y);
1117-
// longn isequal (doublen x, doublen y)
1112+
/* SYCL 1.2.1 ---- 4.13.7 Relational functions. -----------------------------*/
1113+
/* SYCL 2020 ---- 4.17.9 Relational functions. -----------------------------*/
1114+
11181115
template <typename T,
11191116
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
11201117
detail::common_rel_ret_t<T> isequal(T x, T y) __NOEXC {
11211118
return detail::RelConverter<T>::apply(
11221119
__sycl_std::__invoke_FOrdEqual<detail::rel_ret_t<T>>(x, y));
11231120
}
11241121

1125-
// int isnotequal (half x, half y)
1126-
// shortn isnotequal (halfn x, halfn y)
1127-
// igeninteger32bit isnotequal (genfloatf x, genfloatf y)
1128-
// int isnotequal (double x, double y)
1129-
// longn isnotequal (doublen x, doublen y)
11301122
template <typename T,
11311123
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
11321124
detail::common_rel_ret_t<T> isnotequal(T x, T y) __NOEXC {
11331125
return detail::RelConverter<T>::apply(
11341126
__sycl_std::__invoke_FUnordNotEqual<detail::rel_ret_t<T>>(x, y));
11351127
}
11361128

1137-
// int isgreater (half x, half y)
1138-
// shortn isgreater (halfn x, halfn y)
1139-
// igeninteger32bit isgreater (genfloatf x, genfloatf y)
1140-
// int isgreater (double x, double y)
1141-
// longn isgreater (doublen x, doublen y)
11421129
template <typename T,
11431130
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
11441131
detail::common_rel_ret_t<T> isgreater(T x, T y) __NOEXC {
11451132
return detail::RelConverter<T>::apply(
11461133
__sycl_std::__invoke_FOrdGreaterThan<detail::rel_ret_t<T>>(x, y));
11471134
}
11481135

1149-
// int isgreaterequal (half x, half y)
1150-
// shortn isgreaterequal (halfn x, halfn y)
1151-
// igeninteger32bit isgreaterequal (genfloatf x, genfloatf y)
1152-
// int isgreaterequal (double x, double y)
1153-
// longn isgreaterequal (doublen x, doublen y)
11541136
template <typename T,
11551137
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
11561138
detail::common_rel_ret_t<T> isgreaterequal(T x, T y) __NOEXC {
11571139
return detail::RelConverter<T>::apply(
11581140
__sycl_std::__invoke_FOrdGreaterThanEqual<detail::rel_ret_t<T>>(x, y));
11591141
}
11601142

1161-
// int isless (half x, half y)
1162-
// shortn isless (halfn x, halfn y)
1163-
// igeninteger32bit isless (genfloatf x, genfloatf y)
1164-
// int isless (long x, long y)
1165-
// longn isless (doublen x, doublen y)
11661143
template <typename T,
11671144
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
11681145
detail::common_rel_ret_t<T> isless(T x, T y) __NOEXC {
11691146
return detail::RelConverter<T>::apply(
11701147
__sycl_std::__invoke_FOrdLessThan<detail::rel_ret_t<T>>(x, y));
11711148
}
11721149

1173-
// int islessequal (half x, half y)
1174-
// shortn islessequal (halfn x, halfn y)
1175-
// igeninteger32bit islessequal (genfloatf x, genfloatf y)
1176-
// int islessequal (double x, double y)
1177-
// longn islessequal (doublen x, doublen y)
11781150
template <typename T,
11791151
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
11801152
detail::common_rel_ret_t<T> islessequal(T x, T y) __NOEXC {
11811153
return detail::RelConverter<T>::apply(
11821154
__sycl_std::__invoke_FOrdLessThanEqual<detail::rel_ret_t<T>>(x, y));
11831155
}
11841156

1185-
// int islessgreater (half x, half y)
1186-
// shortn islessgreater (halfn x, halfn y)
1187-
// igeninteger32bit islessgreater (genfloatf x, genfloatf y)
1188-
// int islessgreater (double x, double y)
1189-
// longn islessgreater (doublen x, doublen y)
11901157
template <typename T,
11911158
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
11921159
detail::common_rel_ret_t<T> islessgreater(T x, T y) __NOEXC {
11931160
return detail::RelConverter<T>::apply(
11941161
__sycl_std::__invoke_FOrdNotEqual<detail::rel_ret_t<T>>(x, y));
11951162
}
11961163

1197-
// int isfinite (half x)
1198-
// shortn isfinite (halfn x)
1199-
// igeninteger32bit isfinite (genfloatf x)
1200-
// int isfinite (double x)
1201-
// longn isfinite (doublen x)
12021164
template <typename T,
12031165
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
12041166
detail::common_rel_ret_t<T> isfinite(T x) __NOEXC {
12051167
return detail::RelConverter<T>::apply(
12061168
__sycl_std::__invoke_IsFinite<detail::rel_ret_t<T>>(x));
12071169
}
12081170

1209-
// int isinf (half x)
1210-
// shortn isinf (halfn x)
1211-
// igeninteger32bit isinf (genfloatf x)
1212-
// int isinf (double x)
1213-
// longn isinf (doublen x)
12141171
template <typename T,
12151172
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
12161173
detail::common_rel_ret_t<T> isinf(T x) __NOEXC {
12171174
return detail::RelConverter<T>::apply(
12181175
__sycl_std::__invoke_IsInf<detail::rel_ret_t<T>>(x));
12191176
}
12201177

1221-
// int isnan (half x)
1222-
// shortn isnan (halfn x)
1223-
// igeninteger32bit isnan (genfloatf x)
1224-
// int isnan (double x)
1225-
// longn isnan (doublen x)
12261178
template <typename T,
12271179
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
12281180
detail::common_rel_ret_t<T> isnan(T x) __NOEXC {
12291181
return detail::RelConverter<T>::apply(
12301182
__sycl_std::__invoke_IsNan<detail::rel_ret_t<T>>(x));
12311183
}
12321184

1233-
// int isnormal (half x)
1234-
// shortn isnormal (halfn x)
1235-
// igeninteger32bit isnormal (genfloatf x)
1236-
// int isnormal (double x)
1237-
// longn isnormal (doublen x)
12381185
template <typename T,
12391186
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
12401187
detail::common_rel_ret_t<T> isnormal(T x) __NOEXC {
12411188
return detail::RelConverter<T>::apply(
12421189
__sycl_std::__invoke_IsNormal<detail::rel_ret_t<T>>(x));
12431190
}
12441191

1245-
// int isordered (half x)
1246-
// shortn isordered (halfn x, halfn y)
1247-
// igeninteger32bit isordered (genfloatf x, genfloatf y)
1248-
// int isordered (double x, double y)
1249-
// longn isordered (doublen x, doublen y)
12501192
template <typename T,
12511193
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
12521194
detail::common_rel_ret_t<T> isordered(T x, T y) __NOEXC {
12531195
return detail::RelConverter<T>::apply(
12541196
__sycl_std::__invoke_Ordered<detail::rel_ret_t<T>>(x, y));
12551197
}
12561198

1257-
// int isunordered (half x, half y)
1258-
// shortn isunordered (halfn x, halfn y)
1259-
// igeninteger32bit isunordered (genfloatf x, genfloatf y)
1260-
// int isunordered (double x, double y)
1261-
// longn isunordered (doublen x, doublen y)
12621199
template <typename T,
12631200
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
12641201
detail::common_rel_ret_t<T> isunordered(T x, T y) __NOEXC {
12651202
return detail::RelConverter<T>::apply(
12661203
__sycl_std::__invoke_Unordered<detail::rel_ret_t<T>>(x, y));
12671204
}
12681205

1269-
// int signbit (half x)
1270-
// shortn signbit (halfn x)
1271-
// igeninteger32bit signbit (genfloatf x)
1272-
// int signbit (double)
1273-
// longn signbit (doublen x)
12741206
template <typename T,
12751207
typename = detail::enable_if_t<detail::is_genfloat<T>::value, T>>
12761208
detail::common_rel_ret_t<T> signbit(T x) __NOEXC {
12771209
return detail::RelConverter<T>::apply(
12781210
__sycl_std::__invoke_SignBitSet<detail::rel_ret_t<T>>(x));
12791211
}
12801212

1281-
// int any (sigeninteger x)
1213+
namespace detail {
1214+
#if defined(SYCL2020_CONFORMANT_APIS) && SYCL_LANGUAGE_VERSION >= 202001
1215+
using anyall_ret_t = bool;
1216+
#else
1217+
using anyall_ret_t = int;
1218+
#endif
1219+
} // namespace detail
1220+
12821221
template <typename T>
1283-
detail::enable_if_t<detail::is_sigeninteger<T>::value, int> any(T x) __NOEXC {
1222+
detail::enable_if_t<detail::is_sigeninteger<T>::value, detail::anyall_ret_t>
1223+
any(T x) __NOEXC {
12841224
return detail::Boolean<1>(int(detail::msbIsSet(x)));
12851225
}
12861226

1287-
// int any (vigeninteger x)
12881227
template <typename T>
1289-
detail::enable_if_t<detail::is_vigeninteger<T>::value, int> any(T x) __NOEXC {
1228+
detail::enable_if_t<detail::is_vigeninteger<T>::value, detail::anyall_ret_t>
1229+
any(T x) __NOEXC {
12901230
return detail::rel_sign_bit_test_ret_t<T>(
12911231
__sycl_std::__invoke_Any<detail::rel_sign_bit_test_ret_t<T>>(
12921232
detail::rel_sign_bit_test_arg_t<T>(x)));
12931233
}
12941234

1295-
// int all (sigeninteger x)
12961235
template <typename T>
1297-
detail::enable_if_t<detail::is_sigeninteger<T>::value, int> all(T x) __NOEXC {
1236+
detail::enable_if_t<detail::is_sigeninteger<T>::value, detail::anyall_ret_t>
1237+
all(T x) __NOEXC {
12981238
return detail::Boolean<1>(int(detail::msbIsSet(x)));
12991239
}
13001240

1301-
// int all (vigeninteger x)
13021241
template <typename T>
1303-
detail::enable_if_t<detail::is_vigeninteger<T>::value, int> all(T x) __NOEXC {
1242+
detail::enable_if_t<detail::is_vigeninteger<T>::value, detail::anyall_ret_t>
1243+
all(T x) __NOEXC {
13041244
return detail::rel_sign_bit_test_ret_t<T>(
13051245
__sycl_std::__invoke_All<detail::rel_sign_bit_test_ret_t<T>>(
13061246
detail::rel_sign_bit_test_arg_t<T>(x)));

sycl/include/CL/sycl/detail/boolean.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ template <> struct Boolean<1> {
110110

111111
// Cast to a signed interger type
112112
template <typename T> operator T() const {
113-
static_assert(is_sgeninteger<T>::value, "Invalid conversion");
113+
static_assert(std::is_same<T, bool>::value || is_sgeninteger<T>::value,
114+
"Invalid conversion");
114115
return value;
115116
}
116117

sycl/include/CL/sycl/detail/generic_type_traits.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,31 @@ template <typename T> inline constexpr bool msbIsSet(const T x) {
501501
return (x & msbMask(x));
502502
}
503503

504+
#if defined(SYCL2020_CONFORMANT_APIS) && SYCL_LANGUAGE_VERSION >= 202001
505+
// SYCL 2020 4.17.9 (Relation functions), e.g. table 178
506+
//
507+
// genbool isequal (genfloatf x, genfloatf y)
508+
// genbool isequal (genfloatd x, genfloatd y)
509+
//
510+
// TODO: marray support isn't implemented yet.
511+
template <typename T>
512+
using common_rel_ret_t =
513+
conditional_t<is_vgentype<T>::value, make_singed_integer_t<T>, bool>;
514+
#else
515+
// SYCL 1.2.1 4.13.7 (Relation functions), e.g.
516+
//
517+
// igeninteger32bit isequal (genfloatf x, genfloatf y)
518+
// igeninteger64bit isequal (genfloatd x, genfloatd y)
519+
//
520+
// However, we have pre-existing bug so
521+
//
522+
// igeninteger32bit isequal (genfloatd x, genfloatd y)
523+
//
524+
// Fixing it would be an ABI-breaking change so isn't done.
504525
template <typename T>
505526
using common_rel_ret_t =
506527
conditional_t<is_vgentype<T>::value, make_singed_integer_t<T>, int>;
528+
#endif
507529

508530
// forward declaration
509531
template <int N> struct Boolean;

0 commit comments

Comments
 (0)