/
GitCaptain
/
llvm-project
Обзор
Документация
Войти
/
GitCaptain
/
llvm-project
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
fix-tests
libc/test/src/string/memory_utils/backend_test.cpp
197 строк
7 KB
Siva Chandra Reddy
[libc][Obvious] Compare values of the same type in memory_utils/backend_test.
25 июн 2022, 07:50
25 июн 2022, 07:50
a83034e
Код
Авторство
О чём код?
//===-- Unittests for backends --------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "src/__support/CPP/Array.h" #include "src/__support/CPP/ArrayRef.h" #include "src/__support/CPP/Bit.h" #include "src/__support/architectures.h" #include "src/string/memory_utils/backends.h" #include "utils/UnitTest/Test.h" #include <string.h> namespace __llvm_libc { template <size_t Size> using Buffer = cpp::Array<char, Size>; static char GetRandomChar() { // Implementation of C++ minstd_rand seeded with 123456789. // https://en.cppreference.com/w/cpp/numeric/random // "Minimum standard", recommended by Park, Miller, and Stockmeyer in 1993 static constexpr const uint64_t a = 48271; static constexpr const uint64_t c = 0; static constexpr const uint64_t m = 2147483647; static uint64_t seed = 123456789; seed = (a * seed + c) % m; return seed; } static void Randomize(cpp::MutableArrayRef<char> buffer) { for (auto ¤t : buffer) current = GetRandomChar(); } template <size_t Size> static Buffer<Size> GetRandomBuffer() { Buffer<Size> buffer; Randomize(buffer); return buffer; } template <typename Backend, size_t Size> struct Conf { static_assert(Backend::IS_BACKEND_TYPE); using BufferT = Buffer<Size>; using T = typename Backend::template getNextType<Size>; static_assert(sizeof(T) == Size); static constexpr size_t SIZE = Size; static BufferT splat(ubyte value) { return bit_cast<BufferT>(Backend::template splat<T>(value)); } static uint64_t notEquals(const BufferT &v1, const BufferT &v2) { return Backend::template notEquals<T>(bit_cast<T>(v1), bit_cast<T>(v2)); } static int32_t threeWayCmp(const BufferT &v1, const BufferT &v2) { return Backend::template threeWayCmp<T>(bit_cast<T>(v1), bit_cast<T>(v2)); } }; using FunctionTypes = testing::TypeList< // #if defined(LLVM_LIBC_ARCH_X86) // Conf<X86Backend, 1>, // Conf<X86Backend, 2>, // Conf<X86Backend, 4>, // Conf<X86Backend, 8>, // #if HAS_M128 Conf<X86Backend, 16>, // #endif #if HAS_M256 Conf<X86Backend, 32>, // #endif #if HAS_M512 Conf<X86Backend, 64>, // #endif #endif // defined(LLVM_LIBC_ARCH_X86) Conf<Scalar64BitBackend, 1>, // Conf<Scalar64BitBackend, 2>, // Conf<Scalar64BitBackend, 4>, // Conf<Scalar64BitBackend, 8> // >; TYPED_TEST(LlvmLibcMemoryBackend, splat, FunctionTypes) { for (auto value : cpp::Array<uint8_t, 3>{0u, 1u, 255u}) { alignas(64) const auto stored = ParamType::splat(bit_cast<ubyte>(value)); for (size_t i = 0; i < ParamType::SIZE; ++i) EXPECT_EQ(bit_cast<uint8_t>(stored[i]), value); } } TYPED_TEST(LlvmLibcMemoryBackend, notEquals, FunctionTypes) { alignas(64) const auto a = GetRandomBuffer<ParamType::SIZE>(); EXPECT_EQ(ParamType::notEquals(a, a), uint64_t(0)); for (size_t i = 0; i < a.size(); ++i) { alignas(64) auto b = a; ++b[i]; EXPECT_NE(ParamType::notEquals(a, b), uint64_t(0)); EXPECT_NE(ParamType::notEquals(b, a), uint64_t(0)); } } TYPED_TEST(LlvmLibcMemoryBackend, threeWayCmp, FunctionTypes) { alignas(64) const auto a = GetRandomBuffer<ParamType::SIZE>(); EXPECT_EQ(ParamType::threeWayCmp(a, a), 0); for (size_t i = 0; i < a.size(); ++i) { alignas(64) auto b = a; ++b[i]; const auto cmp = memcmp(&a, &b, sizeof(a)); ASSERT_NE(cmp, 0); if (cmp > 0) { EXPECT_GT(ParamType::threeWayCmp(a, b), 0); EXPECT_LT(ParamType::threeWayCmp(b, a), 0); } else { EXPECT_LT(ParamType::threeWayCmp(a, b), 0); EXPECT_GT(ParamType::threeWayCmp(b, a), 0); } } } template <typename Backend, size_t Size, Temporality TS, Aligned AS> struct LoadStoreConf { static_assert(Backend::IS_BACKEND_TYPE); using BufferT = Buffer<Size>; using T = typename Backend::template getNextType<Size>; static_assert(sizeof(T) == Size); static constexpr size_t SIZE = Size; static BufferT load(const BufferT &ref) { const auto *ptr = bit_cast<const T *>(ref.data()); const T value = Backend::template load<T, TS, AS>(ptr); return bit_cast<BufferT>(value); } static void store(BufferT &ref, const BufferT value) { auto *ptr = bit_cast<T *>(ref.data()); Backend::template store<T, TS, AS>(ptr, bit_cast<T>(value)); } }; using LoadStoreTypes = testing::TypeList< // #if defined(LLVM_LIBC_ARCH_X86) // LoadStoreConf<X86Backend, 1, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<X86Backend, 1, Temporality::TEMPORAL, Aligned::YES>, // LoadStoreConf<X86Backend, 2, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<X86Backend, 2, Temporality::TEMPORAL, Aligned::YES>, // LoadStoreConf<X86Backend, 4, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<X86Backend, 4, Temporality::TEMPORAL, Aligned::YES>, // LoadStoreConf<X86Backend, 8, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<X86Backend, 8, Temporality::TEMPORAL, Aligned::YES>, // #if HAS_M128 LoadStoreConf<X86Backend, 16, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<X86Backend, 16, Temporality::TEMPORAL, Aligned::YES>, // LoadStoreConf<X86Backend, 16, Temporality::NON_TEMPORAL, Aligned::YES>, // #endif #if HAS_M256 LoadStoreConf<X86Backend, 32, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<X86Backend, 32, Temporality::TEMPORAL, Aligned::YES>, // LoadStoreConf<X86Backend, 32, Temporality::NON_TEMPORAL, Aligned::YES>, // #endif #if HAS_M512 LoadStoreConf<X86Backend, 64, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<X86Backend, 64, Temporality::TEMPORAL, Aligned::YES>, // LoadStoreConf<X86Backend, 64, Temporality::NON_TEMPORAL, Aligned::YES>, // #endif #endif // defined(LLVM_LIBC_ARCH_X86) LoadStoreConf<Scalar64BitBackend, 1, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<Scalar64BitBackend, 1, Temporality::TEMPORAL, Aligned::YES>, // LoadStoreConf<Scalar64BitBackend, 2, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<Scalar64BitBackend, 2, Temporality::TEMPORAL, Aligned::YES>, // LoadStoreConf<Scalar64BitBackend, 4, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<Scalar64BitBackend, 4, Temporality::TEMPORAL, Aligned::YES>, // LoadStoreConf<Scalar64BitBackend, 8, Temporality::TEMPORAL, Aligned::NO>, // LoadStoreConf<Scalar64BitBackend, 8, Temporality::TEMPORAL, Aligned::YES> // >; TYPED_TEST(LlvmLibcMemoryBackend, load, LoadStoreTypes) { alignas(64) const auto expected = GetRandomBuffer<ParamType::SIZE>(); const auto loaded = ParamType::load(expected); for (size_t i = 0; i < ParamType::SIZE; ++i) EXPECT_EQ(loaded[i], expected[i]); } TYPED_TEST(LlvmLibcMemoryBackend, store, LoadStoreTypes) { alignas(64) const auto expected = GetRandomBuffer<ParamType::SIZE>(); alignas(64) typename ParamType::BufferT stored; ParamType::store(stored, expected); for (size_t i = 0; i < ParamType::SIZE; ++i) EXPECT_EQ(stored[i], expected[i]); } } // namespace __llvm_libc