192 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410 11// FIXME: The following issue occurs on Windows to Armv7 Ubuntu Linux:12// Assertion failed: N->getValueType(0) == MVT::v1i1 && "Expected v1i1 type"13// XFAIL: target=armv7-unknown-linux-gnueabihf14 15// FIXME: This should work with -flax-vector-conversions=none16// ADDITIONAL_COMPILE_FLAGS(clang): -flax-vector-conversions=integer17// ADDITIONAL_COMPILE_FLAGS(apple-clang): -flax-vector-conversions=integer18 19// <experimental/simd>20//21// [simd.class]22// simd& operator++() noexcept;23// simd operator++(int) noexcept;24// simd& operator--() noexcept;25// simd operator--(int) noexcept;26// mask_type operator!() const noexcept;27// simd operator~() const noexcept;28// simd operator+() const noexcept;29// simd operator-() const noexcept;30 31#include "../test_utils.h"32#include <experimental/simd>33 34namespace ex = std::experimental::parallelism_v2;35 36template <class T, std::size_t>37struct CheckSimdPrefixIncrementOperator {38 template <class SimdAbi>39 void operator()() {40 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;41 ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });42 static_assert(noexcept(++origin_simd));43 std::array<T, array_size> expected_return_value, expected_value;44 for (size_t i = 0; i < array_size; ++i) {45 expected_return_value[i] = static_cast<T>(i) + 1;46 expected_value[i] = static_cast<T>(i) + 1;47 }48 assert_simd_values_equal<array_size>(++origin_simd, expected_return_value);49 assert_simd_values_equal<array_size>(origin_simd, expected_value);50 }51};52 53template <class T, std::size_t>54struct CheckSimdPostfixIncrementOperator {55 template <class SimdAbi>56 void operator()() {57 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;58 ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });59 static_assert(noexcept(origin_simd++));60 std::array<T, array_size> expected_return_value, expected_value;61 for (size_t i = 0; i < array_size; ++i) {62 expected_return_value[i] = static_cast<T>(i);63 expected_value[i] = static_cast<T>(i) + 1;64 }65 assert_simd_values_equal<array_size>(origin_simd++, expected_return_value);66 assert_simd_values_equal<array_size>(origin_simd, expected_value);67 }68};69 70template <class T, std::size_t>71struct CheckSimdPrefixDecrementOperator {72 template <class SimdAbi>73 void operator()() {74 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;75 ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });76 static_assert(noexcept(--origin_simd));77 std::array<T, array_size> expected_return_value, expected_value;78 for (size_t i = 0; i < array_size; ++i) {79 expected_return_value[i] = static_cast<T>(i) - 1;80 expected_value[i] = static_cast<T>(i) - 1;81 }82 assert_simd_values_equal<array_size>(--origin_simd, expected_return_value);83 assert_simd_values_equal<array_size>(origin_simd, expected_value);84 }85};86 87template <class T, std::size_t>88struct CheckSimdPostfixDecrementOperator {89 template <class SimdAbi>90 void operator()() {91 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;92 ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });93 static_assert(noexcept(origin_simd--));94 std::array<T, array_size> expected_return_value, expected_value;95 for (size_t i = 0; i < array_size; ++i) {96 expected_return_value[i] = static_cast<T>(i);97 expected_value[i] = static_cast<T>(i) - 1;98 }99 assert_simd_values_equal<array_size>(origin_simd--, expected_return_value);100 assert_simd_values_equal<array_size>(origin_simd, expected_value);101 }102};103 104template <class T, std::size_t>105struct CheckSimdNegationOperator {106 template <class SimdAbi>107 void operator()() {108 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;109 ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });110 static_assert(noexcept(!origin_simd));111 std::array<bool, array_size> expected_value;112 for (size_t i = 0; i < array_size; ++i)113 expected_value[i] = !static_cast<bool>(i);114 assert_simd_mask_values_equal<array_size>(!origin_simd, expected_value);115 }116};117 118template <class T, std::size_t>119struct CheckSimdBitwiseNotOperator {120 template <class SimdAbi>121 void operator()() {122 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;123 ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });124 static_assert(noexcept(~origin_simd));125 std::array<T, array_size> expected_value;126 for (size_t i = 0; i < array_size; ++i)127 expected_value[i] = ~static_cast<T>(i);128 assert_simd_values_equal<array_size>(~origin_simd, expected_value);129 }130};131 132template <class T, std::size_t>133struct CheckSimdPositiveSignOperator {134 template <class SimdAbi>135 void operator()() {136 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;137 ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });138 static_assert(noexcept(+origin_simd));139 std::array<T, array_size> expected_value;140 for (size_t i = 0; i < array_size; ++i)141 expected_value[i] = +static_cast<T>(i);142 assert_simd_values_equal<array_size>(+origin_simd, expected_value);143 }144};145 146template <class T, std::size_t>147struct CheckSimdNegativeSignOperator {148 template <class SimdAbi>149 void operator()() {150 constexpr std::size_t array_size = ex::simd_size_v<T, SimdAbi>;151 ex::simd<T, SimdAbi> origin_simd([](T i) { return i; });152 static_assert(noexcept(-origin_simd));153 std::array<T, array_size> expected_value;154 for (size_t i = 0; i < array_size; ++i)155 expected_value[i] = -static_cast<T>(i);156 assert_simd_values_equal<array_size>(-origin_simd, expected_value);157 }158};159 160template <class T, class SimdAbi = ex::simd_abi::compatible<T>, class = void>161struct has_bitwise_not_op : std::false_type {};162 163template <class T, class SimdAbi>164struct has_bitwise_not_op<T, SimdAbi, std::void_t<decltype(~std::declval<ex::simd<T, SimdAbi>>())>> : std::true_type {};165 166template <class T, std::size_t>167struct CheckSimdBitwiseNotTraits {168 template <class SimdAbi>169 void operator()() {170 // This function shall not participate in overload resolution unless171 // T is an integral type.172 if constexpr (std::is_integral_v<T>)173 static_assert(has_bitwise_not_op<T, SimdAbi>::value);174 // T is not an integral type.175 else176 static_assert(!has_bitwise_not_op<T, SimdAbi>::value);177 }178};179 180int main(int, char**) {181 test_all_simd_abi<CheckSimdPrefixIncrementOperator>();182 test_all_simd_abi<CheckSimdPostfixIncrementOperator>();183 test_all_simd_abi<CheckSimdPrefixDecrementOperator>();184 test_all_simd_abi<CheckSimdPostfixDecrementOperator>();185 test_all_simd_abi<CheckSimdNegationOperator>();186 types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckSimdBitwiseNotOperator>());187 test_all_simd_abi<CheckSimdPositiveSignOperator>();188 test_all_simd_abi<CheckSimdNegativeSignOperator>();189 test_all_simd_abi<CheckSimdBitwiseNotTraits>();190 return 0;191}192