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/string/memory_utils/elements.h"
11 #include "utils/UnitTest/Test.h"
12 
13 namespace __llvm_libc {
14 
15 // Registering Types
16 using FixedSizeTypes = testing::TypeList<
17 #ifdef __SSE2__
18     x86::Vector128, //
19 #endif              // __SSE2__
20 #ifdef __AVX2__
21     x86::Vector256, //
22 #endif              // __AVX2__
23 #if defined(__AVX512F__) and defined(__AVX512BW__)
24     x86::Vector512, //
25 #endif              // defined(__AVX512F__) and defined(__AVX512BW__)
26     scalar::UINT8,  //
27     scalar::UINT16, //
28     scalar::UINT32, //
29     scalar::UINT64, //
30     Repeated<scalar::UINT64, 2>,                            //
31     Repeated<scalar::UINT64, 4>,                            //
32     Repeated<scalar::UINT64, 8>,                            //
33     Repeated<scalar::UINT64, 16>,                           //
34     Repeated<scalar::UINT64, 32>,                           //
35     Chained<scalar::UINT16, scalar::UINT8>,                 //
36     Chained<scalar::UINT32, scalar::UINT16, scalar::UINT8>, //
37     builtin::_1,                                            //
38     builtin::_2,                                            //
39     builtin::_3,                                            //
40     builtin::_4,                                            //
41     builtin::_8                                             //
42     >;
43 
44 char GetRandomChar() {
45   static constexpr const uint64_t a = 1103515245;
46   static constexpr const uint64_t c = 12345;
47   static constexpr const uint64_t m = 1ULL << 31;
48   static uint64_t seed = 123456789;
49   seed = (a * seed + c) % m;
50   return seed;
51 }
52 
53 template <typename Element> using Buffer = cpp::Array<char, Element::kSize>;
54 template <typename Element> Buffer<Element> GetRandomBuffer() {
55   Buffer<Element> buffer;
56   for (auto &current : buffer)
57     current = GetRandomChar();
58   return buffer;
59 }
60 
61 TYPED_TEST(LlvmLibcMemoryElements, Copy, FixedSizeTypes) {
62   Buffer<ParamType> Dst;
63   const auto buffer = GetRandomBuffer<ParamType>();
64   Copy<ParamType>(Dst.data(), buffer.data());
65   for (size_t i = 0; i < ParamType::kSize; ++i)
66     EXPECT_EQ(Dst[i], buffer[i]);
67 }
68 
69 TYPED_TEST(LlvmLibcMemoryElements, Equals, FixedSizeTypes) {
70   const auto buffer = GetRandomBuffer<ParamType>();
71   EXPECT_TRUE(Equals<ParamType>(buffer.data(), buffer.data()));
72 }
73 
74 TYPED_TEST(LlvmLibcMemoryElements, ThreeWayCompare, FixedSizeTypes) {
75   Buffer<ParamType> initial;
76   for (auto &c : initial)
77     c = 5;
78 
79   // Testing equality
80   EXPECT_EQ(ThreeWayCompare<ParamType>(initial.data(), initial.data()), 0);
81 
82   // Testing all mismatching positions
83   for (size_t i = 0; i < ParamType::kSize; ++i) {
84     auto copy = initial;
85     ++copy[i]; // Copy is now lexicographycally greated than initial
86     const auto *less = initial.data();
87     const auto *greater = copy.data();
88     EXPECT_LT(ThreeWayCompare<ParamType>(less, greater), 0);
89     EXPECT_GT(ThreeWayCompare<ParamType>(greater, less), 0);
90   }
91 }
92 
93 TYPED_TEST(LlvmLibcMemoryElements, Splat, FixedSizeTypes) {
94   Buffer<ParamType> Dst;
95   const cpp::Array<char, 3> values = {char(0x00), char(0x7F), char(0xFF)};
96   for (char value : values) {
97     SplatSet<ParamType>(Dst.data(), value);
98     for (size_t i = 0; i < ParamType::kSize; ++i)
99       EXPECT_EQ(Dst[i], value);
100   }
101 }
102 
103 } // namespace __llvm_libc
104