[libcxx-commits] [libcxx] e7a45c6 - [libcxx] <experimental/simd> Added internal storage type, constructors, subscript operators of class simd/simd_mask and related tests
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Sep 11 20:42:05 PDT 2023
Author: Zhangyin
Date: 2023-09-12T11:41:46+08:00
New Revision: e7a45c6d768b755644ce44e095332924009887a3
URL: https://github.com/llvm/llvm-project/commit/e7a45c6d768b755644ce44e095332924009887a3
DIFF: https://github.com/llvm/llvm-project/commit/e7a45c6d768b755644ce44e095332924009887a3.diff
LOG: [libcxx] <experimental/simd> Added internal storage type, constructors, subscript operators of class simd/simd_mask and related tests
[libcxx] <experimental/simd> Added internal storage type for class simd/simd_mask
[libcxx] <experimental/simd> Added all constructors of class simd/simd_mask and related tests
[libcxx] <experimental/simd> Added basic simd reference implementation, subscript operators of class simd/simd_mask and related tests
Reviewed By: #libc, philnik
Differential Revision: https://reviews.llvm.org/D144364
Added:
libcxx/include/experimental/__simd/internal_declaration.h
libcxx/include/experimental/__simd/reference.h
libcxx/test/std/experimental/simd/simd.reference/reference_alias.pass.cpp
Modified:
libcxx/include/CMakeLists.txt
libcxx/include/experimental/__simd/scalar.h
libcxx/include/experimental/__simd/simd.h
libcxx/include/experimental/__simd/simd_mask.h
libcxx/include/experimental/__simd/utility.h
libcxx/include/experimental/__simd/vec_ext.h
libcxx/test/std/experimental/simd/test_utils.h
Removed:
################################################################################
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 0bcbad31d25ae08..7af9b85b974211f 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -906,6 +906,8 @@ set(files
experimental/__simd/abi_tag.h
experimental/__simd/aligned_tag.h
experimental/__simd/declaration.h
+ experimental/__simd/internal_declaration.h
+ experimental/__simd/reference.h
experimental/__simd/scalar.h
experimental/__simd/simd.h
experimental/__simd/simd_mask.h
diff --git a/libcxx/include/experimental/__simd/internal_declaration.h b/libcxx/include/experimental/__simd/internal_declaration.h
new file mode 100644
index 000000000000000..294b54d63bb5d9f
--- /dev/null
+++ b/libcxx/include/experimental/__simd/internal_declaration.h
@@ -0,0 +1,34 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPERIMENTAL___SIMD_INTERNAL_DECLARATION_H
+#define _LIBCPP_EXPERIMENTAL___SIMD_INTERNAL_DECLARATION_H
+
+#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
+
+_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
+inline namespace parallelism_v2 {
+
+template <class _Tp, class _Abi>
+struct __simd_storage;
+
+template <class _Tp, class _Abi>
+struct __mask_storage;
+
+template <class _Tp, class _Abi>
+struct __simd_operations;
+
+template <class _Tp, class _Abi>
+struct __mask_operations;
+
+} // namespace parallelism_v2
+_LIBCPP_END_NAMESPACE_EXPERIMENTAL
+
+#endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
+#endif // _LIBCPP_EXPERIMENTAL___SIMD_INTERNAL_DECLARATION_H
diff --git a/libcxx/include/experimental/__simd/reference.h b/libcxx/include/experimental/__simd/reference.h
new file mode 100644
index 000000000000000..a9c17a230458d61
--- /dev/null
+++ b/libcxx/include/experimental/__simd/reference.h
@@ -0,0 +1,49 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H
+#define _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H
+
+#include <experimental/__simd/utility.h>
+
+#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
+
+_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
+inline namespace parallelism_v2 {
+template <class _Tp, class _Storage, class _Vp>
+class __simd_reference {
+ template <class, class>
+ friend class simd;
+ template <class, class>
+ friend class simd_mask;
+
+ _Storage& __s_;
+ size_t __idx_;
+
+ _LIBCPP_HIDE_FROM_ABI _Vp __get() const { return __s_.__get(__idx_); }
+
+ _LIBCPP_HIDE_FROM_ABI void __set(_Vp __v) {
+ if constexpr (is_same_v<_Vp, bool>)
+ __s_.__set(__idx_, experimental::__set_all_bits<_Tp>(__v));
+ else
+ __s_.__set(__idx_, __v);
+ }
+
+public:
+ using value_type = _Vp;
+
+ __simd_reference() = delete;
+ __simd_reference(const __simd_reference&) = delete;
+};
+
+} // namespace parallelism_v2
+_LIBCPP_END_NAMESPACE_EXPERIMENTAL
+
+#endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
+#endif // _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H
diff --git a/libcxx/include/experimental/__simd/scalar.h b/libcxx/include/experimental/__simd/scalar.h
index d96299e658a0ff2..76bd4d041163a2a 100644
--- a/libcxx/include/experimental/__simd/scalar.h
+++ b/libcxx/include/experimental/__simd/scalar.h
@@ -11,6 +11,7 @@
#define _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H
#include <cstddef>
+#include <experimental/__simd/internal_declaration.h>
#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
@@ -20,8 +21,36 @@ namespace simd_abi {
struct __scalar {
static constexpr size_t __simd_size = 1;
};
-
} // namespace simd_abi
+
+template <class _Tp>
+struct __simd_storage<_Tp, simd_abi::__scalar> {
+ _Tp __data;
+
+ _Tp __get([[maybe_unused]] size_t __idx) const noexcept {
+ _LIBCPP_ASSERT_UNCATEGORIZED(__idx == 0, "Index is out of bounds");
+ return __data;
+ }
+ void __set([[maybe_unused]] size_t __idx, _Tp __v) noexcept {
+ _LIBCPP_ASSERT_UNCATEGORIZED(__idx == 0, "Index is out of bounds");
+ __data = __v;
+ }
+};
+
+template <class _Tp>
+struct __mask_storage<_Tp, simd_abi::__scalar> : __simd_storage<bool, simd_abi::__scalar> {};
+
+template <class _Tp>
+struct __simd_operations<_Tp, simd_abi::__scalar> {
+ using _SimdStorage = __simd_storage<_Tp, simd_abi::__scalar>;
+ using _MaskStorage = __mask_storage<_Tp, simd_abi::__scalar>;
+};
+
+template <class _Tp>
+struct __mask_operations<_Tp, simd_abi::__scalar> {
+ using _MaskStorage = __mask_storage<_Tp, simd_abi::__scalar>;
+};
+
} // namespace parallelism_v2
_LIBCPP_END_NAMESPACE_EXPERIMENTAL
diff --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/simd.h
index 5bbc3e6993a57a2..371e8a65d730a01 100644
--- a/libcxx/include/experimental/__simd/simd.h
+++ b/libcxx/include/experimental/__simd/simd.h
@@ -12,7 +12,10 @@
#include <experimental/__simd/abi_tag.h>
#include <experimental/__simd/declaration.h>
+#include <experimental/__simd/reference.h>
+#include <experimental/__simd/scalar.h>
#include <experimental/__simd/traits.h>
+#include <experimental/__simd/vec_ext.h>
#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
@@ -23,8 +26,14 @@ inline namespace parallelism_v2 {
// TODO: implement simd class
template <class _Tp, class _Abi>
class simd {
+ using _Impl = __simd_operations<_Tp, _Abi>;
+ using _Storage = typename _Impl::_SimdStorage;
+
+ _Storage __s_;
+
public:
using value_type = _Tp;
+ using reference = __simd_reference<_Tp, _Storage, value_type>;
using mask_type = simd_mask<_Tp, _Abi>;
using abi_type = _Abi;
diff --git a/libcxx/include/experimental/__simd/simd_mask.h b/libcxx/include/experimental/__simd/simd_mask.h
index 4ef585f64d54abd..1fe42dca0dfc20f 100644
--- a/libcxx/include/experimental/__simd/simd_mask.h
+++ b/libcxx/include/experimental/__simd/simd_mask.h
@@ -12,6 +12,9 @@
#include <experimental/__simd/abi_tag.h>
#include <experimental/__simd/declaration.h>
+#include <experimental/__simd/reference.h>
+#include <experimental/__simd/scalar.h>
+#include <experimental/__simd/vec_ext.h>
#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
@@ -22,8 +25,14 @@ inline namespace parallelism_v2 {
// TODO: implement simd_mask class
template <class _Tp, class _Abi>
class simd_mask {
+ using _Impl = __mask_operations<_Tp, _Abi>;
+ using _Storage = typename _Impl::_MaskStorage;
+
+ _Storage __s_;
+
public:
using value_type = bool;
+ using reference = __simd_reference<_Tp, _Storage, value_type>;
using simd_type = simd<_Tp, _Abi>;
using abi_type = _Abi;
diff --git a/libcxx/include/experimental/__simd/utility.h b/libcxx/include/experimental/__simd/utility.h
index 9f1948bfd1a405c..7676ff240f6a7ab 100644
--- a/libcxx/include/experimental/__simd/utility.h
+++ b/libcxx/include/experimental/__simd/utility.h
@@ -15,6 +15,11 @@
#include <__type_traits/is_constant_evaluated.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_volatile.h>
+#include <cstdint>
+#include <limits>
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
@@ -23,8 +28,37 @@ inline namespace parallelism_v2 {
template <class _Tp>
constexpr bool __is_vectorizable_v =
is_arithmetic_v<_Tp> && !is_const_v<_Tp> && !is_volatile_v<_Tp> && !is_same_v<_Tp, bool>;
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI auto __choose_mask_type() {
+ if constexpr (sizeof(_Tp) == 1) {
+ return uint8_t{};
+ } else if constexpr (sizeof(_Tp) == 2) {
+ return uint16_t{};
+ } else if constexpr (sizeof(_Tp) == 4) {
+ return uint32_t{};
+ } else if constexpr (sizeof(_Tp) == 8) {
+ return uint64_t{};
+ }
+# ifndef _LIBCPP_HAS_NO_INT128
+ else if constexpr (sizeof(_Tp) == 16) {
+ return __uint128_t{};
+ }
+# endif
+ else
+ static_assert(sizeof(_Tp) == 0, "Unexpected size");
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI auto constexpr __set_all_bits(bool __v) {
+ return __v ? (numeric_limits<decltype(__choose_mask_type<_Tp>())>::max()) : 0;
+}
+
} // namespace parallelism_v2
_LIBCPP_END_NAMESPACE_EXPERIMENTAL
#endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
+
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H
diff --git a/libcxx/include/experimental/__simd/vec_ext.h b/libcxx/include/experimental/__simd/vec_ext.h
index 4ece1dc2cda7983..c50f49252124e21 100644
--- a/libcxx/include/experimental/__simd/vec_ext.h
+++ b/libcxx/include/experimental/__simd/vec_ext.h
@@ -10,7 +10,10 @@
#ifndef _LIBCPP_EXPERIMENTAL___SIMD_VEC_EXT_H
#define _LIBCPP_EXPERIMENTAL___SIMD_VEC_EXT_H
+#include <__bit/bit_ceil.h>
#include <cstddef>
+#include <experimental/__simd/internal_declaration.h>
+#include <experimental/__simd/utility.h>
#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
@@ -21,8 +24,37 @@ template <int _Np>
struct __vec_ext {
static constexpr size_t __simd_size = _Np;
};
-
} // namespace simd_abi
+
+template <class _Tp, int _Np>
+struct __simd_storage<_Tp, simd_abi::__vec_ext<_Np>> {
+ _Tp __data __attribute__((__vector_size__(std::__bit_ceil((sizeof(_Tp) * _Np)))));
+
+ _Tp __get(size_t __idx) const noexcept {
+ _LIBCPP_ASSERT_UNCATEGORIZED(__idx > 0 && __idx <= _Np, "Index is out of bounds");
+ return __data[__idx];
+ }
+ void __set(size_t __idx, _Tp __v) noexcept {
+ _LIBCPP_ASSERT_UNCATEGORIZED(__idx > 0 && __idx <= _Np, "Index is out of bounds");
+ __data[__idx] = __v;
+ }
+};
+
+template <class _Tp, int _Np>
+struct __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>
+ : __simd_storage<decltype(experimental::__choose_mask_type<_Tp>()), simd_abi::__vec_ext<_Np>> {};
+
+template <class _Tp, int _Np>
+struct __simd_operations<_Tp, simd_abi::__vec_ext<_Np>> {
+ using _SimdStorage = __simd_storage<_Tp, simd_abi::__vec_ext<_Np>>;
+ using _MaskStorage = __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>;
+};
+
+template <class _Tp, int _Np>
+struct __mask_operations<_Tp, simd_abi::__vec_ext<_Np>> {
+ using _MaskStorage = __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>;
+};
+
} // namespace parallelism_v2
_LIBCPP_END_NAMESPACE_EXPERIMENTAL
diff --git a/libcxx/test/std/experimental/simd/simd.reference/reference_alias.pass.cpp b/libcxx/test/std/experimental/simd/simd.reference/reference_alias.pass.cpp
new file mode 100644
index 000000000000000..31e6319032d2080
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.reference/reference_alias.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test the alias.
+// simd::reference::value_type
+// simd_mask::reference::value_type
+
+#include "../test_utils.h"
+#include <experimental/simd>
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <class T, std::size_t>
+struct CheckRefAlias {
+ template <class SimdAbi>
+ void operator()() {
+ static_assert(std::is_same_v<typename ex::simd<T, SimdAbi>::reference::value_type, T>);
+ static_assert(std::is_same_v<typename ex::simd_mask<T, SimdAbi>::reference::value_type, bool>);
+ }
+};
+
+int main(int, char**) {
+ test_all_simd_abi<CheckRefAlias>();
+ return 0;
+}
diff --git a/libcxx/test/std/experimental/simd/test_utils.h b/libcxx/test/std/experimental/simd/test_utils.h
index 003d7153122673b..6b9fa146b5364c1 100644
--- a/libcxx/test/std/experimental/simd/test_utils.h
+++ b/libcxx/test/std/experimental/simd/test_utils.h
@@ -36,7 +36,12 @@ struct TestAllSimdAbiFunctor {
}
};
+// TODO: Support long double (12 bytes) for MinGW (DLL, i686)
+#ifdef __MINGW32__
+using arithmetic_no_bool_types = types::concatenate_t<types::integer_types, types::type_list<float, double>>;
+#else
using arithmetic_no_bool_types = types::concatenate_t<types::integer_types, types::floating_point_types>;
+#endif
template <template <class T, std::size_t N> class Func>
void test_all_simd_abi() {
More information about the libcxx-commits
mailing list