diff --git a/libcxx/include/experimental/__simd/utility.h b/libcxx/include/experimental/__simd/utility.h index e4fb51b6f505..73ad387aacc6 100644 --- a/libcxx/include/experimental/__simd/utility.h +++ b/libcxx/include/experimental/__simd/utility.h @@ -65,18 +65,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr decltype(_To{std::declval<_From>()}, true) __is_ return true; } -template -_LIBCPP_HIDE_FROM_ABI constexpr bool __is_non_narrowing_convertible_impl(...) { - return false; -} +template +inline constexpr bool __is_non_narrowing_convertible_v = false; template -_LIBCPP_HIDE_FROM_ABI constexpr bool __is_non_narrowing_arithmetic_convertible() { - if constexpr (is_arithmetic_v<_To> && is_arithmetic_v<_From>) - return std::experimental::parallelism_v2::__is_non_narrowing_convertible_impl<_To>(_From{}); - else - return false; -} +inline constexpr bool __is_non_narrowing_convertible_v<_From, _To, std::void_t()})>> = + true; template _LIBCPP_HIDE_FROM_ABI constexpr _Tp __variadic_sum(_Args... __args) { @@ -90,7 +84,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __is_vectorizable() { template _LIBCPP_HIDE_FROM_ABI constexpr bool __can_broadcast() { - return (is_arithmetic_v<_Up> && __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()) || + return (is_arithmetic_v<_Up> && __is_non_narrowing_convertible_v<_Up, _Tp>) || (!is_arithmetic_v<_Up> && is_convertible_v<_Up, _Tp>) || is_same_v, int> || (is_same_v, unsigned int> && is_unsigned_v<_Tp>); } diff --git a/libcxx/include/experimental/simd b/libcxx/include/experimental/simd index d690fc707380..e6eed6599e74 100644 --- a/libcxx/include/experimental/simd +++ b/libcxx/include/experimental/simd @@ -1851,7 +1851,7 @@ public: // implicit type conversion constructor template > && - __is_non_narrowing_arithmetic_convertible<_Up, value_type>()>> + __is_non_narrowing_convertible_v<_Up, value_type>>> _LIBCPP_HIDE_FROM_ABI simd(const simd<_Up, simd_abi::fixed_size>& __v) { for (size_t __i = 0; __i < size(); __i++) { (*this)[__i] = static_cast<_Tp>(__v[__i]); diff --git a/libcxx/test/std/experimental/simd/simd.class/simd_ctor.pass.cpp b/libcxx/test/std/experimental/simd/simd.class/simd_ctor.pass.cpp index 2971e3eafc97..4a351ef8c3dd 100644 --- a/libcxx/test/std/experimental/simd/simd.class/simd_ctor.pass.cpp +++ b/libcxx/test/std/experimental/simd/simd.class/simd_ctor.pass.cpp @@ -20,112 +20,89 @@ #include namespace ex = std::experimental::parallelism_v2; -template -class zero_init { - T val; - -public: - zero_init() : val(static_cast(0)) {} - zero_init(T val) : val(val) {} - operator T&() { return val; } - operator T() const { return val; } -}; -template +template struct BroadCastHelper { - const std::array<_Tp, array_size>& origin_value; + const std::array& expected_value; - BroadCastHelper(const std::array<_Tp, array_size>& origin_value) : origin_value(origin_value) {} + BroadCastHelper(const std::array& value) : expected_value(value) {} - template + template void operator()() const { - if constexpr (sizeof(_Up) <= sizeof(_Tp)) { - ex::simd<_Tp, SimdAbi> expected_simd_from_vectorizable_type(static_cast<_Up>(3)); - assert_simd_value_correct(expected_simd_from_vectorizable_type, origin_value); + if constexpr (is_non_narrowing_convertible_v) { + ex::simd simd_broadcast_from_vectorizable_type(static_cast(3)); + assert_simd_value_correct(simd_broadcast_from_vectorizable_type, expected_value); } } }; -struct CheckBroadCastSimdCtorFromVectorizedType { - template - void check(const std::array<_Tp, array_size>& origin_value) { - types::for_each(TypeList{}, BroadCastHelper<_Tp, SimdAbi, array_size>(origin_value)); - } - - template +struct CheckSimdBroadcastCtorFromVectorizedType { + template void operator()() { - constexpr size_t array_size = ex::simd_size_v<_Tp, SimdAbi>; - std::array<_Tp, array_size> origin_value; - for (size_t i = 0; i < array_size; ++i) - origin_value[i] = static_cast<_Tp>(3); - - if constexpr (std::is_floating_point_v<_Tp>) - check(origin_value); - else if constexpr (std::is_signed_v<_Tp>) - check(origin_value); - else - check(origin_value); + constexpr std::size_t array_size = ex::simd_size_v; + std::array expected_value; + std::fill(expected_value.begin(), expected_value.end(), 3); + + types::for_each(arithmetic_no_bool_types(), BroadCastHelper(expected_value)); } }; -struct CheckBroadCastSimdCtor { - template +template +class implicit_type { + T val; + +public: + implicit_type(T v) : val(v) {} + operator T() const { return val; } +}; + +struct CheckSimdBroadcastCtor { + template void operator()() { - constexpr size_t array_size = ex::simd_size_v<_Tp, SimdAbi>; - std::array<_Tp, array_size> origin_value; - for (size_t i = 0; i < array_size; ++i) - origin_value[i] = static_cast<_Tp>(3); + constexpr std::size_t array_size = ex::simd_size_v; + std::array expected_value; + std::fill(expected_value.begin(), expected_value.end(), 3); - zero_init<_Tp> implicit_convert_to_3(3); - ex::simd<_Tp, SimdAbi> expected_simd_from_implicit_convert(std::move(implicit_convert_to_3)); - assert_simd_value_correct(expected_simd_from_implicit_convert, origin_value); + implicit_type implicit_convert_to_3(3); + ex::simd simd_broadcast_from_implicit_type(std::move(implicit_convert_to_3)); + assert_simd_value_correct(simd_broadcast_from_implicit_type, expected_value); - int int_value_3 = 3; - ex::simd<_Tp, SimdAbi> expected_simd_from_int(std::move(int_value_3)); - assert_simd_value_correct(expected_simd_from_int, origin_value); + ex::simd simd_broadcast_from_int(3); + assert_simd_value_correct(simd_broadcast_from_int, expected_value); - if constexpr (std::is_unsigned_v<_Tp>) { - unsigned int uint_value_3 = static_cast(3); - ex::simd<_Tp, SimdAbi> expected_simd_from_uint(std::move(uint_value_3)); - assert_simd_value_correct(expected_simd_from_uint, origin_value); + if constexpr (std::is_unsigned_v) { + ex::simd simd_broadcast_from_uint(3u); + assert_simd_value_correct(simd_broadcast_from_uint, expected_value); } } }; -template -struct FixedSimdForEachHelper { - static constexpr size_t array_size = ex::simd_size_v<_Tp, SimdAbi>; +template +struct ConversionHelper { + const std::array& expected_value; + + ConversionHelper(const std::array& value) : expected_value(value) {} - template + template void operator()() const { - if constexpr (sizeof(_Tp) >= sizeof(_Up)) { - ex::simd<_Up, SimdAbi> origin_simd([](_Up i) { return i; }); - ex::simd<_Tp, SimdAbi> convert_from_other_simd(origin_simd); - std::array<_Up, array_size> expected_value; - for (size_t i = 0; i < array_size; i++) - expected_value[i] = static_cast<_Up>(i); - - assert_simd_value_correct(convert_from_other_simd, expected_value); + if constexpr (!std::is_same_v && std::is_same_v> && + is_non_narrowing_convertible_v) { + ex::simd origin_simd([](U i) { return i; }); + ex::simd simd_from_implicit_conversion(origin_simd); + assert_simd_value_correct(simd_from_implicit_conversion, expected_value); } } }; -struct CheckFixedSimdCtor { - template - void check() { - types::for_each(TypeList{}, FixedSimdForEachHelper<_Tp, SimdAbi, _Np>()); - } - - template +struct CheckConversionSimdCtor { + template void operator()() { - if constexpr (std::is_same_v>) { - if constexpr (std::is_floating_point_v<_Tp>) - check(); - else if constexpr (std::is_signed_v<_Tp>) - check(); - else - check(); - } + constexpr std::size_t array_size = ex::simd_size_v; + std::array expected_value; + for (size_t i = 0; i < array_size; ++i) + expected_value[i] = static_cast(i); + + types::for_each(arithmetic_no_bool_types(), ConversionHelper(expected_value)); } }; @@ -194,9 +171,9 @@ void test_simd_abi() { } int main(int, char**) { - test_all_simd_abi(); - test_all_simd_abi(); - test_all_simd_abi(); + test_all_simd_abi(); + test_all_simd_abi(); + test_all_simd_abi(); test_all_simd_abi(); test_all_simd_abi(); return 0; diff --git a/libcxx/test/std/experimental/simd/test_utils.h b/libcxx/test/std/experimental/simd/test_utils.h index a1c400a2cbbf..97338fb0a2bc 100644 --- a/libcxx/test/std/experimental/simd/test_utils.h +++ b/libcxx/test/std/experimental/simd/test_utils.h @@ -113,4 +113,11 @@ constexpr size_t next_pow2(size_t v) noexcept { v++; return v; } + +template +inline constexpr bool is_non_narrowing_convertible_v = false; + +template +inline constexpr bool is_non_narrowing_convertible_v()})>> = true; + #endif // TEST_UTIL_H \ No newline at end of file