]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/experimental/simd/tests/split_concat.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / simd / tests / split_concat.cc
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8 //
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // expensive: * [1-9] * *
19 #include "bits/verify.h"
20 #include "bits/metahelpers.h"
21 #include "bits/conversions.h"
22
23 using std::experimental::simd_cast;
24
25 template <typename V, bool ConstProp, typename F>
26 auto
27 gen(const F& fun)
28 {
29 if constexpr (ConstProp)
30 return V(fun);
31 else
32 return make_value_unknown(V(fun));
33 }
34
35 template <typename V, bool ConstProp>
36 void
37 split_concat()
38 {
39 using T = typename V::value_type;
40 if constexpr (V::size() * 3
41 <= std::experimental::simd_abi::max_fixed_size<T>)
42 {
43 V a(0), b(1), c(2);
44 auto x = concat(a, b, c);
45 COMPARE(x.size(), a.size() * 3);
46 std::size_t i = 0;
47 for (; i < a.size(); ++i)
48 {
49 COMPARE(x[i], T(0));
50 }
51 for (; i < 2 * a.size(); ++i)
52 {
53 COMPARE(x[i], T(1));
54 }
55 for (; i < 3 * a.size(); ++i)
56 {
57 COMPARE(x[i], T(2));
58 }
59 }
60
61 if constexpr (V::size() >= 4)
62 {
63 const V a = gen<V, ConstProp>([](auto i) -> T { return i; });
64 constexpr auto N0 = V::size() / 4u;
65 constexpr auto N1 = V::size() - 2 * N0;
66 using V0 = std::experimental::simd<
67 T, std::experimental::simd_abi::deduce_t<T, N0>>;
68 using V1 = std::experimental::simd<
69 T, std::experimental::simd_abi::deduce_t<T, N1>>;
70 {
71 auto x = std::experimental::split<N0, N0, N1>(a);
72 COMPARE(std::tuple_size<decltype(x)>::value, 3u);
73 COMPARE(std::get<0>(x), V0([](auto i) -> T { return i; }));
74 COMPARE(std::get<1>(x), V0([](auto i) -> T { return i + N0; }));
75 COMPARE(std::get<2>(x), V1([](auto i) -> T { return i + 2 * N0; }));
76 auto b = concat(std::get<1>(x), std::get<2>(x), std::get<0>(x));
77 // a and b may have different types if a was fixed_size<N> such that
78 // another ABI tag exists with equal N, then b will have the
79 // non-fixed-size ABI tag.
80 COMPARE(a.size(), b.size());
81 COMPARE(
82 b, decltype(b)([](auto i) -> T { return (N0 + i) % V::size(); }));
83 }
84 {
85 auto x = std::experimental::split<N0, N1, N0>(a);
86 COMPARE(std::tuple_size<decltype(x)>::value, 3u);
87 COMPARE(std::get<0>(x), V0([](auto i) -> T { return i; }));
88 COMPARE(std::get<1>(x), V1([](auto i) -> T { return i + N0; }));
89 COMPARE(std::get<2>(x), V0([](auto i) -> T { return i + N0 + N1; }));
90 auto b = concat(std::get<1>(x), std::get<2>(x), std::get<0>(x));
91 // a and b may have different types if a was fixed_size<N> such that
92 // another ABI tag exists with equal N, then b will have the
93 // non-fixed-size ABI tag.
94 COMPARE(a.size(), b.size());
95 COMPARE(
96 b, decltype(b)([](auto i) -> T { return (N0 + i) % V::size(); }));
97 }
98 {
99 auto x = std::experimental::split<N1, N0, N0>(a);
100 COMPARE(std::tuple_size<decltype(x)>::value, 3u);
101 COMPARE(std::get<0>(x), V1([](auto i) -> T { return i; }));
102 COMPARE(std::get<1>(x), V0([](auto i) -> T { return i + N1; }));
103 COMPARE(std::get<2>(x), V0([](auto i) -> T { return i + N0 + N1; }));
104 auto b = concat(std::get<1>(x), std::get<2>(x), std::get<0>(x));
105 // a and b may have different types if a was fixed_size<N> such that
106 // another ABI tag exists with equal N, then b will have the
107 // non-fixed-size ABI tag.
108 COMPARE(a.size(), b.size());
109 COMPARE(
110 b, decltype(b)([](auto i) -> T { return (N1 + i) % V::size(); }));
111 }
112 }
113
114 if constexpr (V::size() % 3 == 0)
115 {
116 const V a = gen<V, ConstProp>([](auto i) -> T { return i; });
117 constexpr auto N0 = V::size() / 3;
118 using V0 = std::experimental::simd<
119 T, std::experimental::simd_abi::deduce_t<T, N0>>;
120 using V1 = std::experimental::simd<
121 T, std::experimental::simd_abi::deduce_t<T, 2 * N0>>;
122 {
123 auto [x, y, z] = std::experimental::split<N0, N0, N0>(a);
124 COMPARE(x, V0([](auto i) -> T { return i; }));
125 COMPARE(y, V0([](auto i) -> T { return i + N0; }));
126 COMPARE(z, V0([](auto i) -> T { return i + N0 * 2; }));
127 auto b = concat(x, y, z);
128 COMPARE(a.size(), b.size());
129 COMPARE(b, simd_cast<decltype(b)>(a));
130 COMPARE(simd_cast<V>(b), a);
131 }
132 {
133 auto [x, y] = std::experimental::split<N0, 2 * N0>(a);
134 COMPARE(x, V0([](auto i) -> T { return i; }));
135 COMPARE(y, V1([](auto i) -> T { return i + N0; }));
136 auto b = concat(x, y);
137 COMPARE(a.size(), b.size());
138 COMPARE(b, simd_cast<decltype(b)>(a));
139 COMPARE(simd_cast<V>(b), a);
140 }
141 {
142 auto [x, y] = std::experimental::split<2 * N0, N0>(a);
143 COMPARE(x, V1([](auto i) -> T { return i; }));
144 COMPARE(y, V0([](auto i) -> T { return i + 2 * N0; }));
145 auto b = concat(x, y);
146 COMPARE(a.size(), b.size());
147 COMPARE(b, simd_cast<decltype(b)>(a));
148 COMPARE(simd_cast<V>(b), a);
149 }
150 }
151
152 if constexpr ((V::size() & 1) == 0)
153 {
154 using std::experimental::simd;
155 using std::experimental::simd_abi::deduce_t;
156 using V0 = simd<T, deduce_t<T, V::size()>>;
157 using V2 = simd<T, deduce_t<T, 2>>;
158 using V3 = simd<T, deduce_t<T, V::size() / 2>>;
159
160 const V a = gen<V, ConstProp>([](auto i) -> T { return i; });
161
162 std::array<V2, V::size() / 2> v2s = std::experimental::split<V2>(a);
163 int offset = 0;
164 for (V2 test : v2s)
165 {
166 COMPARE(test, V2([&](auto i) -> T { return i + offset; }));
167 offset += 2;
168 }
169 COMPARE(concat(v2s), simd_cast<V0>(a));
170
171 std::array<V3, 2> v3s = std::experimental::split<V3>(a);
172 COMPARE(v3s[0], V3([](auto i) -> T { return i; }));
173 COMPARE(v3s[1], V3([](auto i) -> T { return i + V3::size(); }));
174 COMPARE(concat(v3s), simd_cast<V0>(a));
175 }
176 }
177
178 template <typename V>
179 void
180 test()
181 {
182 split_concat<V, true>();
183 split_concat<V, false>();
184 }