Index: libcxx/include/experimental/simd =================================================================== --- libcxx/include/experimental/simd +++ libcxx/include/experimental/simd @@ -940,7 +940,7 @@ template using fixed_size = __simd_abi<_StorageKind::_Array, _Np>; -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +#if _LIBCPP_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR constexpr size_t max_fixed_size = 32; #endif @@ -974,7 +974,7 @@ struct vector_aligned_tag {}; template struct overaligned_tag {}; -#if _LIBCPP_STD_VER > 14 +#if _LIBCPP_STD_VER >= 14 _LIBCPP_INLINE_VAR constexpr element_aligned_tag element_aligned{}; _LIBCPP_INLINE_VAR constexpr vector_aligned_tag vector_aligned{}; #if !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) @@ -1019,7 +1019,7 @@ struct is_simd_flag_type> : std::integral_constant {}; -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +#if _LIBCPP_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template _LIBCPP_INLINE_VAR constexpr bool is_abi_tag_v = is_abi_tag<_Tp>::value; template @@ -1061,11 +1061,19 @@ "Element type should be vectorizable"); }; -// TODO: implement it. -template +template struct memory_alignment; -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +// TODO: May extend this after implementing vector_aligned. +template +struct memory_alignment, _Up> + : std::integral_constant)> {}; + +template +struct memory_alignment, bool> + : std::integral_constant)> {}; + +#if _LIBCPP_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template > _LIBCPP_INLINE_VAR constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value; @@ -1522,11 +1530,11 @@ return __m.size(); } -bool all_of(bool __v) noexcept { return __v; } -bool any_of(bool __v) noexcept { return __v; } -bool none_of(bool __v) noexcept { return !__v; } +bool all_of(bool __val) noexcept { return __val; } +bool any_of(bool __val) noexcept { return __val; } +bool none_of(bool __val) noexcept { return !__val; } bool some_of(bool) noexcept { return false; } -int popcount(bool __v) noexcept { return __v; } +int popcount(bool __val) noexcept { return __val; } int find_first_set(bool) noexcept { return 0; } int find_last_set(bool) noexcept { return 0; } @@ -1681,9 +1689,9 @@ template ()>::type> simd(_Up&& __rv) { - auto __v = static_cast<_Tp>(__rv); + auto __val = static_cast<_Tp>(__rv); for (size_t __i = 0; __i < size(); __i++) { - (*this)[__i] = __v; + (*this)[__i] = __val; } } @@ -1987,9 +1995,9 @@ simd_mask() = default; // broadcast constructor - explicit simd_mask(value_type __value) noexcept { + explicit simd_mask(value_type __val) noexcept { for (size_t __i = 0; __i < size(); __i++) { - (*this)[__i] = __value; + (*this)[__i] = __val; } } @@ -2009,6 +2017,7 @@ template ::value>::type> simd_mask(const value_type* __buffer, _Flags) { + // TODO: optimize for overaligned flags for (size_t __i = 0; __i < size(); __i++) { (*this)[__i] = __buffer[__i]; } @@ -2024,6 +2033,7 @@ template typename std::enable_if::value>::type copy_to(value_type* __buffer, _Flags) const { + // TODO: optimize for overaligned flags for (size_t __i = 0; __i < size(); __i++) { __buffer[__i] = (*this)[__i]; } @@ -2093,6 +2103,7 @@ template void __mask_copy_to(const simd<_Tp, _Abi>& __v, const simd_mask<_Tp, _Abi>& __m, _Up* __buffer, _Flags) { + // TODO: optimize for overaligned flags for (size_t __i = 0; __i < __v.size(); __i++) { if (__m[__i]) { __buffer[__i] = static_cast<_Up>(__v[__i]); @@ -2103,6 +2114,7 @@ template void __mask_copy_to(const simd_mask<_Tp, _Abi>& __v, const simd_mask<_Tp, _Abi>& __m, _Up* __buffer, _Flags) { + // TODO: optimize based on bool's bit pattern. for (size_t __i = 0; __i < __v.size(); __i++) { if (__m[__i]) { __buffer[__i] = static_cast<_Up>(__v[__i]); @@ -2111,9 +2123,9 @@ } template -void __mask_copy_to(_Tp __v, bool __m, _Up* __buffer, _Flags) { +void __mask_copy_to(_Tp __val, bool __m, _Up* __buffer, _Flags) { if (__m) { - *__buffer = static_cast<_Up>(__v); + *__buffer = static_cast<_Up>(__val); } } @@ -2141,9 +2153,9 @@ } template -void __mask_copy_from(_Tp& __v, bool __m, const _Up* __buffer, _Flags) { +void __mask_copy_from(_Tp& __val, bool __m, const _Up* __buffer, _Flags) { if (__m) { - __v = static_cast<_Tp>(*__buffer); + __val = static_cast<_Tp>(*__buffer); } } @@ -2493,6 +2505,8 @@ __w.__v_, __w.__m_)); } +// TODO: Implement functions for simd. + _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD #endif /* _LIBCPP_EXPERIMENTAL_SIMD */ Index: libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp +++ libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp @@ -70,7 +70,7 @@ assert(a[3] == 1); } -#if TEST_STD_VER > 14 +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) { fixed_size_simd a(buffer, element_aligned); assert(a[0] == 4); Index: libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp +++ libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp @@ -46,7 +46,7 @@ assert(buf[2] == m[2]); assert(buf[3] == m[3]); } -#if TEST_STD_VER > 14 +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) { bool buf[] = {false, true, true, false}; fixed_size_simd_mask m(buf, element_aligned); Index: libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp +++ libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp @@ -74,7 +74,7 @@ assert(!a[3]); } -#if TEST_STD_VER > 14 +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) { fixed_size_simd_mask a; a.copy_from(buffer, element_aligned); Index: libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp +++ libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp @@ -51,7 +51,7 @@ assert(!buffer[3]); } -#if TEST_STD_VER > 14 +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) { alignas(32) bool buffer[4] = {0}; a.copy_to(buffer, element_aligned); Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp +++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp @@ -74,7 +74,7 @@ assert(a[3] == 1); } -#if TEST_STD_VER > 14 +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) { fixed_size_simd a; a.copy_from(buffer, element_aligned); Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp +++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp @@ -48,7 +48,7 @@ assert(buffer[3] == 1); } -#if TEST_STD_VER > 14 +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) { alignas(32) int32_t buffer[4] = {0}; a.copy_to(buffer, element_aligned); Index: libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp +++ libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp @@ -54,8 +54,7 @@ static_assert(is_abi_tag>::value, ""); static_assert(is_abi_tag>::value, ""); -#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && \ - !defined(_LIBCPP_HAS_NO_INLINE_VARIABLES) +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) static_assert(is_abi_tag_v>, ""); static_assert(is_abi_tag_v>, ""); Index: libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp +++ libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp @@ -67,8 +67,7 @@ static_assert(!is_simd::value, ""); -#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && \ - !defined(_LIBCPP_HAS_NO_INLINE_VARIABLES) +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) static_assert(is_simd_v>, ""); static_assert(is_simd_v>, ""); Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp +++ libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp @@ -26,8 +26,7 @@ static_assert(is_simd_flag_type>::value, ""); static_assert(is_simd_flag_type>::value, ""); -#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && \ - !defined(_LIBCPP_HAS_NO_INLINE_VARIABLES) +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) static_assert(is_simd_flag_type_v, ""); static_assert(is_simd_flag_type_v, ""); Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp =================================================================== --- libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp +++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp @@ -67,8 +67,7 @@ static_assert(!is_simd_mask::value, ""); -#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && \ - !defined(_LIBCPP_HAS_NO_INLINE_VARIABLES) +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) static_assert(is_simd_mask_v>, ""); static_assert(is_simd_mask_v>, ""); Index: libcxx/test/std/experimental/simd/simd.traits/memory_alignment.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/experimental/simd/simd.traits/memory_alignment.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// +// +// [simd.traits] +// template struct memory_alignment; +// template +// inline constexpr size_t memory_alignment_v = memory_alignment::value; + +#include +#include "test_macros.h" + +using namespace std::experimental::parallelism_v2; + +static_assert(std::is_same>::value)>::value, + ""); +static_assert( + std::is_same, int>::value)>::value, + ""); +static_assert( + std::is_same< + const size_t, + decltype(memory_alignment, unsigned int>::value)>::value, + ""); +static_assert( + std::is_same>::value)>::value, + ""); +static_assert( + std::is_same, + bool>::value)>::value, + ""); + +#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + +static_assert( + std::is_same>)>::value, + ""); +static_assert(std::is_same, int>)>::value, + ""); +static_assert( + std::is_same, unsigned int>)>::value, + ""); +static_assert(std::is_same>)>::value, + ""); +static_assert( + std::is_same, bool>)>::value, + ""); + +#endif + +int main() {}