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 // <experimental/simd>
12 //
13 // [simd.class]
14 // template <class U, class Flags> simd(const U* mem, Flags f);
15 
16 #include <cstdint>
17 #include <experimental/simd>
18 
19 #include "test_macros.h"
20 
21 namespace ex = std::experimental::parallelism_v2;
22 
23 template <class T, class... Args>
24 auto not_supported_native_simd_ctor(Args&&... args)
25     -> decltype(ex::native_simd<T>(std::forward<Args>(args)...),
26                 void()) = delete;
27 
28 template <class T>
29 void not_supported_native_simd_ctor(...) {}
30 
31 template <class T, class... Args>
32 auto supported_native_simd_ctor(Args&&... args)
33     -> decltype(ex::native_simd<T>(std::forward<Args>(args)...), void()) {}
34 
35 template <class T>
36 void supported_native_simd_ctor(...) = delete;
37 
38 void compile_load_ctor() {
39   supported_native_simd_ctor<int>((int*)nullptr, ex::element_aligned_tag());
40   supported_native_simd_ctor<uint32_t>((int*)nullptr,
41                                        ex::element_aligned_tag());
42   supported_native_simd_ctor<double>((float*)nullptr,
43                                      ex::element_aligned_tag());
44   supported_native_simd_ctor<uint16_t>((unsigned int*)nullptr,
45                                        ex::element_aligned_tag());
46   supported_native_simd_ctor<uint32_t>((float*)nullptr,
47                                        ex::element_aligned_tag());
48 
49   not_supported_native_simd_ctor<int>((int*)nullptr, int());
50 }
51 
52 template <typename SimdType>
53 void test_load_ctor() {
54   alignas(32) int32_t buffer[] = {4, 3, 2, 1};
55   {
56     SimdType a(buffer, ex::element_aligned_tag());
57     assert(a[0] == 4);
58     assert(a[1] == 3);
59     assert(a[2] == 2);
60     assert(a[3] == 1);
61   }
62   {
63     SimdType a(buffer, ex::vector_aligned_tag());
64     assert(a[0] == 4);
65     assert(a[1] == 3);
66     assert(a[2] == 2);
67     assert(a[3] == 1);
68   }
69   {
70     SimdType a(buffer, ex::overaligned_tag<32>());
71     assert(a[0] == 4);
72     assert(a[1] == 3);
73     assert(a[2] == 2);
74     assert(a[3] == 1);
75   }
76 
77   {
78     SimdType a(buffer, ex::element_aligned);
79     assert(a[0] == 4);
80     assert(a[1] == 3);
81     assert(a[2] == 2);
82     assert(a[3] == 1);
83   }
84   {
85     SimdType a(buffer, ex::vector_aligned);
86     assert(a[0] == 4);
87     assert(a[1] == 3);
88     assert(a[2] == 2);
89     assert(a[3] == 1);
90   }
91   {
92     SimdType a(buffer, ex::overaligned<32>);
93     assert(a[0] == 4);
94     assert(a[1] == 3);
95     assert(a[2] == 2);
96     assert(a[3] == 1);
97   }
98 }
99 
100 template <typename SimdType>
101 void test_converting_load_ctor() {
102   float buffer[] = {1., 2., 4., 8.};
103   SimdType a(buffer, ex::element_aligned_tag());
104   assert(a[0] == 1);
105   assert(a[1] == 2);
106   assert(a[2] == 4);
107   assert(a[3] == 8);
108 }
109 
110 int main(int, char**) {
111   // TODO: adjust the tests when this assertion fails.
112   assert(ex::native_simd<int32_t>::size() >= 4);
113   test_load_ctor<ex::native_simd<int32_t>>();
114   test_load_ctor<ex::fixed_size_simd<int32_t, 4>>();
115   test_converting_load_ctor<ex::native_simd<int32_t>>();
116   test_converting_load_ctor<ex::fixed_size_simd<int32_t, 4>>();
117 
118   return 0;
119 }
120