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++98, c++03, c++11, c++14
10 
11 // See GCC PR63723.
12 // UNSUPPORTED: gcc-4.9
13 
14 // <experimental/simd>
15 //
16 // [simd.class]
17 // template <class G> explicit simd(G&& gen);
18 
19 #include <experimental/simd>
20 #include <cstdint>
21 
22 #include "test_macros.h"
23 
24 namespace ex = std::experimental::parallelism_v2;
25 
26 template <class T, class... Args>
27 auto not_supported_simd128_ctor(Args&&... args) -> decltype(
28     ex::fixed_size_simd<T, 16 / sizeof(T)>(std::forward<Args>(args)...),
29     void()) = delete;
30 
31 template <class T>
32 void not_supported_simd128_ctor(...) {}
33 
34 template <class T, class... Args>
35 auto supported_simd128_ctor(Args&&... args) -> decltype(
36     ex::fixed_size_simd<T, 16 / sizeof(T)>(std::forward<Args>(args)...),
37     void()) {}
38 
39 template <class T>
40 void supported_simd128_ctor(...) = delete;
41 
42 struct identity {
43   template <size_t value>
44   int operator()(std::integral_constant<size_t, value>) const {
45     return value;
46   }
47 };
48 
49 void compile_generator() {
50   supported_simd128_ctor<int>(identity());
51   not_supported_simd128_ctor<int>([](int i) { return float(i); });
52   not_supported_simd128_ctor<int>([](intptr_t i) { return (int*)(i); });
53   not_supported_simd128_ctor<int>([](int* i) { return i; });
54 }
55 
56 struct limited_identity {
57   template <size_t value>
58   typename std::conditional<value <= 2, int32_t, int64_t>::type
59   operator()(std::integral_constant<size_t, value>) const {
60     return value;
61   }
62 };
63 
64 void compile_limited_identity() {
65   supported_simd128_ctor<int64_t>(limited_identity());
66   not_supported_simd128_ctor<int32_t>(limited_identity());
67 }
68 
69 template <typename SimdType>
70 void test_generator() {
71   {
72     SimdType a([](int i) { return i; });
73     assert(a[0] == 0);
74     assert(a[1] == 1);
75     assert(a[2] == 2);
76     assert(a[3] == 3);
77   }
78   {
79     SimdType a([](int i) { return 2 * i - 1; });
80     assert(a[0] == -1);
81     assert(a[1] == 1);
82     assert(a[2] == 3);
83     assert(a[3] == 5);
84   }
85 }
86 
87 int main(int, char**) {
88   // TODO: adjust the tests when this assertion fails.
89   assert(ex::native_simd<int32_t>::size() >= 4);
90   test_generator<ex::native_simd<int32_t>>();
91   test_generator<ex::fixed_size_simd<int32_t, 4>>();
92 
93   return 0;
94 }
95