138cd7de5STim Shen //===----------------------------------------------------------------------===//
238cd7de5STim Shen //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
638cd7de5STim Shen //
738cd7de5STim Shen //===----------------------------------------------------------------------===//
838cd7de5STim Shen 
938cd7de5STim Shen // UNSUPPORTED: c++98, c++03, c++11, c++14
1038cd7de5STim Shen 
1138cd7de5STim Shen // <experimental/simd>
1238cd7de5STim Shen //
1338cd7de5STim Shen // loads [simd.load]
1438cd7de5STim Shen // template <class U, class Flags> void copy_from(const U* mem, Flags f);
1538cd7de5STim Shen 
1638cd7de5STim Shen #include <experimental/simd>
1738cd7de5STim Shen #include <cstdint>
1838cd7de5STim Shen 
1938cd7de5STim Shen #include "test_macros.h"
2038cd7de5STim Shen 
2138cd7de5STim Shen namespace ex = std::experimental::parallelism_v2;
2238cd7de5STim Shen 
2338cd7de5STim Shen template <class T, class... Args>
2438cd7de5STim Shen auto not_supported_load(Args&&... args) -> decltype(
2538cd7de5STim Shen     std::declval<ex::native_simd<T>>().copy_from(std::forward<Args>(args)...),
2638cd7de5STim Shen     void()) = delete;
2738cd7de5STim Shen 
2838cd7de5STim Shen template <class T>
2938cd7de5STim Shen void not_supported_load(...) {}
3038cd7de5STim Shen 
3138cd7de5STim Shen template <class T, class... Args>
3238cd7de5STim Shen auto supported_load(Args&&... args) -> decltype(
3338cd7de5STim Shen     std::declval<ex::native_simd<T>>().copy_from(std::forward<Args>(args)...),
3438cd7de5STim Shen     void()) {}
3538cd7de5STim Shen 
3638cd7de5STim Shen template <class T>
3738cd7de5STim Shen void supported_load(...) = delete;
3838cd7de5STim Shen 
3938cd7de5STim Shen void compile_load() {
4038cd7de5STim Shen   supported_load<int>((int*)nullptr, ex::element_aligned_tag());
4138cd7de5STim Shen   supported_load<uint32_t>((int*)nullptr, ex::element_aligned_tag());
4238cd7de5STim Shen   supported_load<double>((float*)nullptr, ex::element_aligned_tag());
4338cd7de5STim Shen   supported_load<uint16_t>((unsigned int*)nullptr, ex::element_aligned_tag());
4438cd7de5STim Shen   supported_load<uint32_t>((float*)nullptr, ex::element_aligned_tag());
4538cd7de5STim Shen 
4638cd7de5STim Shen   not_supported_load<int>((int*)nullptr, int());
4738cd7de5STim Shen }
4838cd7de5STim Shen 
4938cd7de5STim Shen template <typename SimdType>
5038cd7de5STim Shen void test_load() {
5138cd7de5STim Shen   alignas(32) int32_t buffer[] = {4, 3, 2, 1};
5238cd7de5STim Shen   {
5338cd7de5STim Shen     SimdType a;
5438cd7de5STim Shen     a.copy_from(buffer, ex::element_aligned_tag());
5538cd7de5STim Shen     assert(a[0] == 4);
5638cd7de5STim Shen     assert(a[1] == 3);
5738cd7de5STim Shen     assert(a[2] == 2);
5838cd7de5STim Shen     assert(a[3] == 1);
5938cd7de5STim Shen   }
6038cd7de5STim Shen   {
6138cd7de5STim Shen     SimdType a;
6238cd7de5STim Shen     a.copy_from(buffer, ex::vector_aligned_tag());
6338cd7de5STim Shen     assert(a[0] == 4);
6438cd7de5STim Shen     assert(a[1] == 3);
6538cd7de5STim Shen     assert(a[2] == 2);
6638cd7de5STim Shen     assert(a[3] == 1);
6738cd7de5STim Shen   }
6838cd7de5STim Shen   {
6938cd7de5STim Shen     SimdType a;
7038cd7de5STim Shen     a.copy_from(buffer, ex::overaligned_tag<32>());
7138cd7de5STim Shen     assert(a[0] == 4);
7238cd7de5STim Shen     assert(a[1] == 3);
7338cd7de5STim Shen     assert(a[2] == 2);
7438cd7de5STim Shen     assert(a[3] == 1);
7538cd7de5STim Shen   }
7638cd7de5STim Shen 
7738cd7de5STim Shen   {
7838cd7de5STim Shen     SimdType a;
7938cd7de5STim Shen     a.copy_from(buffer, ex::element_aligned);
8038cd7de5STim Shen     assert(a[0] == 4);
8138cd7de5STim Shen     assert(a[1] == 3);
8238cd7de5STim Shen     assert(a[2] == 2);
8338cd7de5STim Shen     assert(a[3] == 1);
8438cd7de5STim Shen   }
8538cd7de5STim Shen   {
8638cd7de5STim Shen     SimdType a;
8738cd7de5STim Shen     a.copy_from(buffer, ex::vector_aligned);
8838cd7de5STim Shen     assert(a[0] == 4);
8938cd7de5STim Shen     assert(a[1] == 3);
9038cd7de5STim Shen     assert(a[2] == 2);
9138cd7de5STim Shen     assert(a[3] == 1);
9238cd7de5STim Shen   }
9338cd7de5STim Shen   {
9438cd7de5STim Shen     SimdType a;
9538cd7de5STim Shen     a.copy_from(buffer, ex::overaligned<32>);
9638cd7de5STim Shen     assert(a[0] == 4);
9738cd7de5STim Shen     assert(a[1] == 3);
9838cd7de5STim Shen     assert(a[2] == 2);
9938cd7de5STim Shen     assert(a[3] == 1);
10038cd7de5STim Shen   }
10138cd7de5STim Shen }
10238cd7de5STim Shen 
10338cd7de5STim Shen template <typename SimdType>
10438cd7de5STim Shen void test_converting_load() {
10538cd7de5STim Shen   float buffer[] = {1., 2., 4., 8.};
10638cd7de5STim Shen   SimdType a;
10738cd7de5STim Shen   a.copy_from(buffer, ex::element_aligned_tag());
10838cd7de5STim Shen   assert(a[0] == 1);
10938cd7de5STim Shen   assert(a[1] == 2);
11038cd7de5STim Shen   assert(a[2] == 4);
11138cd7de5STim Shen   assert(a[3] == 8);
11238cd7de5STim Shen }
11338cd7de5STim Shen 
114*2df59c50SJF Bastien int main(int, char**) {
11538cd7de5STim Shen   // TODO: adjust the tests when this assertion fails.
11638cd7de5STim Shen   assert(ex::native_simd<int32_t>::size() >= 4);
11738cd7de5STim Shen   test_load<ex::native_simd<int32_t>>();
11838cd7de5STim Shen   test_load<ex::fixed_size_simd<int32_t, 4>>();
11938cd7de5STim Shen   test_converting_load<ex::native_simd<int32_t>>();
12038cd7de5STim Shen   test_converting_load<ex::fixed_size_simd<int32_t, 4>>();
121*2df59c50SJF Bastien 
122*2df59c50SJF Bastien   return 0;
12338cd7de5STim Shen }
124