Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc++] <experimental/simd> Add default constructor for class simd/simd_mask #70424

Merged
merged 1 commit into from
Nov 1, 2023

Conversation

joy2myself
Copy link
Member

@joy2myself joy2myself commented Oct 27, 2023

No description provided.

@joy2myself joy2myself requested a review from a team as a code owner October 27, 2023 07:55
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Oct 27, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Oct 27, 2023

@llvm/pr-subscribers-libcxx

Author: ZhangYin (joy2myself)

Changes

…imd_mask


Full diff: https://github.com/llvm/llvm-project/pull/70424.diff

4 Files Affected:

  • (modified) libcxx/include/experimental/__simd/simd.h (+2)
  • (modified) libcxx/include/experimental/__simd/simd_mask.h (+2)
  • (added) libcxx/test/std/experimental/simd/simd.class/simd_ctor_default.pass.cpp (+108)
  • (added) libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_ctor_default.pass.cpp (+123)
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;
+}

Copy link
Contributor

@philnik777 philnik777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with green CI.

@ldionne ldionne changed the title [libc++] <experimental/simd> Add default constructor for class simd/s… [libc++] <experimental/simd> Add default constructor for class simd/simd_mask Oct 31, 2023
@joy2myself
Copy link
Member Author

It seems the failure of generated files is unrelated. Could this be merged?

@ldionne ldionne merged commit e3c2eac into llvm:main Nov 1, 2023
4 of 5 checks passed
Guzhu-AMD pushed a commit to GPUOpen-Drivers/llvm-project that referenced this pull request Nov 2, 2023
Local branch amd-gfx f98ed7f Merged main:47d9fbc04b91 into amd-gfx:d315d30c5fe7
Remote branch main e3c2eac [libc++] <experimental/simd> Add default constructor for class simd/simd_mask (llvm#70424)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants