118 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410 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 25namespace ex = std::experimental::parallelism_v2;26 27struct 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 34struct 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 41struct 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 48struct 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 55struct 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 62struct 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 69struct 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 76template <typename T, typename SimdAbi, typename Op, typename OpAssign>77struct 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 87template <typename T, typename SimdAbi, typename Op, typename OpAssign>88struct 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 98template <class T, std::size_t>99struct 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 114int main(int, char**) {115 types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckReferenceBitwiseOperators>());116 return 0;117}118