1 //===-- Unittests for memory_utils ----------------------------------------===// 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 #include "src/__support/CPP/Array.h" 10 #include "src/__support/CPP/ArrayRef.h" 11 #include "src/string/memory_utils/elements.h" 12 #include "utils/UnitTest/Test.h" 13 14 namespace __llvm_libc { 15 16 // Registering Types 17 using FixedSizeTypes = testing::TypeList< 18 #if defined(__SSE2__) 19 x86::Vector128, // 20 #endif // __SSE2__ 21 #if defined(__AVX2__) 22 x86::Vector256, // 23 #endif // __AVX2__ 24 #if defined(__AVX512F__) and defined(__AVX512BW__) 25 x86::Vector512, // 26 #endif // defined(__AVX512F__) and defined(__AVX512BW__) 27 scalar::UINT8, // 28 scalar::UINT16, // 29 scalar::UINT32, // 30 scalar::UINT64, // 31 Repeated<scalar::UINT64, 2>, // 32 Repeated<scalar::UINT64, 4>, // 33 Repeated<scalar::UINT64, 8>, // 34 Repeated<scalar::UINT64, 16>, // 35 Repeated<scalar::UINT64, 32>, // 36 Chained<scalar::UINT16, scalar::UINT8>, // 37 Chained<scalar::UINT32, scalar::UINT16, scalar::UINT8>, // 38 builtin::_1, // 39 builtin::_2, // 40 builtin::_3, // 41 builtin::_4, // 42 builtin::_8 // 43 >; 44 45 char GetRandomChar() { 46 static constexpr const uint64_t a = 1103515245; 47 static constexpr const uint64_t c = 12345; 48 static constexpr const uint64_t m = 1ULL << 31; 49 static uint64_t seed = 123456789; 50 seed = (a * seed + c) % m; 51 return seed; 52 } 53 54 void Randomize(cpp::MutableArrayRef<char> buffer) { 55 for (auto ¤t : buffer) 56 current = GetRandomChar(); 57 } 58 59 template <typename Element> using Buffer = cpp::Array<char, Element::SIZE>; 60 61 template <typename Element> Buffer<Element> GetRandomBuffer() { 62 Buffer<Element> buffer; 63 Randomize(buffer); 64 return buffer; 65 } 66 67 TYPED_TEST(LlvmLibcMemoryElements, copy, FixedSizeTypes) { 68 Buffer<ParamType> Dst; 69 const auto buffer = GetRandomBuffer<ParamType>(); 70 copy<ParamType>(Dst.data(), buffer.data()); 71 for (size_t i = 0; i < ParamType::SIZE; ++i) 72 EXPECT_EQ(Dst[i], buffer[i]); 73 } 74 75 template <typename T> T copy(const T &Input) { 76 T Output; 77 for (size_t I = 0; I < Input.size(); ++I) 78 Output[I] = Input[I]; 79 return Output; 80 } 81 82 TYPED_TEST(LlvmLibcMemoryElements, Move, FixedSizeTypes) { 83 constexpr size_t SIZE = ParamType::SIZE; 84 using LargeBuffer = cpp::Array<char, SIZE * 2>; 85 LargeBuffer GroundTruth; 86 Randomize(GroundTruth); 87 // Forward, we move the SIZE first bytes from offset 0 to SIZE. 88 for (size_t Offset = 0; Offset < SIZE; ++Offset) { 89 LargeBuffer Buffer = copy(GroundTruth); 90 move<ParamType>(&Buffer[Offset], &Buffer[0]); 91 for (size_t I = 0; I < SIZE; ++I) 92 EXPECT_EQ(Buffer[I + Offset], GroundTruth[I]); 93 } 94 // Backward, we move the SIZE last bytes from offset 0 to SIZE. 95 for (size_t Offset = 0; Offset < SIZE; ++Offset) { 96 LargeBuffer Buffer = copy(GroundTruth); 97 move<ParamType>(&Buffer[Offset], &Buffer[SIZE]); 98 for (size_t I = 0; I < SIZE; ++I) 99 EXPECT_EQ(Buffer[I + Offset], GroundTruth[SIZE + I]); 100 } 101 } 102 103 TYPED_TEST(LlvmLibcMemoryElements, Equals, FixedSizeTypes) { 104 const auto buffer = GetRandomBuffer<ParamType>(); 105 EXPECT_TRUE(equals<ParamType>(buffer.data(), buffer.data())); 106 } 107 108 TYPED_TEST(LlvmLibcMemoryElements, three_way_compare, FixedSizeTypes) { 109 Buffer<ParamType> initial; 110 for (auto &c : initial) 111 c = 5; 112 113 // Testing equality 114 EXPECT_EQ(three_way_compare<ParamType>(initial.data(), initial.data()), 0); 115 116 // Testing all mismatching positions 117 for (size_t i = 0; i < ParamType::SIZE; ++i) { 118 auto copy = initial; 119 ++copy[i]; // copy is now lexicographycally greated than initial 120 const auto *less = initial.data(); 121 const auto *greater = copy.data(); 122 EXPECT_LT(three_way_compare<ParamType>(less, greater), 0); 123 EXPECT_GT(three_way_compare<ParamType>(greater, less), 0); 124 } 125 } 126 127 TYPED_TEST(LlvmLibcMemoryElements, Splat, FixedSizeTypes) { 128 Buffer<ParamType> Dst; 129 const cpp::Array<char, 3> values = {char(0x00), char(0x7F), char(0xFF)}; 130 for (char value : values) { 131 splat_set<ParamType>(Dst.data(), value); 132 for (size_t i = 0; i < ParamType::SIZE; ++i) 133 EXPECT_EQ(Dst[i], value); 134 } 135 } 136 137 } // namespace __llvm_libc 138