//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 // // // [simd.class] // template void copy_from(const value_type* mem, Flags); // template void copy_to(value_type* mem, Flags); #include "../test_utils.h" namespace ex = std::experimental::parallelism_v2; template struct CheckSimdMaskCopyFrom { template void operator()() { constexpr std::size_t array_size = ex::simd_size_v; // element aligned tag constexpr std::size_t element_alignas_size = alignof(bool); alignas(element_alignas_size) bool element_buffer[array_size]; for (size_t i = 0; i < array_size; ++i) element_buffer[i] = static_cast(i % 2); ex::simd_mask element_mask; element_mask.copy_from(element_buffer, ex::element_aligned_tag()); assert_simd_mask_values_equal(element_mask, element_buffer); // vector aligned tag constexpr std::size_t vector_alignas_size = ex::memory_alignment_v>; alignas(vector_alignas_size) bool vector_buffer[array_size]; for (size_t i = 0; i < array_size; ++i) vector_buffer[i] = static_cast(i % 2); ex::simd_mask vector_mask; vector_mask.copy_from(vector_buffer, ex::vector_aligned_tag()); assert_simd_mask_values_equal(vector_mask, vector_buffer); // overaligned tag constexpr std::size_t over_alignas_size = bit_ceil(sizeof(bool) + 1); alignas(over_alignas_size) bool overaligned_buffer[array_size]; for (size_t i = 0; i < array_size; ++i) overaligned_buffer[i] = static_cast(i % 2); ex::simd_mask overaligned_mask; overaligned_mask.copy_from(overaligned_buffer, ex::overaligned_tag()); assert_simd_mask_values_equal(overaligned_mask, overaligned_buffer); } }; template struct CheckSimdMaskCopyTo { template void operator()() { constexpr std::size_t array_size = ex::simd_size_v; // element aligned tag constexpr std::size_t element_alignas_size = alignof(bool); alignas(element_alignas_size) bool element_buffer[array_size]; ex::simd_mask element_mask(true); element_mask.copy_to(element_buffer, ex::element_aligned_tag()); assert_simd_mask_values_equal(element_mask, element_buffer); // vector aligned tag constexpr std::size_t vector_alignas_size = ex::memory_alignment_v>; alignas(vector_alignas_size) bool vector_buffer[array_size]; ex::simd_mask vector_mask(false); vector_mask.copy_to(vector_buffer, ex::vector_aligned_tag()); assert_simd_mask_values_equal(vector_mask, vector_buffer); // overaligned tag constexpr std::size_t over_alignas_size = bit_ceil(sizeof(bool) + 1); alignas(over_alignas_size) bool overaligned_buffer[array_size]; ex::simd_mask overaligned_mask(true); overaligned_mask.copy_to(overaligned_buffer, ex::overaligned_tag()); assert_simd_mask_values_equal(overaligned_mask, overaligned_buffer); } }; template , class = void> struct has_copy_from : std::false_type {}; template struct has_copy_from>().copy_from( std::declval(), std::declval()))>> : std::true_type {}; template , class = void> struct has_copy_to : std::false_type {}; template struct has_copy_to>().copy_to( std::declval(), std::declval()))>> : std::true_type {}; template struct CheckSimdMaskCopyTraits { template void operator()() { // These functions shall not participate in overload resolution unless // is_simd_flag_type_v is true static_assert(has_copy_from::value); static_assert(has_copy_to::value); // is_simd_flag_type_v is false static_assert(!has_copy_from::value); static_assert(!has_copy_to::value); static_assert(!has_copy_from::value); static_assert(!has_copy_to::value); } }; int main(int, char**) { test_all_simd_abi(); test_all_simd_abi(); test_all_simd_abi(); return 0; }