//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 // Older versions of clang may encounter a backend error (see 0295c2ad): // Pass-by-value arguments with alignment greater than register width are not supported. // XFAIL: target=powerpc{{.*}}-ibm-{{.*}} && clang-18 // This test crashes AppleClang 15 but not later versions. // UNSUPPORTED: apple-clang-15 // FIXME: The following issue occurs on Windows to Armv7 Ubuntu Linux: // Assertion failed: N->getValueType(0) == MVT::v1i1 && "Expected v1i1 type" // XFAIL: target=armv7-unknown-linux-gnueabihf // // // [simd.class] // simd& operator++() noexcept; // simd operator++(int) noexcept; // simd& operator--() noexcept; // simd operator--(int) noexcept; // mask_type operator!() const noexcept; // simd operator~() const noexcept; // simd operator+() const noexcept; // simd operator-() const noexcept; #include "../test_utils.h" #include namespace ex = std::experimental::parallelism_v2; template struct CheckSimdPrefixIncrementOperator { template void operator()() { constexpr std::size_t array_size = ex::simd_size_v; ex::simd origin_simd([](T i) { return i; }); static_assert(noexcept(++origin_simd)); std::array expected_return_value, expected_value; for (size_t i = 0; i < array_size; ++i) { expected_return_value[i] = static_cast(i) + 1; expected_value[i] = static_cast(i) + 1; } assert_simd_values_equal(++origin_simd, expected_return_value); assert_simd_values_equal(origin_simd, expected_value); } }; template struct CheckSimdPostfixIncrementOperator { template void operator()() { constexpr std::size_t array_size = ex::simd_size_v; ex::simd origin_simd([](T i) { return i; }); static_assert(noexcept(origin_simd++)); std::array expected_return_value, expected_value; for (size_t i = 0; i < array_size; ++i) { expected_return_value[i] = static_cast(i); expected_value[i] = static_cast(i) + 1; } assert_simd_values_equal(origin_simd++, expected_return_value); assert_simd_values_equal(origin_simd, expected_value); } }; template struct CheckSimdPrefixDecrementOperator { template void operator()() { constexpr std::size_t array_size = ex::simd_size_v; ex::simd origin_simd([](T i) { return i; }); static_assert(noexcept(--origin_simd)); std::array expected_return_value, expected_value; for (size_t i = 0; i < array_size; ++i) { expected_return_value[i] = static_cast(i) - 1; expected_value[i] = static_cast(i) - 1; } assert_simd_values_equal(--origin_simd, expected_return_value); assert_simd_values_equal(origin_simd, expected_value); } }; template struct CheckSimdPostfixDecrementOperator { template void operator()() { constexpr std::size_t array_size = ex::simd_size_v; ex::simd origin_simd([](T i) { return i; }); static_assert(noexcept(origin_simd--)); std::array expected_return_value, expected_value; for (size_t i = 0; i < array_size; ++i) { expected_return_value[i] = static_cast(i); expected_value[i] = static_cast(i) - 1; } assert_simd_values_equal(origin_simd--, expected_return_value); assert_simd_values_equal(origin_simd, expected_value); } }; template struct CheckSimdNegationOperator { template void operator()() { constexpr std::size_t array_size = ex::simd_size_v; ex::simd origin_simd([](T i) { return i; }); static_assert(noexcept(!origin_simd)); std::array expected_value; for (size_t i = 0; i < array_size; ++i) expected_value[i] = !static_cast(i); assert_simd_mask_values_equal(!origin_simd, expected_value); } }; template struct CheckSimdBitwiseNotOperator { template void operator()() { constexpr std::size_t array_size = ex::simd_size_v; ex::simd origin_simd([](T i) { return i; }); static_assert(noexcept(~origin_simd)); std::array expected_value; for (size_t i = 0; i < array_size; ++i) expected_value[i] = ~static_cast(i); assert_simd_values_equal(~origin_simd, expected_value); } }; template struct CheckSimdPositiveSignOperator { template void operator()() { constexpr std::size_t array_size = ex::simd_size_v; ex::simd origin_simd([](T i) { return i; }); static_assert(noexcept(+origin_simd)); std::array expected_value; for (size_t i = 0; i < array_size; ++i) expected_value[i] = +static_cast(i); assert_simd_values_equal(+origin_simd, expected_value); } }; template struct CheckSimdNegativeSignOperator { template void operator()() { constexpr std::size_t array_size = ex::simd_size_v; ex::simd origin_simd([](T i) { return i; }); static_assert(noexcept(-origin_simd)); std::array expected_value; for (size_t i = 0; i < array_size; ++i) expected_value[i] = -static_cast(i); assert_simd_values_equal(-origin_simd, expected_value); } }; template , class = void> struct has_bitwise_not_op : std::false_type {}; template struct has_bitwise_not_op>())>> : std::true_type {}; template struct CheckSimdBitwiseNotTraits { template void operator()() { // This function shall not participate in overload resolution unless // T is an integral type. if constexpr (std::is_integral_v) static_assert(has_bitwise_not_op::value); // T is not an integral type. else static_assert(!has_bitwise_not_op::value); } }; int main(int, char**) { test_all_simd_abi(); test_all_simd_abi(); test_all_simd_abi(); test_all_simd_abi(); test_all_simd_abi(); types::for_each(types::integer_types(), TestAllSimdAbiFunctor()); test_all_simd_abi(); test_all_simd_abi(); test_all_simd_abi(); return 0; }