diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -886,10 +886,12 @@ experimental/__config experimental/__memory experimental/__simd/abi_tag.h + experimental/__simd/declaration.h experimental/__simd/scalar.h experimental/__simd/simd.h experimental/__simd/simd_mask.h experimental/__simd/traits.h + experimental/__simd/utility.h experimental/__simd/vec_ext.h experimental/deque experimental/forward_list diff --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/declaration.h copy from libcxx/include/experimental/__simd/simd.h copy to libcxx/include/experimental/__simd/declaration.h --- a/libcxx/include/experimental/__simd/simd.h +++ b/libcxx/include/experimental/__simd/declaration.h @@ -7,29 +7,22 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H -#define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H - -#include +#ifndef _LIBCPP_EXPERIMENTAL___SIMD_DECLARATION_H +#define _LIBCPP_EXPERIMENTAL___SIMD_DECLARATION_H #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 { -// class template simd [simd.class] -// TODO: implement simd class template > class simd; -template -using native_simd = simd<_Tp, simd_abi::native<_Tp>>; - -template -using fixed_size_simd = simd<_Tp, simd_abi::fixed_size<_Np>>; +template > +class simd_mask; } // namespace parallelism_v2 _LIBCPP_END_NAMESPACE_EXPERIMENTAL #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) -#endif // _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H +#endif // _LIBCPP_EXPERIMENTAL___SIMD_DECLARATION_H diff --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/simd.h --- a/libcxx/include/experimental/__simd/simd.h +++ b/libcxx/include/experimental/__simd/simd.h @@ -11,6 +11,8 @@ #define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H #include +#include +#include #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) @@ -19,8 +21,15 @@ // class template simd [simd.class] // TODO: implement simd class -template > -class simd; +template +class simd { +public: + using value_type = _Tp; + using mask_type = simd_mask<_Tp, _Abi>; + using abi_type = _Abi; + + static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_size_v; } +}; template using native_simd = simd<_Tp, simd_abi::native<_Tp>>; diff --git a/libcxx/include/experimental/__simd/simd_mask.h b/libcxx/include/experimental/__simd/simd_mask.h --- a/libcxx/include/experimental/__simd/simd_mask.h +++ b/libcxx/include/experimental/__simd/simd_mask.h @@ -11,6 +11,7 @@ #define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_MASK_H #include +#include #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) @@ -19,8 +20,15 @@ // class template simd_mask [simd.mask.class] // TODO: implement simd_mask class -template > -class simd_mask; +template +class simd_mask { +public: + using value_type = bool; + using simd_type = simd<_Tp, _Abi>; + using abi_type = _Abi; + + static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_type::size(); } +}; template using native_simd_mask = simd_mask<_Tp, simd_abi::native<_Tp>>; diff --git a/libcxx/include/experimental/__simd/traits.h b/libcxx/include/experimental/__simd/traits.h --- a/libcxx/include/experimental/__simd/traits.h +++ b/libcxx/include/experimental/__simd/traits.h @@ -11,8 +11,8 @@ #define _LIBCPP_EXPERIMENTAL___SIMD_TRAITS_H #include -#include -#include +#include +#include #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) @@ -50,6 +50,14 @@ template struct is_simd_mask : bool_constant> {}; +template , + class = enable_if_t<__is_vectorizable<_Tp>() && is_abi_tag_v<_Abi>>> +inline constexpr size_t simd_size_v = _Abi::__simd_size; + +template > +struct simd_size : integral_constant> {}; + } // namespace parallelism_v2 _LIBCPP_END_NAMESPACE_EXPERIMENTAL diff --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/utility.h copy from libcxx/include/experimental/__simd/simd.h copy to libcxx/include/experimental/__simd/utility.h --- a/libcxx/include/experimental/__simd/simd.h +++ b/libcxx/include/experimental/__simd/utility.h @@ -7,29 +7,21 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H -#define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H +#ifndef _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H +#define _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H -#include +#include #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 { - -// class template simd [simd.class] -// TODO: implement simd class -template > -class simd; - template -using native_simd = simd<_Tp, simd_abi::native<_Tp>>; - -template -using fixed_size_simd = simd<_Tp, simd_abi::fixed_size<_Np>>; - +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_vectorizable() { + return is_arithmetic_v<_Tp> && !is_const_v<_Tp> && !is_volatile_v<_Tp> && !is_same_v<_Tp, bool>; +} } // namespace parallelism_v2 _LIBCPP_END_NAMESPACE_EXPERIMENTAL #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) -#endif // _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H +#endif // _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H diff --git a/libcxx/include/experimental/simd b/libcxx/include/experimental/simd --- a/libcxx/include/experimental/simd +++ b/libcxx/include/experimental/simd @@ -47,6 +47,10 @@ template struct is_simd_mask; template inline constexpr bool is_simd_mask_v = is_simd_mask::value; + template> struct simd_size; + template> + inline constexpr size_t simd_size_v = simd_size::value; + } // namespace parallelism_v2 } // namespace std::experimental diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -262,6 +262,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/unordered_map algorithm diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -262,6 +262,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/unordered_map algorithm diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -262,6 +262,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -262,6 +262,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -269,6 +269,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv --- a/libcxx/test/libcxx/transitive_includes/cxx23.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv @@ -175,6 +175,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv --- a/libcxx/test/libcxx/transitive_includes/cxx26.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -175,6 +175,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/std/experimental/simd/simd.class/simd_width.pass.cpp b/libcxx/test/std/experimental/simd/simd.class/simd_width.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/experimental/simd/simd.class/simd_width.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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] +// static constexpr size_t size() noexcept; + +#include "../test_utils.h" +#include + +namespace ex = std::experimental::parallelism_v2; +struct CheckSimdWidth { + template + void operator()() { + const ex::simd<_Tp, SimdAbi> origin_simd{}; + static_assert(origin_simd.size() == ex::simd_size_v<_Tp, SimdAbi>); + } +}; +template +void test_simd_abi() {} +template +void test_simd_abi() { + F{}.template operator()<_Tp, SimdAbi>(); + test_simd_abi(); +} + +int main(int, char**) { + test_all_simd_abi(); + return 0; +} diff --git a/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_width.pass.cpp b/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_width.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_width.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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.mask.class] +// static constexpr size_t size() noexcept; + +#include "../test_utils.h" +#include + +namespace ex = std::experimental::parallelism_v2; +struct CheckSimdMaskWidth { + template + void operator()() { + const ex::simd_mask<_Tp, SimdAbi> origin_simd_mask{}; + static_assert(origin_simd_mask.size() == ex::simd_size_v<_Tp, SimdAbi>); + } +}; +template +void test_simd_abi() {} +template +void test_simd_abi() { + F{}.template operator()<_Tp, SimdAbi>(); + test_simd_abi(); +} + +int main(int, char**) { + test_all_simd_abi(); + return 0; +} diff --git a/libcxx/test/std/experimental/simd/simd.traits/simd_size.pass.cpp b/libcxx/test/std/experimental/simd/simd.traits/simd_size.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/experimental/simd/simd.traits/simd_size.pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// 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 simd_size; +//template > +//inline constexpr size_t ex::simd_size_v = ex::simd_size::value; + +#include "../test_utils.h" +#include + +namespace ex = std::experimental::parallelism_v2; + +struct CheckSimdSizeScalar { + template + void operator()() { + static_assert(ex::simd_size<_Tp, SimdAbi>::value == 1); + }; +}; +struct CheckSimdSizeVScalar { + template + void operator()() { + static_assert(ex::simd_size_v<_Tp, SimdAbi> == 1); + }; +}; +struct CheckSimdSizeDeduce { + template + void operator()() { + static_assert(ex::simd_size<_Tp, SimdAbi>::value == _Np); + }; +}; +struct CheckSimdSizeVDeduce { + template + void operator()() { + static_assert(ex::simd_size_v<_Tp, SimdAbi> == _Np); + }; +}; +struct CheckSimdSizeFixedSize { + template + void operator()() { + static_assert(ex::simd_size<_Tp, SimdAbi>::value == _Np); + }; +}; +struct CheckSimdSizeVFixedSize { + template + void operator()() { + static_assert(ex::simd_size_v<_Tp, SimdAbi> == _Np); + }; +}; +struct CheckSimdSizeCompatible { + template + void operator()() { + static_assert(ex::simd_size<_Tp, SimdAbi>::value == 16 / sizeof(_Tp)); + }; +}; +struct CheckSimdSizeVCompatible { + template + void operator()() { + static_assert(ex::simd_size_v<_Tp, SimdAbi> == 16 / sizeof(_Tp)); + }; +}; + +struct CheckSimdSizeNative { + template + void operator()() { + static_assert(ex::simd_size<_Tp, SimdAbi>::value == _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)); + }; +}; +struct CheckSimdSizeVNative { + template + void operator()() { + static_assert(ex::simd_size_v<_Tp, SimdAbi> == _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)); + }; +}; + +template +void test_simd_abi() {} +template +void test_simd_abi() { + if constexpr (std::is_same_v || std::is_same_v) { + F{}.template operator()<_Tp, ex::simd_abi::scalar>(); + } else if constexpr (std::is_same_v || std::is_same_v) { + F{}.template operator()<_Tp, ex::simd_abi::deduce_t<_Tp, _Np>, _Np>(); + } else if constexpr (std::is_same_v || std::is_same_v) { + F{}.template operator()<_Tp, ex::simd_abi::fixed_size<_Np>, _Np>(); + } else if constexpr (std::is_same_v || std::is_same_v) { + F{}.template operator()<_Tp, ex::simd_abi::compatible<_Tp>>(); + } else { + F{}.template operator()<_Tp, ex::simd_abi::native<_Tp>>(); + } + test_simd_abi(); +} + +int main(int, char**) { + test_all_simd_abi(); + test_all_simd_abi(); + + test_all_simd_abi(); + test_all_simd_abi(); + + test_all_simd_abi(); + test_all_simd_abi(); + + test_all_simd_abi(); + test_all_simd_abi(); + + test_all_simd_abi(); + test_all_simd_abi(); + + return 0; +}