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 PlusAssign { 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 MinusAssign { 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 MultipliesAssign { 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 DividesAssign { 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 ModulusAssign { 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 template <typename T, typename SimdAbi, typename Op, typename OpAssign> 63899055f2SZhangYin struct SimdReferenceOperatorHelper { 64899055f2SZhangYin template <class U> 65899055f2SZhangYin void operator()() const { 66899055f2SZhangYin ex::simd<T, SimdAbi> origin_simd(static_cast<T>(3)); 67899055f2SZhangYin static_assert(noexcept(OpAssign{}(origin_simd[0], static_cast<U>(2)))); 68899055f2SZhangYin OpAssign{}(origin_simd[0], static_cast<U>(2)); 69899055f2SZhangYin assert((T)origin_simd[0] == (T)Op{}(static_cast<T>(3), static_cast<T>(std::forward<U>(2)))); 70899055f2SZhangYin } 71899055f2SZhangYin }; 72899055f2SZhangYin 73899055f2SZhangYin template <class T, std::size_t> 74899055f2SZhangYin struct CheckReferenceArithOperators { 75899055f2SZhangYin template <class SimdAbi> 76899055f2SZhangYin void operator()() { 77899055f2SZhangYin types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::plus<>, PlusAssign>()); 78899055f2SZhangYin types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::minus<>, MinusAssign>()); 79899055f2SZhangYin types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::multiplies<>, MultipliesAssign>()); 80899055f2SZhangYin types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::divides<>, DividesAssign>()); 81899055f2SZhangYin } 82899055f2SZhangYin }; 83899055f2SZhangYin 84899055f2SZhangYin template <class T, std::size_t> 85899055f2SZhangYin struct CheckReferenceModOperators { 86899055f2SZhangYin template <class SimdAbi> 87899055f2SZhangYin void operator()() { 88899055f2SZhangYin types::for_each( 89899055f2SZhangYin simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::modulus<>, ModulusAssign>()); 90899055f2SZhangYin } 91899055f2SZhangYin }; 92899055f2SZhangYin 93899055f2SZhangYin int main(int, char**) { 94899055f2SZhangYin test_all_simd_abi<CheckReferenceArithOperators>(); 95899055f2SZhangYin types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckReferenceModOperators>()); 96899055f2SZhangYin return 0; 97899055f2SZhangYin } 98