[libcxx-commits] [libcxx] ce5652c - [libcxx] <experimental/simd> Added simd width functions, simd_size traits and related tests

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Sep 11 20:42:02 PDT 2023


Author: Zhangyin
Date: 2023-09-12T11:41:42+08:00
New Revision: ce5652c78ac05ec2b407cc754757fa0f139a6370

URL: https://github.com/llvm/llvm-project/commit/ce5652c78ac05ec2b407cc754757fa0f139a6370
DIFF: https://github.com/llvm/llvm-project/commit/ce5652c78ac05ec2b407cc754757fa0f139a6370.diff

LOG: [libcxx] <experimental/simd> Added simd width functions, simd_size traits and related tests

Reviewed By: #libc, philnik

Differential Revision: https://reviews.llvm.org/D144363

Added: 
    libcxx/include/experimental/__simd/declaration.h
    libcxx/include/experimental/__simd/utility.h
    libcxx/test/std/experimental/simd/simd.class/simd_alias.pass.cpp
    libcxx/test/std/experimental/simd/simd.class/simd_width.pass.cpp
    libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_alias.pass.cpp
    libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_width.pass.cpp
    libcxx/test/std/experimental/simd/simd.traits/simd_size.pass.cpp
    libcxx/test/std/experimental/simd/simd.traits/simd_size.verify.cpp

Modified: 
    libcxx/docs/Status/ParallelismProjects.csv
    libcxx/include/CMakeLists.txt
    libcxx/include/experimental/__simd/simd.h
    libcxx/include/experimental/__simd/simd_mask.h
    libcxx/include/experimental/__simd/traits.h
    libcxx/include/experimental/simd
    libcxx/test/std/experimental/simd/test_utils.h

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/ParallelismProjects.csv b/libcxx/docs/Status/ParallelismProjects.csv
index 5b5584647a3a9f4..1c0ee558c9bcf8c 100644
--- a/libcxx/docs/Status/ParallelismProjects.csv
+++ b/libcxx/docs/Status/ParallelismProjects.csv
@@ -8,14 +8,16 @@ Section,Description,Dependencies,Assignee,Complete
 | `[parallel.simd.traits] <https://wg21.link/N4808>`_, "`simd type traits is_simd[_v] <https://reviews.llvm.org/D144362>`_", [parallel.simd.class] declaration and alias, Yin Zhang, |Complete|
 | `[parallel.simd.traits] <https://wg21.link/N4808>`_, "`simd type traits is_simd_mask[_v] <https://reviews.llvm.org/D144362>`_", [parallel.simd.mask.class] declaration and alias, Yin Zhang, |Complete|
 | `[parallel.simd.traits] <https://wg21.link/N4808>`_, "simd type traits is_simd_flag_type", None, Yin Zhang, |In Progress|
-| `[parallel.simd.traits] <https://wg21.link/N4808>`_, "simd type traits simd_size", None, Yin Zhang, |In Progress|
+| `[parallel.simd.traits] <https://wg21.link/N4808>`_, "`simd type traits simd_size[_v] <https://reviews.llvm.org/D144363>`_", [parallel.simd.traits] is_abi_tag[_v], Yin Zhang, |Complete|
 | `[parallel.simd.traits] <https://wg21.link/N4808>`_, "simd type traits memory_alignment", None, Yin Zhang, |In Progress|
 | `[parallel.simd.traits] <https://wg21.link/N4808>`_, "simd type traits rebind_simd", None, Yin Zhang, |In Progress|
 | `[parallel.simd.traits] <https://wg21.link/N4808>`_, "simd type traits resize_simd", None, Yin Zhang, |In Progress|
 | `[parallel.simd.whereexpr] <https://wg21.link/N4808>`_, "Where expression class templates", None, Yin Zhang, |In Progress|
 | `[parallel.simd.class] <https://wg21.link/N4808>`_, "`Class template simd declaration and alias <https://reviews.llvm.org/D144362>`_", [parallel.simd.abi], Yin Zhang, |Complete|
+| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd<>::size() <https://reviews.llvm.org/D144363>`_", [parallel.simd.traits] simd_size[_v], Yin Zhang, |Complete|
 | `[parallel.simd.class] <https://wg21.link/N4808>`_, "Class template simd implementation", None, Yin Zhang, |In Progress|
 | `[parallel.simd.nonmembers] <https://wg21.link/N4808>`_, "simd non-member operations", None, Yin Zhang, |In Progress|
 | `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "`Class template simd_mask declaration and alias <https://reviews.llvm.org/D144362>`_", [parallel.simd.abi], Yin Zhang, |Complete|
+| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "`simd_mask<>::size() <https://reviews.llvm.org/D144363>`_", [parallel.simd.class] simd<>::size(), Yin Zhang, |Complete|
 | `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "Class template simd_mask implementation", None, Yin Zhang, |In Progress|
 | `[parallel.simd.mask.nonmembers] <https://wg21.link/N4808>`_, "simd_mask non-member operations", None, Yin Zhang, |In Progress|

diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index e9bb73d66b1024a..e2088c7cbdec2af 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -904,10 +904,12 @@ set(files
   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/declaration.h b/libcxx/include/experimental/__simd/declaration.h
new file mode 100644
index 000000000000000..747f87be63e535b
--- /dev/null
+++ b/libcxx/include/experimental/__simd/declaration.h
@@ -0,0 +1,28 @@
+// -*- 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_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 {
+
+template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
+class simd;
+
+template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
+class simd_mask;
+
+} // namespace parallelism_v2
+_LIBCPP_END_NAMESPACE_EXPERIMENTAL
+
+#endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
+#endif // _LIBCPP_EXPERIMENTAL___SIMD_DECLARATION_H

diff  --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/simd.h
index 2c38c7c6fc63548..5bbc3e6993a57a2 100644
--- 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 <experimental/__simd/abi_tag.h>
+#include <experimental/__simd/declaration.h>
+#include <experimental/__simd/traits.h>
 
 #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
 
@@ -19,8 +21,15 @@ inline namespace parallelism_v2 {
 
 // class template simd [simd.class]
 // TODO: implement simd class
-template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
-class simd;
+template <class _Tp, class _Abi>
+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<value_type, abi_type>; }
+};
 
 template <class _Tp>
 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
index fae40b93f35e68f..4ef585f64d54abd 100644
--- 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 <experimental/__simd/abi_tag.h>
+#include <experimental/__simd/declaration.h>
 
 #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
 
@@ -19,8 +20,15 @@ inline namespace parallelism_v2 {
 
 // class template simd_mask [simd.mask.class]
 // TODO: implement simd_mask class
-template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
-class simd_mask;
+template <class _Tp, class _Abi>
+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 <class _Tp>
 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
index 475946c138ee95b..907da33c9f15e86 100644
--- 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 <experimental/__simd/abi_tag.h>
-#include <experimental/__simd/simd.h>
-#include <experimental/__simd/simd_mask.h>
+#include <experimental/__simd/declaration.h>
+#include <experimental/__simd/utility.h>
 
 #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
 
@@ -50,6 +50,15 @@ inline constexpr bool is_simd_mask_v<simd_mask<_Tp, _Abi>> = true;
 template <class _Tp>
 struct is_simd_mask : bool_constant<is_simd_mask_v<_Tp>> {};
 
+template <class _Tp, class _Abi = simd_abi::compatible<_Tp>, bool = (__is_vectorizable_v<_Tp> && is_abi_tag_v<_Abi>)>
+struct simd_size : integral_constant<size_t, _Abi::__simd_size> {};
+
+template <class _Tp, class _Abi>
+struct simd_size<_Tp, _Abi, false> {};
+
+template <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
+inline constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value;
+
 } // namespace parallelism_v2
 _LIBCPP_END_NAMESPACE_EXPERIMENTAL
 

