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++03, c++11, c++14 10 // XFAIL: target=powerpc{{.*}}le-unknown-linux-gnu 11 12 // <experimental/simd> 13 // 14 // [simd.class] 15 // template<class U> simd(U&& value) noexcept; 16 17 #include <algorithm> 18 #include <experimental/simd> 19 20 #include "../test_utils.h" 21 22 namespace ex = std::experimental::parallelism_v2; 23 24 template <class T, class SimdAbi, std::size_t array_size> 25 struct BroadCastHelper { 26 const std::array<T, array_size>& expected_value; 27 28 BroadCastHelper(const std::array<T, array_size>& value) : expected_value(value) {} 29 30 template <class U> 31 void operator()() const { 32 if constexpr (is_non_narrowing_convertible_v<U, T>) { 33 ex::simd<T, SimdAbi> simd_broadcast_from_vectorizable_type(static_cast<U>(3)); 34 assert_simd_values_equal<array_size>(simd_broadcast_from_vectorizable_type, expected_value); 35 } 36 } 37 }; 38 39 template <class T, std::size_t> 40 struct CheckSimdBroadcastCtorFromVectorizedType { 41 template <class SimdAbi> 42 void operator()() { 43 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>; 44 std::array<T, array_size> expected_value; 45 std::fill(expected_value.begin(), expected_value.end(), 3); 46 47 types::for_each(simd_test_types(), BroadCastHelper<T, SimdAbi, array_size>(expected_value)); 48 } 49 }; 50 51 template <class T> 52 class implicit_type { 53 T val; 54 55 public: 56 implicit_type(T v) : val(v) {} 57 operator T() const { return val; } 58 }; 59 60 template <class T, std::size_t> 61 struct CheckSimdBroadcastCtor { 62 template <class SimdAbi> 63 void operator()() { 64 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>; 65 std::array<T, array_size> expected_value; 66 std::fill(expected_value.begin(), expected_value.end(), 3); 67 68 implicit_type<T> implicit_convert_to_3(3); 69 ex::simd<T, SimdAbi> simd_broadcast_from_implicit_type(std::move(implicit_convert_to_3)); 70 assert_simd_values_equal<array_size>(simd_broadcast_from_implicit_type, expected_value); 71 72 ex::simd<T, SimdAbi> simd_broadcast_from_int(3); 73 assert_simd_values_equal<array_size>(simd_broadcast_from_int, expected_value); 74 75 if constexpr (std::is_unsigned_v<T>) { 76 ex::simd<T, SimdAbi> simd_broadcast_from_uint(3u); 77 assert_simd_values_equal<array_size>(simd_broadcast_from_uint, expected_value); 78 } 79 } 80 }; 81 82 template <class T> 83 class no_implicit_type { 84 T val; 85 86 public: 87 no_implicit_type(T v) : val(v) {} 88 }; 89 90 template <class U, class T, class SimdAbi = ex::simd_abi::compatible<T>, class = void> 91 struct has_broadcast_ctor : std::false_type {}; 92 93 template <class U, class T, class SimdAbi> 94 struct has_broadcast_ctor<U, T, SimdAbi, std::void_t<decltype(ex::simd<T, SimdAbi>(std::declval<U>()))>> 95 : std::true_type {}; 96 97 template <class T, class SimdAbi> 98 struct CheckBroadcastCtorTraitsHelper { 99 template <class U> 100 void operator()() const { 101 if constexpr (std::is_same_v<U, int>) 102 static_assert(has_broadcast_ctor<U, T, SimdAbi>::value); 103 else if constexpr (std::is_same_v<U, unsigned int> && std::is_unsigned_v<T>) 104 static_assert(has_broadcast_ctor<U, T, SimdAbi>::value); 105 else if constexpr (is_non_narrowing_convertible_v<U, T>) 106 static_assert(has_broadcast_ctor<U, T, SimdAbi>::value); 107 else 108 static_assert(!has_broadcast_ctor<U, T, SimdAbi>::value); 109 } 110 }; 111 112 template <class T, std::size_t> 113 struct CheckBroadcastCtorTraits { 114 template <class SimdAbi> 115 void operator()() { 116 types::for_each(simd_test_types(), CheckBroadcastCtorTraitsHelper<T, SimdAbi>()); 117 118 static_assert(!has_broadcast_ctor<no_implicit_type<T>, T, SimdAbi>::value); 119 static_assert(has_broadcast_ctor<implicit_type<T>, T, SimdAbi>::value); 120 } 121 }; 122 123 int main(int, char**) { 124 test_all_simd_abi<CheckSimdBroadcastCtorFromVectorizedType>(); 125 test_all_simd_abi<CheckSimdBroadcastCtor>(); 126 test_all_simd_abi<CheckBroadcastCtorTraits>(); 127 return 0; 128 } 129