//===----------------------------------------------------------------------===// // // 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.traits] // template struct memory_alignment; // template // inline constexpr std::size_t memory_alignment_v = memory_alignment::value; #include "../test_utils.h" namespace ex = std::experimental::parallelism_v2; template struct CheckMemoryAlignmentMask { template void operator()() { LIBCPP_STATIC_ASSERT( ex::memory_alignment>::value == bit_ceil(sizeof(bool) * ex::simd_size_v)); LIBCPP_STATIC_ASSERT( ex::memory_alignment_v> == bit_ceil(sizeof(bool) * ex::simd_size_v)); } }; template struct CheckMemoryAlignmentLongDouble { template void operator()() { if constexpr (std::is_same_v) { // on i686-w64-mingw32-clang++, the size of long double is 12 bytes. Disambiguation is needed. static_assert( ex::memory_alignment>::value == bit_ceil(sizeof(T) * ex::simd_size_v)); static_assert(ex::memory_alignment_v> == bit_ceil(sizeof(T) * ex::simd_size_v)); } } }; struct CheckMemAlignmentFixedDeduce { template void check() { if constexpr (!std::is_same_v) { static_assert(ex::memory_alignment_v>> == sizeof(T) * bit_ceil(N), "Memory Alignment mismatch with abi fixed_size"); static_assert(ex::memory_alignment>>::value == sizeof(T) * bit_ceil(N), "Memory Alignment mismatch with abi fixed_size"); static_assert(ex::memory_alignment_v>> == sizeof(T) * bit_ceil(N), "Memory Alignment mismatch with abi deduce"); static_assert(ex::memory_alignment>>::value == sizeof(T) * bit_ceil(N), "Memory Alignment mismatch with abi deduce"); } } template void performChecks(std::index_sequence) { (check(), ...); } template void operator()() { performChecks(std::make_index_sequence{}); } }; struct CheckMemAlignmentScalarNativeCompatible { template void operator()() { if constexpr (!std::is_same_v) { static_assert(ex::memory_alignment>::value == sizeof(T)); static_assert(ex::memory_alignment_v> == sizeof(T)); LIBCPP_STATIC_ASSERT(ex::memory_alignment>>::value == 16); LIBCPP_STATIC_ASSERT(ex::memory_alignment_v>> == 16); LIBCPP_STATIC_ASSERT( ex::memory_alignment>>::value == _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES); LIBCPP_STATIC_ASSERT( ex::memory_alignment_v>> == _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES); } } }; template struct has_memory_alignment : std::false_type {}; template struct has_memory_alignment::value)>> : std::true_type {}; struct CheckMemoryAlignmentTraits { template void operator()() { static_assert(has_memory_alignment>::value); static_assert(has_memory_alignment>::value); static_assert(has_memory_alignment, T>::value); static_assert(has_memory_alignment, bool>::value); static_assert(!has_memory_alignment::value); static_assert(!has_memory_alignment::value); static_assert(!has_memory_alignment, bool>::value); static_assert(!has_memory_alignment, T>::value); } }; int main(int, char**) { types::for_each(arithmetic_no_bool_types(), CheckMemAlignmentFixedDeduce()); types::for_each(arithmetic_no_bool_types(), CheckMemAlignmentScalarNativeCompatible()); test_all_simd_abi(); test_all_simd_abi(); types::for_each(arithmetic_no_bool_types(), CheckMemoryAlignmentTraits()); return 0; }