]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/experimental/simd/tests/split_concat.cc
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
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)
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.
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/>.
18 // expensive: * [1-9] * *
19 #include "bits/verify.h"
20 #include "bits/metahelpers.h"
21 #include "bits/conversions.h"
23 using std::experimental::simd_cast
;
25 template <typename V
, bool ConstProp
, typename F
>
29 if constexpr (ConstProp
)
32 return make_value_unknown(V(fun
));
35 template <typename V
, bool ConstProp
>
39 using T
= typename
V::value_type
;
40 if constexpr (V::size() * 3
41 <= std::experimental::simd_abi::max_fixed_size
<T
>)
44 auto x
= concat(a
, b
, c
);
45 COMPARE(x
.size(), a
.size() * 3);
47 for (; i
< a
.size(); ++i
)
51 for (; i
< 2 * a
.size(); ++i
)
55 for (; i
< 3 * a
.size(); ++i
)
61 if constexpr (V::size() >= 4)
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
>>;
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());
82 b
, decltype(b
)([](auto i
) -> T
{ return (N0
+ i
) % V::size(); }));
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());
96 b
, decltype(b
)([](auto i
) -> T
{ return (N0
+ i
) % V::size(); }));
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());
110 b
, decltype(b
)([](auto i
) -> T
{ return (N1
+ i
) % V::size(); }));
114 if constexpr (V::size() % 3 == 0)
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
>>;
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
);
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
);
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
);
152 if constexpr ((V::size() & 1) == 0)
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>>;
160 const V a
= gen
<V
, ConstProp
>([](auto i
) -> T
{ return i
; });
162 std::array
<V2
, V::size() / 2> v2s
= std::experimental::split
<V2
>(a
);
166 COMPARE(test
, V2([&](auto i
) -> T
{ return i
+ offset
; }));
169 COMPARE(concat(v2s
), simd_cast
<V0
>(a
));
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
));
178 template <typename V
>
182 split_concat
<V
, true>();
183 split_concat
<V
, false>();