1 //===----------------------------------------------------------------------===// 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 9 // UNSUPPORTED: c++03, c++11, c++14 10 11 // <experimental/simd> 12 // 13 // [simd.reference] 14 // template<class U> reference|=(U&& x) && noexcept; 15 // template<class U> reference&=(U&& x) && noexcept; 16 // template<class U> reference^=(U&& x) && noexcept; 17 // template<class U> reference<<=(U&& x) && noexcept; 18 // template<class U> reference>>=(U&& x) && noexcept; 19 20 #include <experimental/simd> 21 #include <functional> 22 23 #include "../test_utils.h" 24 25 namespace ex = std::experimental::parallelism_v2; 26 27 struct AndAssign { 28 template <typename T, typename U> 29 void operator()(T&& lhs, const U& rhs) const noexcept { 30 std::forward<T>(lhs) &= rhs; 31 } 32 }; 33 34 struct OrAssign { 35 template <typename T, typename U> 36 void operator()(T&& lhs, const U& rhs) const noexcept { 37 std::forward<T>(lhs) |= rhs; 38 } 39 }; 40 41 struct XorAssign { 42 template <typename T, typename U> 43 void operator()(T&& lhs, const U& rhs) const noexcept { 44 std::forward<T>(lhs) ^= rhs; 45 } 46 }; 47 48 struct LeftShiftAssign { 49 template <typename T, typename U> 50 void operator()(T&& lhs, const U& rhs) const noexcept { 51 std::forward<T>(lhs) <<= rhs; 52 } 53 }; 54 55 struct RightShiftAssign { 56 template <typename T, typename U> 57 void operator()(T&& lhs, const U& rhs) const noexcept { 58 std::forward<T>(lhs) >>= rhs; 59 } 60 }; 61 62 struct LeftShift { 63 template <typename T, typename U> 64 T operator()(const T& lhs, const U& rhs) const noexcept { 65 return lhs << rhs; 66 } 67 }; 68 69 struct RightShift { 70 template <typename T, typename U> 71 T operator()(const T& lhs, const U& rhs) const noexcept { 72 return lhs >> rhs; 73 } 74 }; 75 76 template <typename T, typename SimdAbi, typename Op, typename OpAssign> 77 struct SimdReferenceOperatorHelper { 78 template <class U> 79 void operator()() const { 80 ex::simd<T, SimdAbi> origin_simd(static_cast<T>(3)); 81 static_assert(noexcept(OpAssign{}(origin_simd[0], static_cast<U>(2)))); 82 OpAssign{}(origin_simd[0], static_cast<U>(2)); 83 assert((T)origin_simd[0] == (T)Op{}(static_cast<T>(3), static_cast<T>(std::forward<U>(2)))); 84 } 85 }; 86 87 template <typename T, typename SimdAbi, typename Op, typename OpAssign> 88 struct MaskReferenceOperatorHelper { 89 template <class U> 90 void operator()() const { 91 ex::simd_mask<T, SimdAbi> origin_mask(true); 92 static_assert(noexcept(OpAssign{}(origin_mask[0], static_cast<U>(false)))); 93 OpAssign{}(origin_mask[0], static_cast<U>(false)); 94 assert((bool)origin_mask[0] == (bool)Op{}(true, static_cast<bool>(std::forward<U>(false)))); 95 } 96 }; 97 98 template <class T, std::size_t> 99 struct CheckReferenceBitwiseOperators { 100 template <class SimdAbi> 101 void operator()() { 102 types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_and<>, AndAssign>()); 103 types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_or<>, OrAssign>()); 104 types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_xor<>, XorAssign>()); 105 types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, LeftShift, LeftShiftAssign>()); 106 types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, RightShift, RightShiftAssign>()); 107 108 types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_and<>, AndAssign>()); 109 types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_or<>, OrAssign>()); 110 types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_xor<>, XorAssign>()); 111 } 112 }; 113 114 int main(int, char**) { 115 types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckReferenceBitwiseOperators>()); 116 return 0; 117 } 118