]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/experimental/simd/tests/split_concat.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / simd / tests / split_concat.cc
CommitLineData
a945c346 1// Copyright (C) 2020-2024 Free Software Foundation, Inc.
02e32295
MK
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
aa89c53c 18// expensive: * [1-9] * *
073df3e7 19#include "bits/main.h"
02e32295
MK
20
21using std::experimental::simd_cast;
22
23template <typename V, bool ConstProp, typename F>
24 auto
25 gen(const F& fun)
26 {
27 if constexpr (ConstProp)
28 return V(fun);
29 else
30 return make_value_unknown(V(fun));
31 }
32
33template <typename V, bool ConstProp>
34 void
35 split_concat()
36 {
37 using T = typename V::value_type;
38 if constexpr (V::size() * 3
39 <= std::experimental::simd_abi::max_fixed_size<T>)
40 {
41 V a(0), b(1), c(2);
42 auto x = concat(a, b, c);
43 COMPARE(x.size(), a.size() * 3);
44 std::size_t i = 0;
45 for (; i < a.size(); ++i)
46 {
47 COMPARE(x[i], T(0));
48 }
49 for (; i < 2 * a.size(); ++i)
50 {
51 COMPARE(x[i], T(1));
52 }
53 for (; i < 3 * a.size(); ++i)
54 {
55 COMPARE(x[i], T(2));
56 }
57 }
58
59 if constexpr (V::size() >= 4)
60 {
61 const V a = gen<V, ConstProp>([](auto i) -> T { return i; });
62 constexpr auto N0 = V::size() / 4u;
63 constexpr auto N1 = V::size() - 2 * N0;
64 using V0 = std::experimental::simd<
65 T, std::experimental::simd_abi::deduce_t<T, N0>>;
66 using V1 = std::experimental::simd<
67 T, std::experimental::simd_abi::deduce_t<T, N1>>;
68 {
69 auto x = std::experimental::split<N0, N0, N1>(a);
70 COMPARE(std::tuple_size<decltype(x)>::value, 3u);
71 COMPARE(std::get<0>(x), V0([](auto i) -> T { return i; }));
72 COMPARE(std::get<1>(x), V0([](auto i) -> T { return i + N0; }));
73 COMPARE(std::get<2>(x), V1([](auto i) -> T { return i + 2 * N0; }));
74 auto b = concat(std::get<1>(x), std::get<2>(x), std::get<0>(x));
75 // a and b may have different types if a was fixed_size<N> such that
76 // another ABI tag exists with equal N, then b will have the
77 // non-fixed-size ABI tag.
78 COMPARE(a.size(), b.size());
79 COMPARE(
80 b, decltype(b)([](auto i) -> T { return (N0 + i) % V::size(); }));
81 }
82 {
83 auto x = std::experimental::split<N0, N1, N0>(a);
84 COMPARE(std::tuple_size<decltype(x)>::value, 3u);
85 COMPARE(std::get<0>(x), V0([](auto i) -> T { return i; }));
86 COMPARE(std::get<1>(x), V1([](auto i) -> T { return i + N0; }));
87 COMPARE(std::get<2>(x), V0([](auto i) -> T { return i + N0 + N1; }));
88 auto b = concat(std::get<1>(x), std::get<2>(x), std::get<0>(x));
89 // a and b may have different types if a was fixed_size<N> such that
90 // another ABI tag exists with equal N, then b will have the
91 // non-fixed-size ABI tag.
92 COMPARE(a.size(), b.size());
93 COMPARE(
94 b, decltype(b)([](auto i) -> T { return (N0 + i) % V::size(); }));
95 }
96 {
97 auto x = std::experimental::split<N1, N0, N0>(a);
98 COMPARE(std::tuple_size<decltype(x)>::value, 3u);
99 COMPARE(std::get<0>(x), V1([](auto i) -> T { return i; }));
100 COMPARE(std::get<1>(x), V0([](auto i) -> T { return i + N1; }));
101 COMPARE(std::get<2>(x), V0([](auto i) -> T { return i + N0 + N1; }));
102 auto b = concat(std::get<1>(x), std::get<2>(x), std::get<0>(x));
103 // a and b may have different types if a was fixed_size<N> such that
104 // another ABI tag exists with equal N, then b will have the
105 // non-fixed-size ABI tag.
106 COMPARE(a.size(), b.size());
107 COMPARE(
108 b, decltype(b)([](auto i) -> T { return (N1 + i) % V::size(); }));
109 }
110 }
111
112 if constexpr (V::size() % 3 == 0)
113 {
114 const V a = gen<V, ConstProp>([](auto i) -> T { return i; });
115 constexpr auto N0 = V::size() / 3;
116 using V0 = std::experimental::simd<
117 T, std::experimental::simd_abi::deduce_t<T, N0>>;
118 using V1 = std::experimental::simd<
119 T, std::experimental::simd_abi::deduce_t<T, 2 * N0>>;
120 {
121 auto [x, y, z] = std::experimental::split<N0, N0, N0>(a);
122 COMPARE(x, V0([](auto i) -> T { return i; }));
123 COMPARE(y, V0([](auto i) -> T { return i + N0; }));
124 COMPARE(z, V0([](auto i) -> T { return i + N0 * 2; }));
125 auto b = concat(x, y, z);
126 COMPARE(a.size(), b.size());
127 COMPARE(b, simd_cast<decltype(b)>(a));
128 COMPARE(simd_cast<V>(b), a);
129 }
130 {
131 auto [x, y] = std::experimental::split<N0, 2 * N0>(a);
132 COMPARE(x, V0([](auto i) -> T { return i; }));
133 COMPARE(y, V1([](auto i) -> T { return i + N0; }));
134 auto b = concat(x, y);
135 COMPARE(a.size(), b.size());
136 COMPARE(b, simd_cast<decltype(b)>(a));
137 COMPARE(simd_cast<V>(b), a);
138 }
139 {
140 auto [x, y] = std::experimental::split<2 * N0, N0>(a);
141 COMPARE(x, V1([](auto i) -> T { return i; }));
142 COMPARE(y, V0([](auto i) -> T { return i + 2 * N0; }));
143 auto b = concat(x, y);
144 COMPARE(a.size(), b.size());
145 COMPARE(b, simd_cast<decltype(b)>(a));
146 COMPARE(simd_cast<V>(b), a);
147 }
148 }
149
150 if constexpr ((V::size() & 1) == 0)
151 {
152 using std::experimental::simd;
153 using std::experimental::simd_abi::deduce_t;
154 using V0 = simd<T, deduce_t<T, V::size()>>;
155 using V2 = simd<T, deduce_t<T, 2>>;
156 using V3 = simd<T, deduce_t<T, V::size() / 2>>;
157
158 const V a = gen<V, ConstProp>([](auto i) -> T { return i; });
159
160 std::array<V2, V::size() / 2> v2s = std::experimental::split<V2>(a);
161 int offset = 0;
162 for (V2 test : v2s)
163 {
164 COMPARE(test, V2([&](auto i) -> T { return i + offset; }));
165 offset += 2;
166 }
167 COMPARE(concat(v2s), simd_cast<V0>(a));
168
169 std::array<V3, 2> v3s = std::experimental::split<V3>(a);
170 COMPARE(v3s[0], V3([](auto i) -> T { return i; }));
171 COMPARE(v3s[1], V3([](auto i) -> T { return i + V3::size(); }));
172 COMPARE(concat(v3s), simd_cast<V0>(a));
173 }
174 }
175
176template <typename V>
177 void
178 test()
179 {
180 split_concat<V, true>();
181 split_concat<V, false>();
182 }