1899055f2SZhangYin //===----------------------------------------------------------------------===// 2899055f2SZhangYin // 3899055f2SZhangYin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4899055f2SZhangYin // See https://llvm.org/LICENSE.txt for license information. 5899055f2SZhangYin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6899055f2SZhangYin // 7899055f2SZhangYin //===----------------------------------------------------------------------===// 8899055f2SZhangYin 9899055f2SZhangYin // UNSUPPORTED: c++03, c++11, c++14 10899055f2SZhangYin 11899055f2SZhangYin // <experimental/simd> 12899055f2SZhangYin // 13899055f2SZhangYin // [simd.reference] 14899055f2SZhangYin // template<class U> reference|=(U&& x) && noexcept; 15899055f2SZhangYin // template<class U> reference&=(U&& x) && noexcept; 16899055f2SZhangYin // template<class U> reference^=(U&& x) && noexcept; 17899055f2SZhangYin // template<class U> reference<<=(U&& x) && noexcept; 18899055f2SZhangYin // template<class U> reference>>=(U&& x) && noexcept; 19899055f2SZhangYin 20899055f2SZhangYin #include <experimental/simd> 21*09e3a360SLouis Dionne #include <functional> 22*09e3a360SLouis Dionne 23*09e3a360SLouis Dionne #include "../test_utils.h" 24899055f2SZhangYin 25899055f2SZhangYin namespace ex = std::experimental::parallelism_v2; 26899055f2SZhangYin 27899055f2SZhangYin struct AndAssign { 28899055f2SZhangYin template <typename T, typename U> 29899055f2SZhangYin void operator()(T&& lhs, const U& rhs) const noexcept { 30899055f2SZhangYin std::forward<T>(lhs) &= rhs; 31899055f2SZhangYin } 32899055f2SZhangYin }; 33899055f2SZhangYin 34899055f2SZhangYin struct OrAssign { 35899055f2SZhangYin template <typename T, typename U> 36899055f2SZhangYin void operator()(T&& lhs, const U& rhs) const noexcept { 37899055f2SZhangYin std::forward<T>(lhs) |= rhs; 38899055f2SZhangYin } 39899055f2SZhangYin }; 40899055f2SZhangYin 41899055f2SZhangYin struct XorAssign { 42899055f2SZhangYin template <typename T, typename U> 43899055f2SZhangYin void operator()(T&& lhs, const U& rhs) const noexcept { 44899055f2SZhangYin std::forward<T>(lhs) ^= rhs; 45899055f2SZhangYin } 46899055f2SZhangYin }; 47899055f2SZhangYin 48899055f2SZhangYin struct LeftShiftAssign { 49899055f2SZhangYin template <typename T, typename U> 50899055f2SZhangYin void operator()(T&& lhs, const U& rhs) const noexcept { 51899055f2SZhangYin std::forward<T>(lhs) <<= rhs; 52899055f2SZhangYin } 53899055f2SZhangYin }; 54899055f2SZhangYin 55899055f2SZhangYin struct RightShiftAssign { 56899055f2SZhangYin template <typename T, typename U> 57899055f2SZhangYin void operator()(T&& lhs, const U& rhs) const noexcept { 58899055f2SZhangYin std::forward<T>(lhs) >>= rhs; 59899055f2SZhangYin } 60899055f2SZhangYin }; 61899055f2SZhangYin 62899055f2SZhangYin struct LeftShift { 63899055f2SZhangYin template <typename T, typename U> 64899055f2SZhangYin T operator()(const T& lhs, const U& rhs) const noexcept { 65899055f2SZhangYin return lhs << rhs; 66899055f2SZhangYin } 67899055f2SZhangYin }; 68899055f2SZhangYin 69899055f2SZhangYin struct RightShift { 70899055f2SZhangYin template <typename T, typename U> 71899055f2SZhangYin T operator()(const T& lhs, const U& rhs) const noexcept { 72899055f2SZhangYin return lhs >> rhs; 73899055f2SZhangYin } 74899055f2SZhangYin }; 75899055f2SZhangYin 76899055f2SZhangYin template <typename T, typename SimdAbi, typename Op, typename OpAssign> 77899055f2SZhangYin struct SimdReferenceOperatorHelper { 78899055f2SZhangYin template <class U> 79899055f2SZhangYin void operator()() const { 80899055f2SZhangYin ex::simd<T, SimdAbi> origin_simd(static_cast<T>(3)); 81899055f2SZhangYin static_assert(noexcept(OpAssign{}(origin_simd[0], static_cast<U>(2)))); 82899055f2SZhangYin OpAssign{}(origin_simd[0], static_cast<U>(2)); 83899055f2SZhangYin assert((T)origin_simd[0] == (T)Op{}(static_cast<T>(3), static_cast<T>(std::forward<U>(2)))); 84899055f2SZhangYin } 85899055f2SZhangYin }; 86899055f2SZhangYin 87899055f2SZhangYin template <typename T, typename SimdAbi, typename Op, typename OpAssign> 88899055f2SZhangYin struct MaskReferenceOperatorHelper { 89899055f2SZhangYin template <class U> 90899055f2SZhangYin void operator()() const { 91899055f2SZhangYin ex::simd_mask<T, SimdAbi> origin_mask(true); 92899055f2SZhangYin static_assert(noexcept(OpAssign{}(origin_mask[0], static_cast<U>(false)))); 93899055f2SZhangYin OpAssign{}(origin_mask[0], static_cast<U>(false)); 94899055f2SZhangYin assert((bool)origin_mask[0] == (bool)Op{}(true, static_cast<bool>(std::forward<U>(false)))); 95899055f2SZhangYin } 96899055f2SZhangYin }; 97899055f2SZhangYin 98899055f2SZhangYin template <class T, std::size_t> 99899055f2SZhangYin struct CheckReferenceBitwiseOperators { 100899055f2SZhangYin template <class SimdAbi> 101899055f2SZhangYin void operator()() { 102899055f2SZhangYin types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_and<>, AndAssign>()); 103899055f2SZhangYin types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_or<>, OrAssign>()); 104899055f2SZhangYin types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::bit_xor<>, XorAssign>()); 105899055f2SZhangYin types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, LeftShift, LeftShiftAssign>()); 106899055f2SZhangYin types::for_each(simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, RightShift, RightShiftAssign>()); 107899055f2SZhangYin 108899055f2SZhangYin types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_and<>, AndAssign>()); 109899055f2SZhangYin types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_or<>, OrAssign>()); 110899055f2SZhangYin types::for_each(simd_test_integer_types(), MaskReferenceOperatorHelper<T, SimdAbi, std::bit_xor<>, XorAssign>()); 111899055f2SZhangYin } 112899055f2SZhangYin }; 113899055f2SZhangYin 114899055f2SZhangYin int main(int, char**) { 115899055f2SZhangYin types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckReferenceBitwiseOperators>()); 116899055f2SZhangYin return 0; 117899055f2SZhangYin } 118