[libcxx-commits] [libcxx] [libc++] <experimental/simd> Add default constructor for class simd/s… (PR #70424)

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Oct 27 00:55:38 PDT 2023


https://github.com/joy2myself created https://github.com/llvm/llvm-project/pull/70424

…imd_mask

>From a11ea8349ff8ce189f0bf2303300aa605c501a73 Mon Sep 17 00:00:00 2001
From: Yin Zhang <zhangyin2018 at iscas.ac.cn>
Date: Sun, 8 Oct 2023 16:13:20 +0800
Subject: [PATCH] [libc++] <experimental/simd> Add default constructor for
 class simd/simd_mask

---
 libcxx/include/experimental/__simd/simd.h     |   2 +
 .../include/experimental/__simd/simd_mask.h   |   2 +
 .../simd.class/simd_ctor_default.pass.cpp     | 108 +++++++++++++++
 .../simd_mask_ctor_default.pass.cpp           | 123 ++++++++++++++++++
 4 files changed, 235 insertions(+)
 create mode 100644 libcxx/test/std/experimental/simd/simd.class/simd_ctor_default.pass.cpp
 create mode 100644 libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_ctor_default.pass.cpp

diff --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/simd.h
index c71dd625e46c61e..d4a6f238a536802 100644
--- a/libcxx/include/experimental/__simd/simd.h
+++ b/libcxx/include/experimental/__simd/simd.h
@@ -40,6 +40,8 @@ class simd {
 
   static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_size_v<value_type, abi_type>; }
 
+  simd() noexcept = default;
+
   // broadcast constructor
   template <class _Up, enable_if_t<__can_broadcast_v<value_type, __remove_cvref_t<_Up>>, int> = 0>
   _LIBCPP_HIDE_FROM_ABI simd(_Up&& __v) noexcept : __s_(_Impl::__broadcast(static_cast<value_type>(__v))) {}
diff --git a/libcxx/include/experimental/__simd/simd_mask.h b/libcxx/include/experimental/__simd/simd_mask.h
index 946338542ca0dda..f78a4ab5099a59a 100644
--- a/libcxx/include/experimental/__simd/simd_mask.h
+++ b/libcxx/include/experimental/__simd/simd_mask.h
@@ -38,6 +38,8 @@ class simd_mask {
 
   static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_type::size(); }
 
+  simd_mask() noexcept = default;
+
   // broadcast constructor
   _LIBCPP_HIDE_FROM_ABI explicit simd_mask(value_type __v) noexcept : __s_(_Impl::__broadcast(__v)) {}
 
diff --git a/libcxx/test/std/experimental/simd/simd.class/simd_ctor_default.pass.cpp b/libcxx/test/std/experimental/simd/simd.class/simd_ctor_default.pass.cpp
new file mode 100644
index 000000000000000..359f3c41b2507f9
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.class/simd_ctor_default.pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// 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]
+// simd() noexcept = default;
+
+#include "../test_utils.h"
+#include <experimental/simd>
+
+namespace ex = std::experimental::parallelism_v2;
+
+// See https://www.open-std.org/jtc1/sc22/WG21/docs/papers/2019/n4808.pdf
+// Default intialization performs no initialization of the elements; value-initialization initializes each element with T().
+// [ Note: Thus, default initialization leaves the elements in an indeterminate state. end note ]
+template <class T, std::size_t>
+struct CheckSimdDefaultCtor {
+  template <class SimdAbi>
+  void operator()() {
+    static_assert(std::is_nothrow_default_constructible_v<ex::simd<T, SimdAbi>>);
+    ex::simd<T, SimdAbi> pure_simd;
+    // trash value in default ctor
+    static_assert(pure_simd.size() > 0);
+  }
+};
+
+template <class T, std::size_t>
+struct CheckSimdDefaultCopyCtor {
+  template <class SimdAbi>
+  void operator()() {
+    ex::simd<T, SimdAbi> pure_simd([](T i) { return i; });
+    constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
+    std::array<T, array_size> expected_value;
+    for (size_t i = 0; i < array_size; ++i)
+      expected_value[i] = pure_simd[i];
+
+    static_assert(std::is_nothrow_copy_constructible_v<ex::simd<T, SimdAbi>>);
+    ex::simd<T, SimdAbi> from_copy_ctor(pure_simd);
+    assert_simd_values_equal<array_size>(from_copy_ctor, expected_value);
+  }
+};
+
+template <class T, std::size_t>
+struct CheckSimdDefaultMoveCtor {
+  template <class SimdAbi>
+  void operator()() {
+    ex::simd<T, SimdAbi> pure_simd([](T i) { return i; });
+    constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
+    std::array<T, array_size> expected_value;
+    for (size_t i = 0; i < array_size; ++i)
+      expected_value[i] = pure_simd[i];
+
+    static_assert(std::is_nothrow_move_constructible_v<ex::simd<T, SimdAbi>>);
+    ex::simd<T, SimdAbi> from_move_ctor(std::move(pure_simd));
+    assert_simd_values_equal<array_size>(from_move_ctor, expected_value);
+  }
+};
+
+template <class T, std::size_t>
+struct CheckSimdDefaultCopyAssignment {
+  template <class SimdAbi>
+  void operator()() {
+    ex::simd<T, SimdAbi> pure_simd([](T i) { return i; });
+    constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
+    std::array<T, array_size> expected_value;
+    for (size_t i = 0; i < array_size; ++i)
+      expected_value[i] = pure_simd[i];
+
+    static_assert(std::is_nothrow_copy_assignable_v<ex::simd<T, SimdAbi>>);
+    ex::simd<T, SimdAbi> from_copy_assignment;
+    from_copy_assignment = pure_simd;
+    assert_simd_values_equal<array_size>(from_copy_assignment, expected_value);
+  }
+};
+
+template <class T, std::size_t>
+struct CheckSimdDefaultMoveAssignment {
+  template <class SimdAbi>
+  void operator()() {
+    ex::simd<T, SimdAbi> pure_simd([](T i) { return i; });
+    constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
+    std::array<T, array_size> expected_value;
+    for (size_t i = 0; i < array_size; ++i)
+      expected_value[i] = pure_simd[i];
+
+    static_assert(std::is_nothrow_move_assignable_v<ex::simd<T, SimdAbi>>);
+    ex::simd<T, SimdAbi> from_move_assignment;
+    from_move_assignment = std::move(pure_simd);
+    assert_simd_values_equal<array_size>(from_move_assignment, expected_value);
+  }
+};
+
+int main(int, char**) {
+  test_all_simd_abi<CheckSimdDefaultCtor>();
+  test_all_simd_abi<CheckSimdDefaultCopyCtor>();
+  test_all_simd_abi<CheckSimdDefaultMoveCtor>();
+  test_all_simd_abi<CheckSimdDefaultCopyAssignment>();
+  test_all_simd_abi<CheckSimdDefaultMoveAssignment>();
+  return 0;
+}
diff --git a/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_ctor_default.pass.cpp b/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_ctor_default.pass.cpp
new file mode 100644
index 000000000000000..ec0efeaab65155e
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_ctor_default.pass.cpp
@@ -0,0 +1,123 @@
+//===----------------------------------------------------------------------===//
+//
+// 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]
+// simd_mask() noexcept = default;
+
+#include "../test_utils.h"
+#include <experimental/simd>
+
+namespace ex = std::experimental::parallelism_v2;
+
+// See https://www.open-std.org/jtc1/sc22/WG21/docs/papers/2019/n4808.pdf
+// Default intialization performs no initialization of the elements; value-initialization initializes each element with T().
+// [ Note: Thus, default initialization leaves the elements in an indeterminate state. — end note ]
+template <class T, std::size_t>
+struct CheckSimdMaskDefaultCtor {
+  template <class SimdAbi>
+  void operator()() {
+    ex::simd_mask<T, SimdAbi> pure_mask;
+    // trash value in default ctor
+    static_assert(pure_mask.size() > 0);
+  }
+};
+
+template <class T, std::size_t>
+struct CheckSimdMaskDefaultCopyCtor {
+  template <class SimdAbi>
+  void operator()() {
+    ex::simd_mask<T, SimdAbi> pure_mask;
+    constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
+    std::array<bool, array_size> expected_value;
+    for (size_t i = 0; i < array_size; ++i) {
+      if (i % 2 == 0)
+        pure_mask[i] = true;
+      else
+        pure_mask[i] = false;
+      expected_value[i] = pure_mask[i];
+    }
+
+    ex::simd_mask<T, SimdAbi> from_copy_ctor(pure_mask);
+    assert_simd_mask_values_equal<array_size>(from_copy_ctor, expected_value);
+  }
+};
+
+template <class T, std::size_t>
+struct CheckSimdMaskDefaultMoveCtor {
+  template <class SimdAbi>
+  void operator()() {
+    ex::simd_mask<T, SimdAbi> pure_mask;
+    constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
+    std::array<bool, array_size> expected_value;
+    for (size_t i = 0; i < array_size; ++i) {
+      if (i % 2 == 0)
+        pure_mask[i] = true;
+      else
+        pure_mask[i] = false;
+      expected_value[i] = pure_mask[i];
+    }
+
+    ex::simd_mask<T, SimdAbi> from_move_ctor(std::move(pure_mask));
+    assert_simd_mask_values_equal<array_size>(from_move_ctor, expected_value);
+  }
+};
+
+template <class T, std::size_t>
+struct CheckSimdMaskDefaultCopyAssignment {
+  template <class SimdAbi>
+  void operator()() {
+    ex::simd_mask<T, SimdAbi> pure_mask;
+    constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
+    std::array<bool, array_size> expected_value;
+    for (size_t i = 0; i < array_size; ++i) {
+      if (i % 2 == 0)
+        pure_mask[i] = true;
+      else
+        pure_mask[i] = false;
+      expected_value[i] = pure_mask[i];
+    }
+
+    ex::simd_mask<T, SimdAbi> from_copy_assignment;
+    from_copy_assignment = pure_mask;
+    assert_simd_mask_values_equal<array_size>(from_copy_assignment, expected_value);
+  }
+};
+
+template <class T, std::size_t>
+struct CheckSimdMaskDefaultMoveAssignment {
+  template <class SimdAbi>
+  void operator()() {
+    ex::simd_mask<T, SimdAbi> pure_mask;
+    constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
+    std::array<bool, array_size> expected_value;
+    for (size_t i = 0; i < array_size; ++i) {
+      if (i % 2 == 0)
+        pure_mask[i] = true;
+      else
+        pure_mask[i] = false;
+      expected_value[i] = pure_mask[i];
+    }
+
+    ex::simd_mask<T, SimdAbi> from_move_assignment;
+    from_move_assignment = std::move(pure_mask);
+    assert_simd_mask_values_equal<array_size>(from_move_assignment, expected_value);
+  }
+};
+
+int main(int, char**) {
+  test_all_simd_abi<CheckSimdMaskDefaultCtor>();
+  test_all_simd_abi<CheckSimdMaskDefaultCopyCtor>();
+  test_all_simd_abi<CheckSimdMaskDefaultMoveCtor>();
+  test_all_simd_abi<CheckSimdMaskDefaultCopyAssignment>();
+  test_all_simd_abi<CheckSimdMaskDefaultMoveAssignment>();
+  return 0;
+}



More information about the libcxx-commits mailing list