diff  --git a/libcxx/include/experimental/__simd/utility.h b/libcxx/include/experimental/__simd/utility.h
new file mode 100644
index 000000000000000..2f77fda49cf57f7
--- /dev/null
+++ b/libcxx/include/experimental/__simd/utility.h
@@ -0,0 +1,29 @@
+// -*- 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_UTILITY_H
+#define _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H
+
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_volatile.h>
+
+#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
+
+_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
+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>;
+} // namespace parallelism_v2
+_LIBCPP_END_NAMESPACE_EXPERIMENTAL
+
+#endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
+#endif // _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H

diff  --git a/libcxx/include/experimental/simd b/libcxx/include/experimental/simd
index 59f212dce88d0da..e82eb380c05613b 100644
--- a/libcxx/include/experimental/simd
+++ b/libcxx/include/experimental/simd
@@ -47,6 +47,10 @@ inline namespace parallelism_v2 {
   template <class T> struct is_simd_mask;
   template <class T> inline constexpr bool is_simd_mask_v = is_simd_mask<T>::value;
 
+  template<class T, class Abi = simd_abi::compatible<T>> struct simd_size;
+  template<class T, class Abi = simd_abi::compatible<T>>
+    inline constexpr size_t simd_size_v = simd_size<T,Abi>::value;
+
 } // namespace parallelism_v2
 } // namespace std::experimental
 

diff  --git a/libcxx/test/std/experimental/simd/simd.class/simd_alias.pass.cpp b/libcxx/test/std/experimental/simd/simd.class/simd_alias.pass.cpp
new file mode 100644
index 000000000000000..8fb47aa54b68ead
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.class/simd_alias.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+// template <class T, class Abi> class simd {
+// public:
+//   using value_type = T;
+//   using mask_type = simd_mask<T, Abi>;
+//   using abi_type = Abi;
+// };
+
+#include "../test_utils.h"
+#include <experimental/simd>
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <class T, std::size_t>
+struct CheckSimdAlias {
+  template <class SimdAbi>
+  void operator()() {
+    static_assert(std::is_same_v<typename ex::simd<T, SimdAbi>::value_type, T>);
+    static_assert(std::is_same_v<typename ex::simd<T, SimdAbi>::mask_type, ex::simd_mask<T, SimdAbi>>);
+    static_assert(std::is_same_v<typename ex::simd<T, SimdAbi>::abi_type, SimdAbi>);
+  }
+};
+
+int main(int, char**) {
+  test_all_simd_abi<CheckSimdAlias>();
+  return 0;
+}

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
index 000000000000000..1d03666da9f0937
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.class/simd_width.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/simd>
+//
+// [simd.class]
+// static constexpr std::size_t size() noexcept;
+
+#include "../test_utils.h"
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <class T, std::size_t>
+struct CheckSimdWidth {
+  template <class SimdAbi>
+  void operator()() {
+    static_assert(ex::simd<T, SimdAbi>::size() == ex::simd_size_v<T, SimdAbi>);
+  }
+};
+
+int main(int, char**) {
+  test_all_simd_abi<CheckSimdWidth>();
+  return 0;
+}

diff  --git a/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_alias.pass.cpp b/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_alias.pass.cpp
new file mode 100644
index 000000000000000..963376585e53c59
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_alias.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+// template <class T, class Abi> class simd_mask {
+// public:
+//   using value_type = bool;
+//   using simd_type = simd<T, Abi>;
+//   using abi_type = Abi;
+// };
+
+#include "../test_utils.h"
+#include <experimental/simd>
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <class T, std::size_t>
+struct CheckSimdMaskAlias {
+  template <class SimdAbi>
+  void operator()() {
+    static_assert(std::is_same_v<typename ex::simd_mask<T, SimdAbi>::value_type, bool>);
+    static_assert(std::is_same_v<typename ex::simd_mask<T, SimdAbi>::simd_type, ex::simd<T, SimdAbi>>);
+    static_assert(std::is_same_v<typename ex::simd_mask<T, SimdAbi>::abi_type, SimdAbi>);
+  }
+};
+
+int main(int, char**) {
+  test_all_simd_abi<CheckSimdMaskAlias>();
+  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
index 000000000000000..c3df207e19c9521
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_width.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/simd>
+//
+// [simd.mask.class]
+// static constexpr std::size_t size() noexcept;
+
+#include "../test_utils.h"
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <class T, std::size_t>
+struct CheckSimdMaskWidth {
+  template <class SimdAbi>
+  void operator()() {
+    static_assert(ex::simd_mask<T, SimdAbi>::size() == ex::simd_size_v<T, SimdAbi>);
+  }
+};
+
+int main(int, char**) {
+  test_all_simd_abi<CheckSimdMaskWidth>();
+  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
index 000000000000000..bc14eb7611a9fd6
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.traits/simd_size.pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/simd>
+//
+// [simd.traits]
+//template <class T, class Abi = simd_abi::compatible<T>> struct simd_size;
+//template <class T, class Abi = simd_abi::compatible<T>>
+//inline constexpr std::size_t ex::simd_size_v = ex::simd_size<T, Abi>::value;
+
+#include "../test_utils.h"
+
+namespace ex = std::experimental::parallelism_v2;
+
+struct CheckSimdSizeFixedDeduce {
+  template <class T, std::size_t N>
+  void check() {
+    static_assert(ex::simd_size_v<T, ex::simd_abi::fixed_size<N>> == N, "Simd size mismatch with abi fixed_size");
+    static_assert(ex::simd_size<T, ex::simd_abi::fixed_size<N>>::value == N, "Simd size mismatch with abi fixed_size");
+
+    static_assert(ex::simd_size_v<T, ex::simd_abi::deduce_t<T, N>> == N, "Simd size mismatch with abi deduce");
+    static_assert(ex::simd_size<T, ex::simd_abi::deduce_t<T, N>>::value == N, "Simd size mismatch with abi deduce");
+  }
+
+  template <class T, std::size_t... N>
+  void performChecks(std::index_sequence<N...>) {
+    (check<T, N + 1>(), ...);
+  }
+
+  template <class T>
+  void operator()() {
+    performChecks<T>(std::make_index_sequence<max_simd_size>{});
+  }
+};
+
+struct CheckSimdSizeScalarNativeCompatible {
+  template <class T>
+  void operator()() {
+    static_assert(ex::simd_size_v<T, ex::simd_abi::scalar> == 1);
+    static_assert(ex::simd_size<T, ex::simd_abi::scalar>::value == 1);
+
+    LIBCPP_STATIC_ASSERT(ex::simd_size<T, ex::simd_abi::compatible<T>>::value == 16 / sizeof(T));
+    LIBCPP_STATIC_ASSERT(ex::simd_size_v<T, ex::simd_abi::compatible<T>> == 16 / sizeof(T));
+
+    LIBCPP_STATIC_ASSERT(
+        ex::simd_size<T, ex::simd_abi::native<T>>::value == _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(T));
+    LIBCPP_STATIC_ASSERT(ex::simd_size_v<T, ex::simd_abi::native<T>> == _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(T));
+  }
+};
+
+template <class T, class Abi = ex::simd_abi::compatible<T>, class = void>
+struct has_simd_size : std::false_type {};
+
+template <class T, class Abi>
+struct has_simd_size<T, Abi, std::void_t<decltype(ex::simd_size<T, Abi>::value)>> : std::true_type {};
+
+struct CheckSimdSizeTraits {
+  template <class T>
+  void operator()() {
+    static_assert(has_simd_size<T>::value);
+    static_assert(!has_simd_size<ex::native_simd<T>>::value);
+
+    static_assert(has_simd_size<T, ex::simd_abi::scalar>::value);
+    static_assert(has_simd_size<T, ex::simd_abi::fixed_size<4>>::value);
+    static_assert(has_simd_size<T, ex::simd_abi::native<T>>::value);
+    static_assert(has_simd_size<T, ex::simd_abi::compatible<T>>::value);
+
+    static_assert(!has_simd_size<ex::simd_abi::native<T>, ex::simd_abi::native<T>>::value);
+    static_assert(!has_simd_size<ex::native_simd<T>, ex::simd_abi::native<T>>::value);
+    static_assert(!has_simd_size<ex::fixed_size_simd<T, 3>, ex::simd_abi::native<T>>::value);
+    static_assert(!has_simd_size<ex::fixed_size_simd_mask<T, 4>, ex::simd_abi::native<T>>::value);
+
+    static_assert(!has_simd_size<T, T>::value);
+    static_assert(!has_simd_size<T, ex::native_simd<T>>::value);
+    static_assert(!has_simd_size<T, ex::fixed_size_simd<T, 3>>::value);
+    static_assert(!has_simd_size<T, ex::fixed_size_simd_mask<T, 4>>::value);
+  }
+};
+
+int main(int, char**) {
+  types::for_each(arithmetic_no_bool_types(), CheckSimdSizeFixedDeduce());
+  types::for_each(arithmetic_no_bool_types(), CheckSimdSizeScalarNativeCompatible());
+  types::for_each(arithmetic_no_bool_types(), CheckSimdSizeTraits());
+  return 0;
+}

diff  --git a/libcxx/test/std/experimental/simd/simd.traits/simd_size.verify.cpp b/libcxx/test/std/experimental/simd/simd.traits/simd_size.verify.cpp
new file mode 100644
index 000000000000000..16bbf9aea32f880
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.traits/simd_size.verify.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <experimental/simd>
+//
+// [simd.traits]
+//template <class T, class Abi = simd_abi::compatible<T>> struct simd_size;
+//template <class T, class Abi = simd_abi::compatible<T>>
+//inline constexpr std::size_t ex::simd_size_v = ex::simd_size<T, Abi>::value;
+
+#include <experimental/simd>
+
+namespace ex = std::experimental::parallelism_v2;
+
+int main(int, char**) {
+  (void)ex::simd_size<bool, ex::simd_abi::compatible<bool>>::value;
+  // expected-error-re@* {{no member named 'value' in {{.*}}}}
+  (void)ex::simd_size<ex::native_simd<int>, ex::simd_abi::native<int>>::value;
+  // expected-error-re@* {{no member named 'value' in {{.*}}}}
+  (void)ex::simd_size<int, int>::value;
+  // expected-error-re@* {{no member named 'value' in {{.*}}}}
+  (void)ex::simd_size<int, ex::native_simd<int>>::value;
+  // expected-error-re@* {{no member named 'value' in {{.*}}}}
+
+  (void)ex::simd_size_v<bool, ex::simd_abi::compatible<bool>>;
+  // expected-error-re@* {{no member named 'value' in {{.*}}}}
+  (void)ex::simd_size_v<ex::native_simd<int>, ex::simd_abi::native<int>>;
+  // expected-error-re@* {{no member named 'value' in {{.*}}}}
+  (void)ex::simd_size_v<int, int>;
+  // expected-error-re@* {{no member named 'value' in {{.*}}}}
+  (void)ex::simd_size_v<int, ex::native_simd<int>>;
+  // expected-error-re@* {{no member named 'value' in {{.*}}}}
+
+  return 0;
+}

diff  --git a/libcxx/test/std/experimental/simd/test_utils.h b/libcxx/test/std/experimental/simd/test_utils.h
index 11a678b76637c92..0116412e8a6294a 100644
--- a/libcxx/test/std/experimental/simd/test_utils.h
+++ b/libcxx/test/std/experimental/simd/test_utils.h
@@ -36,9 +36,10 @@ struct TestAllSimdAbiFunctor {
   }
 };
 
+using arithmetic_no_bool_types = types::concatenate_t<types::integer_types, types::floating_point_types>;
+
 template <template <class T, std::size_t N> class Func>
 void test_all_simd_abi() {
-  using arithmetic_no_bool_types = types::concatenate_t<types::integer_types, types::floating_point_types>;
   types::for_each(arithmetic_no_bool_types(), TestAllSimdAbiFunctor<Func>());
 }
 


        


More information about the libcxx-commits mailing list