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 
9*31cbe0f2SLouis Dionne // UNSUPPORTED: 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>
18a0686015SDavid Zarzycki #include <cassert>
1938cd7de5STim Shen 
2038cd7de5STim Shen #include "test_macros.h"
2138cd7de5STim Shen 
2238cd7de5STim Shen namespace ex = std::experimental::parallelism_v2;
2338cd7de5STim Shen 
2438cd7de5STim Shen template <class T, class... Args>
2538cd7de5STim Shen auto not_supported_load(Args&&... args) -> decltype(
2638cd7de5STim Shen     std::declval<ex::native_simd<T>>().copy_from(std::forward<Args>(args)...),
2738cd7de5STim Shen     void()) = delete;
2838cd7de5STim Shen 
2938cd7de5STim Shen template <class T>
not_supported_load(...)3038cd7de5STim Shen void not_supported_load(...) {}
3138cd7de5STim Shen 
3238cd7de5STim Shen template <class T, class... Args>
supported_load(Args &&...args)3338cd7de5STim Shen auto supported_load(Args&&... args) -> decltype(
3438cd7de5STim Shen     std::declval<ex::native_simd<T>>().copy_from(std::forward<Args>(args)...),
3538cd7de5STim Shen     void()) {}
3638cd7de5STim Shen 
3738cd7de5STim Shen template <class T>
3838cd7de5STim Shen void supported_load(...) = delete;
3938cd7de5STim Shen 
compile_load()4038cd7de5STim Shen void compile_load() {
4138cd7de5STim Shen   supported_load<int>((int*)nullptr, ex::element_aligned_tag());
4238cd7de5STim Shen   supported_load<uint32_t>((int*)nullptr, ex::element_aligned_tag());
4338cd7de5STim Shen   supported_load<double>((float*)nullptr, ex::element_aligned_tag());
4438cd7de5STim Shen   supported_load<uint16_t>((unsigned int*)nullptr, ex::element_aligned_tag());
4538cd7de5STim Shen   supported_load<uint32_t>((float*)nullptr, ex::element_aligned_tag());
4638cd7de5STim Shen 
4738cd7de5STim Shen   not_supported_load<int>((int*)nullptr, int());
4838cd7de5STim Shen }
4938cd7de5STim Shen 
5038cd7de5STim Shen template <typename SimdType>
test_load()5138cd7de5STim Shen void test_load() {
5238cd7de5STim Shen   alignas(32) int32_t buffer[] = {4, 3, 2, 1};
5338cd7de5STim Shen   {
5438cd7de5STim Shen     SimdType a;
5538cd7de5STim Shen     a.copy_from(buffer, ex::element_aligned_tag());
5638cd7de5STim Shen     assert(a[0] == 4);
5738cd7de5STim Shen     assert(a[1] == 3);
5838cd7de5STim Shen     assert(a[2] == 2);
5938cd7de5STim Shen     assert(a[3] == 1);
6038cd7de5STim Shen   }
6138cd7de5STim Shen   {
6238cd7de5STim Shen     SimdType a;
6338cd7de5STim Shen     a.copy_from(buffer, ex::vector_aligned_tag());
6438cd7de5STim Shen     assert(a[0] == 4);
6538cd7de5STim Shen     assert(a[1] == 3);
6638cd7de5STim Shen     assert(a[2] == 2);
6738cd7de5STim Shen     assert(a[3] == 1);
6838cd7de5STim Shen   }
6938cd7de5STim Shen   {
7038cd7de5STim Shen     SimdType a;
7138cd7de5STim Shen     a.copy_from(buffer, ex::overaligned_tag<32>());
7238cd7de5STim Shen     assert(a[0] == 4);
7338cd7de5STim Shen     assert(a[1] == 3);
7438cd7de5STim Shen     assert(a[2] == 2);
7538cd7de5STim Shen     assert(a[3] == 1);
7638cd7de5STim Shen   }
7738cd7de5STim Shen 
7838cd7de5STim Shen   {
7938cd7de5STim Shen     SimdType a;
8038cd7de5STim Shen     a.copy_from(buffer, ex::element_aligned);
8138cd7de5STim Shen     assert(a[0] == 4);
8238cd7de5STim Shen     assert(a[1] == 3);
8338cd7de5STim Shen     assert(a[2] == 2);
8438cd7de5STim Shen     assert(a[3] == 1);
8538cd7de5STim Shen   }
8638cd7de5STim Shen   {
8738cd7de5STim Shen     SimdType a;
8838cd7de5STim Shen     a.copy_from(buffer, ex::vector_aligned);
8938cd7de5STim Shen     assert(a[0] == 4);
9038cd7de5STim Shen     assert(a[1] == 3);
9138cd7de5STim Shen     assert(a[2] == 2);
9238cd7de5STim Shen     assert(a[3] == 1);
9338cd7de5STim Shen   }
9438cd7de5STim Shen   {
9538cd7de5STim Shen     SimdType a;
9638cd7de5STim Shen     a.copy_from(buffer, ex::overaligned<32>);
9738cd7de5STim Shen     assert(a[0] == 4);
9838cd7de5STim Shen     assert(a[1] == 3);
9938cd7de5STim Shen     assert(a[2] == 2);
10038cd7de5STim Shen     assert(a[3] == 1);
10138cd7de5STim Shen   }
10238cd7de5STim Shen }
10338cd7de5STim Shen 
10438cd7de5STim Shen template <typename SimdType>
test_converting_load()10538cd7de5STim Shen void test_converting_load() {
10638cd7de5STim Shen   float buffer[] = {1., 2., 4., 8.};
10738cd7de5STim Shen   SimdType a;
10838cd7de5STim Shen   a.copy_from(buffer, ex::element_aligned_tag());
10938cd7de5STim Shen   assert(a[0] == 1);
11038cd7de5STim Shen   assert(a[1] == 2);
11138cd7de5STim Shen   assert(a[2] == 4);
11238cd7de5STim Shen   assert(a[3] == 8);
11338cd7de5STim Shen }
11438cd7de5STim Shen 
main(int,char **)1152df59c50SJF Bastien int main(int, char**) {
11638cd7de5STim Shen   // TODO: adjust the tests when this assertion fails.
11738cd7de5STim Shen   assert(ex::native_simd<int32_t>::size() >= 4);
11838cd7de5STim Shen   test_load<ex::native_simd<int32_t>>();
11938cd7de5STim Shen   test_load<ex::fixed_size_simd<int32_t, 4>>();
12038cd7de5STim Shen   test_converting_load<ex::native_simd<int32_t>>();
12138cd7de5STim Shen   test_converting_load<ex::fixed_size_simd<int32_t, 4>>();
1222df59c50SJF Bastien 
1232df59c50SJF Bastien   return 0;
12438cd7de5STim Shen }
125