Skip to content

Commit fee1989

Browse files
authored
[SYCL][ESIMD] Fix bit operation compilation errors, add test. (#3847)
* [SYCL][ESIMD] Fix bit operation compilation errors, add test. E2E test will be added to llvm-test-suite. Signed-off-by: kbobrovs <[email protected]>
1 parent 525d253 commit fee1989

File tree

3 files changed

+115
-35
lines changed

3 files changed

+115
-35
lines changed

sycl/include/sycl/ext/intel/experimental/esimd/detail/math_intrin.hpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ __esimd_bfext(__SEIEED::vector_type_t<T0, SZ> src0,
158158
__SEIEED::vector_type_t<T0, SZ> src1,
159159
__SEIEED::vector_type_t<T0, SZ> src2);
160160

161-
template <int SZ>
162-
SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SEIEED::vector_type_t<uint32_t, SZ>
163-
__esimd_fbl(__SEIEED::vector_type_t<uint32_t, SZ> src0);
161+
template <typename T0, int SZ>
162+
SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SEIEED::vector_type_t<T0, SZ>
163+
__esimd_fbl(__SEIEED::vector_type_t<T0, SZ> src0);
164164

165165
template <typename T0, int SZ>
166166
SYCL_EXTERNAL SYCL_ESIMD_FUNCTION __SEIEED::vector_type_t<int, SZ>
@@ -833,12 +833,12 @@ __esimd_bfext(__SEIEED::vector_type_t<T0, SZ> width,
833833
return retv;
834834
};
835835

836-
template <int SZ>
837-
inline __SEIEED::vector_type_t<uint32_t, SZ>
838-
__esimd_fbl(__SEIEED::vector_type_t<uint32_t, SZ> src0) {
836+
template <typename T0, int SZ>
837+
inline __SEIEED::vector_type_t<T0, SZ>
838+
__esimd_fbl(__SEIEED::vector_type_t<T0, SZ> src0) {
839839
int i;
840-
uint32_t ret;
841-
__SEIEED::vector_type_t<uint32_t, SZ> retv;
840+
T0 ret;
841+
__SEIEED::vector_type_t<T0, SZ> retv;
842842

843843
for (i = 0; i < SZ; i++) {
844844
SIMDCF_ELEMENT_SKIP(i);

sycl/include/sycl/ext/intel/experimental/esimd/math.hpp

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,60 +1270,106 @@ ESIMD_NODEBUG ESIMD_INLINE
12701270
return esimd_pack_mask(src_0);
12711271
}
12721272

1273-
/// Count component-wise the total bits set in source operand.
1273+
/// Count number of bits set in the source operand per element.
1274+
/// @param src0 the source operand to count bits in.
1275+
/// @return a vector of \c uint32_t, where each element is set to bit count of
1276+
/// the corresponding element of the source operand.
12741277
template <typename T, int N>
1275-
ESIMD_NODEBUG ESIMD_INLINE
1276-
typename sycl::detail::enable_if_t<std::is_integral<T>::value,
1277-
simd<uint, N>>
1278-
esimd_cbit(simd<T, N> src0) {
1279-
return __esimd_cbit<T, N>(src0.data());
1278+
ESIMD_NODEBUG ESIMD_INLINE typename sycl::detail::enable_if_t<
1279+
std::is_integral<T>::value && sizeof(T) <= 4, simd<uint32_t, N>>
1280+
esimd_cbit(simd<T, N> src) {
1281+
return __esimd_cbit<T, N>(src.data());
12801282
}
12811283

1284+
/// Scalar version of \c esimd_cbit - both input and output are scalars rather
1285+
/// than vectors.
12821286
template <typename T>
12831287
ESIMD_NODEBUG ESIMD_INLINE typename sycl::detail::enable_if_t<
1284-
std::is_integral<T>::value && detail::is_esimd_scalar<T>::value, uint>
1288+
std::is_integral<T>::value && sizeof(T) <= 4, uint32_t>
12851289
esimd_cbit(T src) {
12861290
simd<T, 1> Src = src;
1287-
simd<uint, 1> Result = esimd_cbit(Src);
1291+
simd<uint32_t, 1> Result = esimd_cbit(Src);
12881292
return Result[0];
12891293
}
12901294

1295+
/// Find the per element number of the first bit set in the source operand
1296+
/// starting from the least significant bit.
1297+
/// @param src0 the source operand to count bits in.
1298+
/// @return a vector of the same type as the source operand, where each element
1299+
/// is set to the number first bit set in corresponding element of the
1300+
/// source operand. \c 0xFFFFffff is returned for an element equal to \c 0.
12911301
/// Find component-wise the first bit from LSB side
1292-
template <int N>
1293-
ESIMD_NODEBUG ESIMD_INLINE simd<unsigned, N> esimd_fbl(simd<unsigned, N> src) {
1294-
return __esimd_fbl(src.data());
1302+
template <typename T, int N>
1303+
ESIMD_NODEBUG ESIMD_INLINE typename sycl::detail::enable_if_t<
1304+
std::is_integral<T>::value && (sizeof(T) == 4), simd<T, N>>
1305+
esimd_fbl(simd<T, N> src) {
1306+
return __esimd_fbl<T, N>(src.data());
12951307
}
12961308

1297-
template <typename T = void>
1298-
ESIMD_NODEBUG ESIMD_INLINE unsigned esimd_fbl(unsigned src) {
1299-
simd<unsigned, 1> Src = src;
1300-
simd<unsigned, 1> Result = esimd_fbl(Src);
1309+
/// Scalar version of \c esimd_fbl - both input and output are scalars rather
1310+
/// than vectors.
1311+
template <typename T>
1312+
ESIMD_NODEBUG ESIMD_INLINE typename sycl::detail::enable_if_t<
1313+
std::is_integral<T>::value && (sizeof(T) == 4), T>
1314+
esimd_fbl(T src) {
1315+
simd<T, 1> Src = src;
1316+
simd<T, 1> Result = esimd_fbl(Src);
13011317
return Result[0];
13021318
}
13031319

1304-
/// Find component-wise the first bit from MSB side.
1305-
template <int N>
1306-
ESIMD_NODEBUG ESIMD_INLINE simd<int, N> esimd_fbh(simd<int, N> src) {
1307-
return __esimd_sfbh(src.data());
1320+
/// Find the per element number of the first bit set in the source operand
1321+
/// starting from the most significant bit (sign bit is skipped).
1322+
/// @param src0 the source operand to count bits in.
1323+
/// @return a vector of the same type as the source operand, where each element
1324+
/// is set to the number first bit set in corresponding element of the
1325+
/// source operand. \c 0xFFFFffff is returned for an element equal to \c 0
1326+
/// or \c -1.
1327+
template <typename T, int N>
1328+
ESIMD_NODEBUG ESIMD_INLINE typename sycl::detail::enable_if_t<
1329+
std::is_integral<T>::value && std::is_signed<T>::value && (sizeof(T) == 4),
1330+
simd<T, N>>
1331+
esimd_fbh(simd<T, N> src) {
1332+
return __esimd_sfbh<T, N>(src.data());
13081333
}
13091334

1310-
template <int N>
1311-
ESIMD_NODEBUG ESIMD_INLINE simd<unsigned int, N>
1312-
esimd_fbh(simd<unsigned int, N> src) {
1313-
return __esimd_ufbh(src.data());
1335+
/// Scalar version of \c esimd_fbh - both input and output are scalars rather
1336+
/// than vectors.
1337+
template <typename T>
1338+
ESIMD_NODEBUG ESIMD_INLINE typename sycl::detail::enable_if_t<
1339+
std::is_integral<T>::value && std::is_signed<T>::value && (sizeof(T) == 4),
1340+
T>
1341+
esimd_fbh(T src) {
1342+
simd<T, 1> Src = src;
1343+
simd<T, 1> Result = esimd_fbh(Src);
1344+
return Result[0];
13141345
}
13151346

1347+
/// Find the per element number of the first bit set in the source operand
1348+
/// starting from the most significant bit (sign bit is counted).
1349+
/// @param src0 the source operand to count bits in.
1350+
/// @return a vector of the same type as the source operand, where each element
1351+
/// is set to the number first bit set in corresponding element of the
1352+
/// source operand. \c 0xFFFFffff is returned for an element equal to \c 0.
1353+
template <typename T, int N>
1354+
ESIMD_NODEBUG ESIMD_INLINE typename sycl::detail::enable_if_t<
1355+
std::is_integral<T>::value && !std::is_signed<T>::value && (sizeof(T) == 4),
1356+
simd<T, N>>
1357+
esimd_fbh(simd<T, N> src) {
1358+
return __esimd_ufbh<T, N>(src.data());
1359+
}
1360+
1361+
/// Scalar unsigned version of \c esimd_fbh - both input and output are unsigned
1362+
/// scalars rather than vectors.
13161363
template <typename T>
13171364
ESIMD_NODEBUG ESIMD_INLINE typename sycl::detail::enable_if_t<
1318-
detail::is_dword_type<T>::value && detail::is_esimd_scalar<T>::value, T>
1365+
std::is_integral<T>::value && !std::is_signed<T>::value && (sizeof(T) == 4),
1366+
T>
13191367
esimd_fbh(T src) {
13201368
simd<T, 1> Src = src;
13211369
simd<T, 1> Result = esimd_fbh(Src);
13221370
return Result[0];
13231371
}
13241372

1325-
template <typename T = void> simd<uint, 4> esimd_rdtsc();
1326-
13271373
/// \brief DP4A.
13281374
///
13291375
/// @param src0 the first source operand of dp4a operation.
@@ -1749,7 +1795,7 @@ ESIMD_INLINE simd<float, N> esimd_tanh_cody_waite_impl(simd<float, N> x) {
17491795
* | x | rational polynomial | 1 - 2/(1 + exp(2*x)) | 1
17501796
*
17511797
* rational polynomial for single precision = x + x * (g * (p[1] * g + p[0]) /
1752-
* (g + q[0]) g = x^2 p0 = 0.82377 28127 E+00 p1 = 0.38310 10665 E-02 q0 =
1798+
* (g + q[0]) g = x^2 p0 = -0.82377 28127 E+00 p1 = -0.38310 10665 E-02 q0 =
17531799
* 0.24713 19654 E+01 q1 = 1.00000 00000 E+00
17541800
*
17551801
*/
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %clangxx -fsycl -fsyntax-only -Xclang -verify %s
2+
// expected-no-diagnostics
3+
4+
// This test checks that esimd_cbit, esimd_fbl and esimd_fbh APIs can be
5+
// compiled by host and device compilers.
6+
7+
#include <sycl/ext/intel/experimental/esimd.hpp>
8+
9+
#include <cstdint>
10+
11+
using namespace sycl::ext::intel::experimental::esimd;
12+
13+
template <typename T, int N> void test_esimd_cbit() SYCL_ESIMD_FUNCTION {
14+
simd<T, N> v;
15+
auto cbit_res = esimd_cbit(v);
16+
auto cbit_scalar_res = esimd_cbit(v[0]);
17+
}
18+
19+
template <typename T, int N> void test_esimd_fbx() SYCL_ESIMD_FUNCTION {
20+
simd<T, N> v;
21+
auto fbl_res = esimd_fbl(v);
22+
auto fbl_scalar_res = esimd_fbl(v[0]);
23+
auto fbh_res = esimd_fbh(v);
24+
auto fbh_scalar_res = esimd_fbh(v[0]);
25+
}
26+
27+
void foo() SYCL_ESIMD_FUNCTION {
28+
test_esimd_cbit<char, 1>();
29+
test_esimd_cbit<int, 8>();
30+
test_esimd_cbit<unsigned short, 32>();
31+
32+
test_esimd_fbx<int, 8>();
33+
test_esimd_fbx<unsigned int, 16>();
34+
}

0 commit comments

Comments
 (0)