Skip to content

Commit 6493e6b

Browse files
authored
[ESIMD] Enable unary operations on constant simd objects. (#4703)
Signed-off-by: Konstantin S Bobrovsky <[email protected]>
1 parent 0bbb091 commit 6493e6b

File tree

3 files changed

+96
-3
lines changed

3 files changed

+96
-3
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,13 +531,15 @@ template <typename Ty, int N, class Derived, class SFINAE> class simd_obj_impl {
531531

532532
/// Bitwise inversion, available in all subclasses.
533533
template <class T1 = Ty, class = std::enable_if_t<std::is_integral_v<T1>>>
534-
Derived operator~() {
534+
Derived operator~() const {
535535
return Derived(~data());
536536
}
537537

538538
/// Unary logical negation operator, available in all subclasses.
539+
/// Similarly to C++, where !x returns bool, !simd returns as simd_mask, where
540+
/// each element is a result of comparision with zero.
539541
template <class T1 = Ty, class = std::enable_if_t<std::is_integral_v<T1>>>
540-
simd_mask_type<N> operator!() {
542+
simd_mask_type<N> operator!() const {
541543
using MaskVecT = typename simd_mask_type<N>::vector_type;
542544
auto R = data() == vector_type(0);
543545
return simd_mask_type<N>{__builtin_convertvector(R, MaskVecT) &

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class simd
102102
/// @}
103103

104104
#define __ESIMD_DEF_SIMD_ARITH_UNARY_OP(ARITH_UNARY_OP) \
105-
template <class T1 = Ty> simd operator ARITH_UNARY_OP() { \
105+
template <class T1 = Ty> simd operator ARITH_UNARY_OP() const { \
106106
static_assert(!std::is_unsigned_v<T1>, \
107107
#ARITH_UNARY_OP "doesn't apply to unsigned types"); \
108108
return simd(ARITH_UNARY_OP(base_type::data())); \
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// RUN: %clangxx -fsycl -fsyntax-only -Xclang -verify %s
2+
// expected-no-diagnostics
3+
4+
// This test checks that compiler can apply unary operators to constant simd,
5+
// simd_mask and simd_view objects, as well as to non-constant ones.
6+
7+
#include <CL/sycl.hpp>
8+
#include <sycl/ext/intel/experimental/esimd.hpp>
9+
#include <type_traits>
10+
11+
using namespace sycl::ext::intel::experimental::esimd;
12+
13+
template <class T, int N> struct S {
14+
S() : val(T(0)) {}
15+
const simd<T, N> val;
16+
};
17+
18+
template <int N> struct Smask {
19+
Smask() : val(0) {}
20+
const simd_mask<N> val;
21+
};
22+
23+
template <class T, int N>
24+
SYCL_ESIMD_FUNCTION auto test_simd_unary_plus_minus(const simd<T, N> &x,
25+
const S<T, N> &y) {
26+
auto z0 = -x; // negate constant simd parameter
27+
auto z1 = -y.val; // negate field of a constant simd parameter
28+
const auto x0 = x;
29+
auto z2 = +x0; // unary '+' on constant local simd object
30+
return z0 + z1 + z2;
31+
}
32+
33+
template <class T, int N>
34+
SYCL_ESIMD_FUNCTION auto test_simd_unary_ops(const simd<T, N> &x,
35+
const S<T, N> &y) {
36+
auto z0 = !x; // logically negate constant simd parameter
37+
auto z1 = !y.val; // logically negate field of a constant simd parameter
38+
const auto x0 = x;
39+
auto z2 = !x0; // logically negate constant local simd object
40+
41+
auto z3 = ~x; // bitwise invert constant simd parameter
42+
auto z4 = ~y.val; // bitwise invert field of a constant simd parameter
43+
const auto x1 = x;
44+
auto z5 = ~x1; // bitwise invert constant local simd object
45+
46+
return (z0 | z1 | z2) | ((z3 | z4 | z5) == 0);
47+
}
48+
49+
template <int N>
50+
SYCL_ESIMD_FUNCTION auto test_simd_mask_unary_ops(const simd_mask<N> &x,
51+
const Smask<N> &y) {
52+
auto z0 = !x; // logically negate constant simd_mask parameter
53+
auto z1 = !y.val; // logically negate field of a constant simd_mask parameter
54+
const auto x0 = x;
55+
auto z2 = !x0; // logically negate constant local simd_mask object
56+
57+
auto z3 = ~x; // bitwise invert constant simd_mask parameter
58+
auto z4 = ~y.val; // bitwise invert field of a constant simd_mask parameter
59+
const auto x1 = x;
60+
auto z5 = ~x1; // bitwise invert constant local simd_mask object
61+
62+
return (z0 | z1 | z2) | ((z3 | z4 | z5) == 0);
63+
}
64+
65+
void foo() {
66+
{
67+
simd<float, 32> x;
68+
S<float, 32> y;
69+
test_simd_unary_plus_minus(x, y);
70+
}
71+
{
72+
simd<char, 8> x;
73+
S<char, 8> y;
74+
test_simd_unary_plus_minus(x, y);
75+
}
76+
{
77+
simd<char, 8> x;
78+
S<char, 8> y;
79+
test_simd_unary_ops(x, y);
80+
}
81+
{
82+
simd<unsigned int, 32> x;
83+
S<unsigned int, 32> y;
84+
test_simd_unary_ops(x, y);
85+
}
86+
{
87+
simd_mask<32> x;
88+
Smask<32> y;
89+
test_simd_mask_unary_ops(x, y);
90+
}
91+
}

0 commit comments

Comments
 (0)