Skip to content

Commit e3c2eac

Browse files
authored
[libc++] <experimental/simd> Add default constructor for class simd/simd_mask (llvm#70424)
1 parent 0a34aae commit e3c2eac

File tree

5 files changed

+237
-0
lines changed

5 files changed

+237
-0
lines changed

libcxx/docs/Status/ParallelismProjects.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ Section,Description,Dependencies,Assignee,Complete
1818
| `[parallel.simd.reference] <https://wg21.link/N4808>`_, "`Element references operator= <https://github.com/llvm/llvm-project/pull/70020>`_", None, Yin Zhang, |Complete|
1919
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`Class template simd declaration and alias <https://reviews.llvm.org/D144362>`_", [parallel.simd.abi], Yin Zhang, |Complete|
2020
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd<>::size() <https://reviews.llvm.org/D144363>`_", [parallel.simd.traits] simd_size[_v], Yin Zhang, |Complete|
21+
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd default constructor <https://github.com/llvm/llvm-project/pull/70424>`_", None, Yin Zhang, |Complete|
2122
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd broadcast constructor <https://reviews.llvm.org/D156225>`_", None, Yin Zhang, |Complete|
2223
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd generate constructor <https://reviews.llvm.org/D159442>`_", None, Yin Zhang, |Complete|
2324
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "`simd subscript operators <https://github.com/llvm/llvm-project/pull/68960>`_", None, Yin Zhang, |Complete|
2425
| `[parallel.simd.class] <https://wg21.link/N4808>`_, "Class template simd implementation", None, Yin Zhang, |In Progress|
2526
| `[parallel.simd.nonmembers] <https://wg21.link/N4808>`_, "simd non-member operations", None, Yin Zhang, |In Progress|
2627
| `[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|
2728
| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "`simd_mask<>::size() <https://reviews.llvm.org/D144363>`_", [parallel.simd.class] simd<>::size(), Yin Zhang, |Complete|
29+
| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "`simd_mask default constructor <https://github.com/llvm/llvm-project/pull/70424>`_", None, Yin Zhang, |Complete|
2830
| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "`simd_mask broadcast constructor <https://reviews.llvm.org/D156225>`_", None, Yin Zhang, |Complete|
2931
| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "`simd_mask subscript operators <https://github.com/llvm/llvm-project/pull/68960>`_", None, Yin Zhang, |Complete|
3032
| `[parallel.simd.mask.class] <https://wg21.link/N4808>`_, "Class template simd_mask implementation", None, Yin Zhang, |In Progress|

libcxx/include/experimental/__simd/simd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class simd {
4040

4141
static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_size_v<value_type, abi_type>; }
4242

43+
_LIBCPP_HIDE_FROM_ABI simd() noexcept = default;
44+
4345
// broadcast constructor
4446
template <class _Up, enable_if_t<__can_broadcast_v<value_type, __remove_cvref_t<_Up>>, int> = 0>
4547
_LIBCPP_HIDE_FROM_ABI simd(_Up&& __v) noexcept : __s_(_Impl::__broadcast(static_cast<value_type>(__v))) {}

libcxx/include/experimental/__simd/simd_mask.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class simd_mask {
3838

3939
static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_type::size(); }
4040

41+
_LIBCPP_HIDE_FROM_ABI simd_mask() noexcept = default;
42+
4143
// broadcast constructor
4244
_LIBCPP_HIDE_FROM_ABI explicit simd_mask(value_type __v) noexcept : __s_(_Impl::__broadcast(__v)) {}
4345

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14
10+
11+
// <experimental/simd>
12+
//
13+
// [simd.class]
14+
// simd() noexcept = default;
15+
16+
#include "../test_utils.h"
17+
#include <experimental/simd>
18+
19+
namespace ex = std::experimental::parallelism_v2;
20+
21+
// See https://www.open-std.org/jtc1/sc22/WG21/docs/papers/2019/n4808.pdf
22+
// Default intialization performs no initialization of the elements; value-initialization initializes each element with T().
23+
// Thus, default initialization leaves the elements in an indeterminate state.
24+
template <class T, std::size_t>
25+
struct CheckSimdDefaultCtor {
26+
template <class SimdAbi>
27+
void operator()() {
28+
static_assert(std::is_nothrow_default_constructible_v<ex::simd<T, SimdAbi>>);
29+
ex::simd<T, SimdAbi> pure_simd;
30+
// trash value in default ctor
31+
static_assert(pure_simd.size() > 0);
32+
}
33+
};
34+
35+
template <class T, std::size_t>
36+
struct CheckSimdDefaultCopyCtor {
37+
template <class SimdAbi>
38+
void operator()() {
39+
ex::simd<T, SimdAbi> pure_simd([](T i) { return i; });
40+
constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
41+
std::array<T, array_size> expected_value;
42+
for (size_t i = 0; i < array_size; ++i)
43+
expected_value[i] = pure_simd[i];
44+
45+
static_assert(std::is_nothrow_copy_constructible_v<ex::simd<T, SimdAbi>>);
46+
ex::simd<T, SimdAbi> from_copy_ctor(pure_simd);
47+
assert_simd_values_equal<array_size>(from_copy_ctor, expected_value);
48+
}
49+
};
50+
51+
template <class T, std::size_t>
52+
struct CheckSimdDefaultMoveCtor {
53+
template <class SimdAbi>
54+
void operator()() {
55+
ex::simd<T, SimdAbi> pure_simd([](T i) { return i; });
56+
constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
57+
std::array<T, array_size> expected_value;
58+
for (size_t i = 0; i < array_size; ++i)
59+
expected_value[i] = pure_simd[i];
60+
61+
static_assert(std::is_nothrow_move_constructible_v<ex::simd<T, SimdAbi>>);
62+
ex::simd<T, SimdAbi> from_move_ctor(std::move(pure_simd));
63+
assert_simd_values_equal<array_size>(from_move_ctor, expected_value);
64+
}
65+
};
66+
67+
template <class T, std::size_t>
68+
struct CheckSimdDefaultCopyAssignment {
69+
template <class SimdAbi>
70+
void operator()() {
71+
ex::simd<T, SimdAbi> pure_simd([](T i) { return i; });
72+
constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
73+
std::array<T, array_size> expected_value;
74+
for (size_t i = 0; i < array_size; ++i)
75+
expected_value[i] = pure_simd[i];
76+
77+
static_assert(std::is_nothrow_copy_assignable_v<ex::simd<T, SimdAbi>>);
78+
ex::simd<T, SimdAbi> from_copy_assignment;
79+
from_copy_assignment = pure_simd;
80+
assert_simd_values_equal<array_size>(from_copy_assignment, expected_value);
81+
}
82+
};
83+
84+
template <class T, std::size_t>
85+
struct CheckSimdDefaultMoveAssignment {
86+
template <class SimdAbi>
87+
void operator()() {
88+
ex::simd<T, SimdAbi> pure_simd([](T i) { return i; });
89+
constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
90+
std::array<T, array_size> expected_value;
91+
for (size_t i = 0; i < array_size; ++i)
92+
expected_value[i] = pure_simd[i];
93+
94+
static_assert(std::is_nothrow_move_assignable_v<ex::simd<T, SimdAbi>>);
95+
ex::simd<T, SimdAbi> from_move_assignment;
96+
from_move_assignment = std::move(pure_simd);
97+
assert_simd_values_equal<array_size>(from_move_assignment, expected_value);
98+
}
99+
};
100+
101+
int main(int, char**) {
102+
test_all_simd_abi<CheckSimdDefaultCtor>();
103+
test_all_simd_abi<CheckSimdDefaultCopyCtor>();
104+
test_all_simd_abi<CheckSimdDefaultMoveCtor>();
105+
test_all_simd_abi<CheckSimdDefaultCopyAssignment>();
106+
test_all_simd_abi<CheckSimdDefaultMoveAssignment>();
107+
return 0;
108+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14
10+
11+
// <experimental/simd>
12+
//
13+
// [simd.mask.class]
14+
// simd_mask() noexcept = default;
15+
16+
#include "../test_utils.h"
17+
#include <experimental/simd>
18+
19+
namespace ex = std::experimental::parallelism_v2;
20+
21+
// See https://www.open-std.org/jtc1/sc22/WG21/docs/papers/2019/n4808.pdf
22+
// Default intialization performs no initialization of the elements; value-initialization initializes each element with T().
23+
// Thus, default initialization leaves the elements in an indeterminate state.
24+
template <class T, std::size_t>
25+
struct CheckSimdMaskDefaultCtor {
26+
template <class SimdAbi>
27+
void operator()() {
28+
ex::simd_mask<T, SimdAbi> pure_mask;
29+
// trash value in default ctor
30+
static_assert(pure_mask.size() > 0);
31+
}
32+
};
33+
34+
template <class T, std::size_t>
35+
struct CheckSimdMaskDefaultCopyCtor {
36+
template <class SimdAbi>
37+
void operator()() {
38+
ex::simd_mask<T, SimdAbi> pure_mask;
39+
constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
40+
std::array<bool, array_size> expected_value;
41+
for (size_t i = 0; i < array_size; ++i) {
42+
if (i % 2 == 0)
43+
pure_mask[i] = true;
44+
else
45+
pure_mask[i] = false;
46+
expected_value[i] = pure_mask[i];
47+
}
48+
49+
ex::simd_mask<T, SimdAbi> from_copy_ctor(pure_mask);
50+
assert_simd_mask_values_equal<array_size>(from_copy_ctor, expected_value);
51+
}
52+
};
53+
54+
template <class T, std::size_t>
55+
struct CheckSimdMaskDefaultMoveCtor {
56+
template <class SimdAbi>
57+
void operator()() {
58+
ex::simd_mask<T, SimdAbi> pure_mask;
59+
constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
60+
std::array<bool, array_size> expected_value;
61+
for (size_t i = 0; i < array_size; ++i) {
62+
if (i % 2 == 0)
63+
pure_mask[i] = true;
64+
else
65+
pure_mask[i] = false;
66+
expected_value[i] = pure_mask[i];
67+
}
68+
69+
ex::simd_mask<T, SimdAbi> from_move_ctor(std::move(pure_mask));
70+
assert_simd_mask_values_equal<array_size>(from_move_ctor, expected_value);
71+
}
72+
};
73+
74+
template <class T, std::size_t>
75+
struct CheckSimdMaskDefaultCopyAssignment {
76+
template <class SimdAbi>
77+
void operator()() {
78+
ex::simd_mask<T, SimdAbi> pure_mask;
79+
constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
80+
std::array<bool, array_size> expected_value;
81+
for (size_t i = 0; i < array_size; ++i) {
82+
if (i % 2 == 0)
83+
pure_mask[i] = true;
84+
else
85+
pure_mask[i] = false;
86+
expected_value[i] = pure_mask[i];
87+
}
88+
89+
ex::simd_mask<T, SimdAbi> from_copy_assignment;
90+
from_copy_assignment = pure_mask;
91+
assert_simd_mask_values_equal<array_size>(from_copy_assignment, expected_value);
92+
}
93+
};
94+
95+
template <class T, std::size_t>
96+
struct CheckSimdMaskDefaultMoveAssignment {
97+
template <class SimdAbi>
98+
void operator()() {
99+
ex::simd_mask<T, SimdAbi> pure_mask;
100+
constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;
101+
std::array<bool, array_size> expected_value;
102+
for (size_t i = 0; i < array_size; ++i) {
103+
if (i % 2 == 0)
104+
pure_mask[i] = true;
105+
else
106+
pure_mask[i] = false;
107+
expected_value[i] = pure_mask[i];
108+
}
109+
110+
ex::simd_mask<T, SimdAbi> from_move_assignment;
111+
from_move_assignment = std::move(pure_mask);
112+
assert_simd_mask_values_equal<array_size>(from_move_assignment, expected_value);
113+
}
114+
};
115+
116+
int main(int, char**) {
117+
test_all_simd_abi<CheckSimdMaskDefaultCtor>();
118+
test_all_simd_abi<CheckSimdMaskDefaultCopyCtor>();
119+
test_all_simd_abi<CheckSimdMaskDefaultMoveCtor>();
120+
test_all_simd_abi<CheckSimdMaskDefaultCopyAssignment>();
121+
test_all_simd_abi<CheckSimdMaskDefaultMoveAssignment>();
122+
return 0;
123+
}

0 commit comments

Comments
 (0)