brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · 172c97f Raw
170 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.class]14// template<class U, class Flags> void copy_from(const U* mem, Flags);15// template<class U, class Flags> void copy_to(U* mem, Flags) const;16 17#include "../test_utils.h"18 19namespace ex = std::experimental::parallelism_v2;20 21template <class T, class SimdAbi, std::size_t array_size>22struct ElementAlignedCopyFromHelper {23  template <class U>24  void operator()() const {25    U buffer[array_size];26    for (size_t i = 0; i < array_size; ++i)27      buffer[i] = static_cast<U>(i);28    ex::simd<T, SimdAbi> origin_simd;29    origin_simd.copy_from(buffer, ex::element_aligned_tag());30    assert_simd_values_equal(origin_simd, buffer);31  }32};33 34template <class T, class SimdAbi, std::size_t array_size>35struct VectorAlignedCopyFromHelper {36  template <class U>37  void operator()() const {38    alignas(ex::memory_alignment_v<ex::simd<T, SimdAbi>, U>) U buffer[array_size];39    for (size_t i = 0; i < array_size; ++i)40      buffer[i] = static_cast<U>(i);41    ex::simd<T, SimdAbi> origin_simd;42    origin_simd.copy_from(buffer, ex::vector_aligned_tag());43    assert_simd_values_equal(origin_simd, buffer);44  }45};46 47template <class T, class SimdAbi, std::size_t array_size>48struct OveralignedCopyFromHelper {49  template <class U>50  void operator()() const {51    alignas(bit_ceil(sizeof(U) + 1)) U buffer[array_size];52    for (size_t i = 0; i < array_size; ++i)53      buffer[i] = static_cast<U>(i);54    ex::simd<T, SimdAbi> origin_simd;55    origin_simd.copy_from(buffer, ex::overaligned_tag<bit_ceil(sizeof(U) + 1)>());56    assert_simd_values_equal(origin_simd, buffer);57  }58};59 60template <class T, std::size_t>61struct CheckSimdCopyFrom {62  template <class SimdAbi>63  void operator()() {64    constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;65 66    types::for_each(simd_test_types(), ElementAlignedCopyFromHelper<T, SimdAbi, array_size>());67    types::for_each(simd_test_types(), VectorAlignedCopyFromHelper<T, SimdAbi, array_size>());68    types::for_each(simd_test_types(), OveralignedCopyFromHelper<T, SimdAbi, array_size>());69  }70};71 72template <class T, class SimdAbi, std::size_t array_size>73struct ElementAlignedCopyToHelper {74  template <class U>75  void operator()() const {76    U buffer[array_size];77    ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });78    origin_simd.copy_to(buffer, ex::element_aligned_tag());79    assert_simd_values_equal(origin_simd, buffer);80  }81};82 83template <class T, class SimdAbi, std::size_t array_size>84struct VectorAlignedCopyToHelper {85  template <class U>86  void operator()() const {87    alignas(ex::memory_alignment_v<ex::simd<T, SimdAbi>, U>) U buffer[array_size];88    ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });89    origin_simd.copy_to(buffer, ex::vector_aligned_tag());90    assert_simd_values_equal(origin_simd, buffer);91  }92};93 94template <class T, class SimdAbi, std::size_t array_size>95struct OveralignedCopyToHelper {96  template <class U>97  void operator()() const {98    alignas(bit_ceil(sizeof(U) + 1)) U buffer[array_size];99    ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });100    origin_simd.copy_to(buffer, ex::overaligned_tag<bit_ceil(sizeof(U) + 1)>());101    assert_simd_values_equal(origin_simd, buffer);102  }103};104 105template <class T, std::size_t>106struct CheckSimdCopyTo {107  template <class SimdAbi>108  void operator()() {109    constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;110 111    types::for_each(simd_test_types(), ElementAlignedCopyToHelper<T, SimdAbi, array_size>());112    types::for_each(simd_test_types(), VectorAlignedCopyToHelper<T, SimdAbi, array_size>());113    types::for_each(simd_test_types(), OveralignedCopyToHelper<T, SimdAbi, array_size>());114  }115};116 117template <class U, class T, class Flags, class SimdAbi = ex::simd_abi::compatible<T>, class = void>118struct has_copy_from : std::false_type {};119 120template <class U, class T, class Flags, class SimdAbi>121struct has_copy_from<U,122                     T,123                     Flags,124                     SimdAbi,125                     std::void_t<decltype(std::declval<ex::simd<T, SimdAbi>>().copy_from(126                         std::declval<const U*>(), std::declval<Flags>()))>> : std::true_type {};127 128template <class U, class T, class Flags, class SimdAbi = ex::simd_abi::compatible<T>, class = void>129struct has_copy_to : std::false_type {};130 131template <class U, class T, class Flags, class SimdAbi>132struct has_copy_to<133    U,134    T,135    Flags,136    SimdAbi,137    std::void_t<decltype(std::declval<ex::simd<T, SimdAbi>>().copy_to(std::declval<U*>(), std::declval<Flags>()))>>138    : std::true_type {};139 140template <class T, std::size_t>141struct CheckSimdCopyTraits {142  template <class SimdAbi>143  void operator()() {144    // These functions shall not participate in overload resolution unless145    // is_simd_flag_type_v<Flags> is true, and146    // U is a vectorizable type.147    static_assert(has_copy_from<int, T, ex::element_aligned_tag, SimdAbi>::value);148    static_assert(has_copy_to<int, T, ex::element_aligned_tag, SimdAbi>::value);149 150    // is_simd_flag_type_v<Flags> is false151    static_assert(!has_copy_from<int, T, T, SimdAbi>::value);152    static_assert(!has_copy_to<int, T, T, SimdAbi>::value);153    static_assert(!has_copy_from<int, T, SimdAbi, SimdAbi>::value);154    static_assert(!has_copy_to<int, T, SimdAbi, SimdAbi>::value);155 156    // U is not a vectorizable type.157    static_assert(!has_copy_from<SimdAbi, T, ex::element_aligned_tag, SimdAbi>::value);158    static_assert(!has_copy_to<SimdAbi, T, ex::element_aligned_tag, SimdAbi>::value);159    static_assert(!has_copy_from<ex::element_aligned_tag, T, ex::element_aligned_tag, SimdAbi>::value);160    static_assert(!has_copy_to<ex::element_aligned_tag, T, ex::element_aligned_tag, SimdAbi>::value);161  }162};163 164int main(int, char**) {165  test_all_simd_abi<CheckSimdCopyFrom>();166  test_all_simd_abi<CheckSimdCopyTo>();167  test_all_simd_abi<CheckSimdCopyTraits>();168  return 0;169}170