1*38cd7de5STim Shen //===----------------------------------------------------------------------===//
2*38cd7de5STim Shen //
3*38cd7de5STim Shen //                     The LLVM Compiler Infrastructure
4*38cd7de5STim Shen //
5*38cd7de5STim Shen // This file is dual licensed under the MIT and the University of Illinois Open
6*38cd7de5STim Shen // Source Licenses. See LICENSE.TXT for details.
7*38cd7de5STim Shen //
8*38cd7de5STim Shen //===----------------------------------------------------------------------===//
9*38cd7de5STim Shen 
10*38cd7de5STim Shen // UNSUPPORTED: c++98, c++03, c++11, c++14
11*38cd7de5STim Shen 
12*38cd7de5STim Shen // <experimental/simd>
13*38cd7de5STim Shen //
14*38cd7de5STim Shen // loads [simd.load]
15*38cd7de5STim Shen // template <class U, class Flags> void copy_from(const U* mem, Flags f);
16*38cd7de5STim Shen 
17*38cd7de5STim Shen #include <experimental/simd>
18*38cd7de5STim Shen #include <cstdint>
19*38cd7de5STim Shen 
20*38cd7de5STim Shen #include "test_macros.h"
21*38cd7de5STim Shen 
22*38cd7de5STim Shen namespace ex = std::experimental::parallelism_v2;
23*38cd7de5STim Shen 
24*38cd7de5STim Shen template <class T, class... Args>
25*38cd7de5STim Shen auto not_supported_load(Args&&... args) -> decltype(
26*38cd7de5STim Shen     std::declval<ex::native_simd<T>>().copy_from(std::forward<Args>(args)...),
27*38cd7de5STim Shen     void()) = delete;
28*38cd7de5STim Shen 
29*38cd7de5STim Shen template <class T>
30*38cd7de5STim Shen void not_supported_load(...) {}
31*38cd7de5STim Shen 
32*38cd7de5STim Shen template <class T, class... Args>
33*38cd7de5STim Shen auto supported_load(Args&&... args) -> decltype(
34*38cd7de5STim Shen     std::declval<ex::native_simd<T>>().copy_from(std::forward<Args>(args)...),
35*38cd7de5STim Shen     void()) {}
36*38cd7de5STim Shen 
37*38cd7de5STim Shen template <class T>
38*38cd7de5STim Shen void supported_load(...) = delete;
39*38cd7de5STim Shen 
40*38cd7de5STim Shen void compile_load() {
41*38cd7de5STim Shen   supported_load<int>((int*)nullptr, ex::element_aligned_tag());
42*38cd7de5STim Shen   supported_load<uint32_t>((int*)nullptr, ex::element_aligned_tag());
43*38cd7de5STim Shen   supported_load<double>((float*)nullptr, ex::element_aligned_tag());
44*38cd7de5STim Shen   supported_load<uint16_t>((unsigned int*)nullptr, ex::element_aligned_tag());
45*38cd7de5STim Shen   supported_load<uint32_t>((float*)nullptr, ex::element_aligned_tag());
46*38cd7de5STim Shen 
47*38cd7de5STim Shen   not_supported_load<int>((int*)nullptr, int());
48*38cd7de5STim Shen }
49*38cd7de5STim Shen 
50*38cd7de5STim Shen template <typename SimdType>
51*38cd7de5STim Shen void test_load() {
52*38cd7de5STim Shen   alignas(32) int32_t buffer[] = {4, 3, 2, 1};
53*38cd7de5STim Shen   {
54*38cd7de5STim Shen     SimdType a;
55*38cd7de5STim Shen     a.copy_from(buffer, ex::element_aligned_tag());
56*38cd7de5STim Shen     assert(a[0] == 4);
57*38cd7de5STim Shen     assert(a[1] == 3);
58*38cd7de5STim Shen     assert(a[2] == 2);
59*38cd7de5STim Shen     assert(a[3] == 1);
60*38cd7de5STim Shen   }
61*38cd7de5STim Shen   {
62*38cd7de5STim Shen     SimdType a;
63*38cd7de5STim Shen     a.copy_from(buffer, ex::vector_aligned_tag());
64*38cd7de5STim Shen     assert(a[0] == 4);
65*38cd7de5STim Shen     assert(a[1] == 3);
66*38cd7de5STim Shen     assert(a[2] == 2);
67*38cd7de5STim Shen     assert(a[3] == 1);
68*38cd7de5STim Shen   }
69*38cd7de5STim Shen   {
70*38cd7de5STim Shen     SimdType a;
71*38cd7de5STim Shen     a.copy_from(buffer, ex::overaligned_tag<32>());
72*38cd7de5STim Shen     assert(a[0] == 4);
73*38cd7de5STim Shen     assert(a[1] == 3);
74*38cd7de5STim Shen     assert(a[2] == 2);
75*38cd7de5STim Shen     assert(a[3] == 1);
76*38cd7de5STim Shen   }
77*38cd7de5STim Shen 
78*38cd7de5STim Shen   {
79*38cd7de5STim Shen     SimdType a;
80*38cd7de5STim Shen     a.copy_from(buffer, ex::element_aligned);
81*38cd7de5STim Shen     assert(a[0] == 4);
82*38cd7de5STim Shen     assert(a[1] == 3);
83*38cd7de5STim Shen     assert(a[2] == 2);
84*38cd7de5STim Shen     assert(a[3] == 1);
85*38cd7de5STim Shen   }
86*38cd7de5STim Shen   {
87*38cd7de5STim Shen     SimdType a;
88*38cd7de5STim Shen     a.copy_from(buffer, ex::vector_aligned);
89*38cd7de5STim Shen     assert(a[0] == 4);
90*38cd7de5STim Shen     assert(a[1] == 3);
91*38cd7de5STim Shen     assert(a[2] == 2);
92*38cd7de5STim Shen     assert(a[3] == 1);
93*38cd7de5STim Shen   }
94*38cd7de5STim Shen   {
95*38cd7de5STim Shen     SimdType a;
96*38cd7de5STim Shen     a.copy_from(buffer, ex::overaligned<32>);
97*38cd7de5STim Shen     assert(a[0] == 4);
98*38cd7de5STim Shen     assert(a[1] == 3);
99*38cd7de5STim Shen     assert(a[2] == 2);
100*38cd7de5STim Shen     assert(a[3] == 1);
101*38cd7de5STim Shen   }
102*38cd7de5STim Shen }
103*38cd7de5STim Shen 
104*38cd7de5STim Shen template <typename SimdType>
105*38cd7de5STim Shen void test_converting_load() {
106*38cd7de5STim Shen   float buffer[] = {1., 2., 4., 8.};
107*38cd7de5STim Shen   SimdType a;
108*38cd7de5STim Shen   a.copy_from(buffer, ex::element_aligned_tag());
109*38cd7de5STim Shen   assert(a[0] == 1);
110*38cd7de5STim Shen   assert(a[1] == 2);
111*38cd7de5STim Shen   assert(a[2] == 4);
112*38cd7de5STim Shen   assert(a[3] == 8);
113*38cd7de5STim Shen }
114*38cd7de5STim Shen 
115*38cd7de5STim Shen int main() {
116*38cd7de5STim Shen   // TODO: adjust the tests when this assertion fails.
117*38cd7de5STim Shen   assert(ex::native_simd<int32_t>::size() >= 4);
118*38cd7de5STim Shen   test_load<ex::native_simd<int32_t>>();
119*38cd7de5STim Shen   test_load<ex::fixed_size_simd<int32_t, 4>>();
120*38cd7de5STim Shen   test_converting_load<ex::native_simd<int32_t>>();
121*38cd7de5STim Shen   test_converting_load<ex::fixed_size_simd<int32_t, 4>>();
122*38cd7de5STim Shen }
123