@@ -66,6 +66,18 @@ struct IncDec {};
6666
6767template <class T > static constexpr bool not_fp = !is_vgenfloat_v<T>;
6868
69+ #if !__SYCL_USE_LIBSYCL8_VEC_IMPL
70+ // Not using `is_byte_v` to avoid unnecessary dependencies on `half`/`bfloat16`
71+ // headers.
72+ template <class T >
73+ static constexpr bool not_byte =
74+ #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
75+ !std::is_same_v<T, std::byte>;
76+ #else
77+ true ;
78+ #endif
79+ #endif
80+
6981// To provide information about operators availability depending on vec/swizzle
7082// element type.
7183template <typename Op, typename T>
@@ -80,6 +92,7 @@ inline constexpr bool is_op_available_for_type<OpAssign<Op>, T> =
8092 inline constexpr bool is_op_available_for_type<OP, T> = COND;
8193
8294// clang-format off
95+ #if __SYCL_USE_LIBSYCL8_VEC_IMPL
8396__SYCL_OP_AVAILABILITY (std::plus<void > , true )
8497__SYCL_OP_AVAILABILITY(std::minus<void > , true )
8598__SYCL_OP_AVAILABILITY(std::multiplies<void > , true )
@@ -110,6 +123,38 @@ __SYCL_OP_AVAILABILITY(std::bit_not<void> , not_fp<T>)
110123__SYCL_OP_AVAILABILITY(UnaryPlus , true )
111124
112125__SYCL_OP_AVAILABILITY(IncDec , true )
126+ #else
127+ __SYCL_OP_AVAILABILITY (std::plus<void > , not_byte<T>)
128+ __SYCL_OP_AVAILABILITY(std::minus<void > , not_byte<T>)
129+ __SYCL_OP_AVAILABILITY(std::multiplies<void > , not_byte<T>)
130+ __SYCL_OP_AVAILABILITY(std::divides<void > , not_byte<T>)
131+ __SYCL_OP_AVAILABILITY(std::modulus<void > , not_fp<T>)
132+
133+ __SYCL_OP_AVAILABILITY(std::bit_and<void > , not_fp<T>)
134+ __SYCL_OP_AVAILABILITY(std::bit_or<void > , not_fp<T>)
135+ __SYCL_OP_AVAILABILITY(std::bit_xor<void > , not_fp<T>)
136+
137+ __SYCL_OP_AVAILABILITY(std::equal_to<void > , true )
138+ __SYCL_OP_AVAILABILITY(std::not_equal_to<void > , true )
139+ __SYCL_OP_AVAILABILITY(std::less<void > , true )
140+ __SYCL_OP_AVAILABILITY(std::greater<void > , true )
141+ __SYCL_OP_AVAILABILITY(std::less_equal<void > , true )
142+ __SYCL_OP_AVAILABILITY(std::greater_equal<void > , true )
143+
144+ __SYCL_OP_AVAILABILITY(std::logical_and<void > , not_byte<T> && not_fp<T>)
145+ __SYCL_OP_AVAILABILITY(std::logical_or<void > , not_byte<T> && not_fp<T>)
146+
147+ __SYCL_OP_AVAILABILITY(ShiftLeft , not_byte<T> && not_fp<T>)
148+ __SYCL_OP_AVAILABILITY(ShiftRight , not_byte<T> && not_fp<T>)
149+
150+ // Unary
151+ __SYCL_OP_AVAILABILITY(std::negate<void > , not_byte<T>)
152+ __SYCL_OP_AVAILABILITY(std::logical_not<void > , not_byte<T>)
153+ __SYCL_OP_AVAILABILITY(std::bit_not<void > , not_fp<T>)
154+ __SYCL_OP_AVAILABILITY(UnaryPlus , not_byte<T>)
155+
156+ __SYCL_OP_AVAILABILITY(IncDec , not_byte<T>)
157+ #endif
113158// clang-format on
114159
115160#undef __SYCL_OP_AVAILABILITY
@@ -188,6 +233,12 @@ template <typename Self> struct VecOperators {
188233 using element_type = typename from_incomplete<Self>::element_type;
189234 static constexpr int N = from_incomplete<Self>::size();
190235
236+ #if !__SYCL_USE_LIBSYCL8_VEC_IMPL
237+ template <typename T>
238+ static constexpr bool is_compatible_scalar =
239+ std::is_convertible_v<T, typename from_incomplete<Self>::element_type>;
240+ #endif
241+
191242 template <typename Op>
192243 using result_t = std::conditional_t <
193244 is_logical<Op>, vec<fixed_width_signed<sizeof (element_type)>, N>, Self>;
@@ -293,6 +344,7 @@ template <typename Self> struct VecOperators {
293344 struct OpMixin <Op, std::enable_if_t <std::is_same_v<Op, IncDec>>>
294345 : public IncDecImpl<Self> {};
295346
347+ #if __SYCL_USE_LIBSYCL8_VEC_IMPL
296348#define __SYCL_VEC_BINOP_MIXIN (OP, OPERATOR ) \
297349 template <typename Op> \
298350 struct OpMixin <Op, std::enable_if_t <std::is_same_v<Op, OP>>> { \
@@ -341,13 +393,60 @@ template <typename Self> struct VecOperators {
341393 friend auto operator OPERATOR (const Self &v) { return apply<OP>(v); } \
342394 };
343395
396+ #else
397+
398+ #define __SYCL_VEC_BINOP_MIXIN (OP, OPERATOR ) \
399+ template <typename Op> \
400+ struct OpMixin <Op, std::enable_if_t <std::is_same_v<Op, OP>>> { \
401+ friend result_t <OP> operator OPERATOR (const Self & lhs, \
402+ const Self & rhs) { \
403+ return VecOperators::apply<OP>(lhs, rhs); \
404+ } \
405+ template <typename T> \
406+ friend std::enable_if_t <is_compatible_scalar<T>, result_t <OP>> \
407+ operator OPERATOR (const Self & lhs, const T & rhs) { \
408+ return VecOperators::apply<OP>(lhs, Self{static_cast <T>(rhs)}); \
409+ } \
410+ template <typename T> \
411+ friend std::enable_if_t <is_compatible_scalar<T>, result_t <OP>> \
412+ operator OPERATOR (const T & lhs, const Self & rhs) { \
413+ return VecOperators::apply<OP>(Self{static_cast <T>(lhs)}, rhs); \
414+ } \
415+ };
416+
417+ #define __SYCL_VEC_OPASSIGN_MIXIN (OP, OPERATOR ) \
418+ template <typename Op> \
419+ struct OpMixin <Op, std::enable_if_t <std::is_same_v<Op, OpAssign<OP>>>> { \
420+ friend Self &operator OPERATOR (Self & lhs, const Self & rhs) { \
421+ lhs = OP{}(lhs, rhs); \
422+ return lhs; \
423+ } \
424+ template <typename T> \
425+ friend std::enable_if_t <is_compatible_scalar<T>, Self &> \
426+ operator OPERATOR (Self & lhs, const T & rhs) { \
427+ lhs = OP{}(lhs, rhs); \
428+ return lhs; \
429+ } \
430+ };
431+
432+ #define __SYCL_VEC_UOP_MIXIN (OP, OPERATOR ) \
433+ template <typename Op> \
434+ struct OpMixin <Op, std::enable_if_t <std::is_same_v<Op, OP>>> { \
435+ friend result_t <OP> operator OPERATOR (const Self & v) { \
436+ return apply<OP>(v); \
437+ } \
438+ };
439+
440+ #endif
441+
344442 __SYCL_INSTANTIATE_OPERATORS (__SYCL_VEC_BINOP_MIXIN,
345443 __SYCL_VEC_OPASSIGN_MIXIN, __SYCL_VEC_UOP_MIXIN)
346444
347445#undef __SYCL_VEC_UOP_MIXIN
348446#undef __SYCL_VEC_OPASSIGN_MIXIN
349447#undef __SYCL_VEC_BINOP_MIXIN
350448
449+ #if __SYCL_USE_LIBSYCL8_VEC_IMPL
351450 template <typename Op>
352451 struct OpMixin <Op, std::enable_if_t <std::is_same_v<Op, std::bit_not<void >>>> {
353452 template <typename T = typename from_incomplete<Self>::element_type>
@@ -356,6 +455,7 @@ template <typename Self> struct VecOperators {
356455 return apply<std::bit_not<void >>(v);
357456 }
358457 };
458+ #endif
359459
360460 template <typename ... Op>
361461 struct __SYCL_EBO CombineImpl : public OpMixin<Op>... {};
@@ -377,6 +477,7 @@ template <typename Self> struct VecOperators {
377477 OpAssign<ShiftRight>, IncDec> {};
378478};
379479
480+ #if __SYCL_USE_LIBSYCL8_VEC_IMPL
380481template <typename DataT, int NumElements>
381482class vec_arith : public VecOperators <vec<DataT, NumElements>>::Combined {};
382483
@@ -427,6 +528,7 @@ class vec_arith<std::byte, NumElements>
427528 }
428529};
429530#endif // (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
531+ #endif
430532
431533#undef __SYCL_INSTANTIATE_OPERATORS
432534
0 commit comments