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/utils.h"
11 #include "utils/UnitTest/Test.h"
12
13 namespace __llvm_libc {
14
TEST(LlvmLibcUtilsTest,IsPowerOfTwoOrZero)15 TEST(LlvmLibcUtilsTest, IsPowerOfTwoOrZero) {
16 static const cpp::Array<bool, 65> kExpectedValues{
17 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 0-15
18 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
19 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47
20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 48-63
21 1 // 64
22 };
23 for (size_t i = 0; i < kExpectedValues.size(); ++i)
24 EXPECT_EQ(is_power2_or_zero(i), kExpectedValues[i]);
25 }
26
TEST(LlvmLibcUtilsTest,IsPowerOfTwo)27 TEST(LlvmLibcUtilsTest, IsPowerOfTwo) {
28 static const cpp::Array<bool, 65> kExpectedValues{
29 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 0-15
30 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
31 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47
32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 48-63
33 1 // 64
34 };
35 for (size_t i = 0; i < kExpectedValues.size(); ++i)
36 EXPECT_EQ(is_power2(i), kExpectedValues[i]);
37 }
38
TEST(LlvmLibcUtilsTest,Log2)39 TEST(LlvmLibcUtilsTest, Log2) {
40 static const cpp::Array<size_t, 65> kExpectedValues{
41 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, // 0-15
42 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 16-31
43 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 32-47
44 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 48-63
45 6 // 64
46 };
47 for (size_t i = 0; i < kExpectedValues.size(); ++i)
48 EXPECT_EQ(log2(i), kExpectedValues[i]);
49 }
50
TEST(LlvmLibcUtilsTest,LEPowerOf2)51 TEST(LlvmLibcUtilsTest, LEPowerOf2) {
52 static const cpp::Array<size_t, 65> kExpectedValues{
53 0, 1, 2, 2, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, // 0-15
54 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, // 16-31
55 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 32-47
56 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 48-63
57 64 // 64
58 };
59 for (size_t i = 0; i < kExpectedValues.size(); ++i)
60 EXPECT_EQ(le_power2(i), kExpectedValues[i]);
61 }
62
TEST(LlvmLibcUtilsTest,GEPowerOf2)63 TEST(LlvmLibcUtilsTest, GEPowerOf2) {
64 static const cpp::Array<size_t, 66> kExpectedValues{
65 0, 1, 2, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, // 0-15
66 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 16-31
67 32, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 32-47
68 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 48-63
69 64, 128 // 64-65
70 };
71 for (size_t i = 0; i < kExpectedValues.size(); ++i)
72 EXPECT_EQ(ge_power2(i), kExpectedValues[i]);
73 }
74
75 using I = intptr_t;
76
77 // Converts an offset into a pointer.
forge(size_t offset)78 const void *forge(size_t offset) {
79 return reinterpret_cast<const void *>(offset);
80 }
81
TEST(LlvmLibcUtilsTest,OffsetToNextAligned)82 TEST(LlvmLibcUtilsTest, OffsetToNextAligned) {
83 EXPECT_EQ(offset_to_next_aligned<16>(forge(0)), I(0));
84 EXPECT_EQ(offset_to_next_aligned<16>(forge(1)), I(15));
85 EXPECT_EQ(offset_to_next_aligned<16>(forge(16)), I(0));
86 EXPECT_EQ(offset_to_next_aligned<16>(forge(15)), I(1));
87 EXPECT_EQ(offset_to_next_aligned<32>(forge(16)), I(16));
88 }
89
TEST(LlvmLibcUtilsTest,OffsetFromLastAligned)90 TEST(LlvmLibcUtilsTest, OffsetFromLastAligned) {
91 EXPECT_EQ(offset_from_last_aligned<16>(forge(0)), I(0));
92 EXPECT_EQ(offset_from_last_aligned<16>(forge(1)), I(1));
93 EXPECT_EQ(offset_from_last_aligned<16>(forge(16)), I(0));
94 EXPECT_EQ(offset_from_last_aligned<16>(forge(15)), I(15));
95 EXPECT_EQ(offset_from_last_aligned<32>(forge(16)), I(16));
96 }
97
TEST(LlvmLibcUtilsTest,OffsetToNextCacheLine)98 TEST(LlvmLibcUtilsTest, OffsetToNextCacheLine) {
99 EXPECT_GT(LLVM_LIBC_CACHELINE_SIZE, 0);
100 EXPECT_EQ(offset_to_next_cache_line(forge(0)), I(0));
101 EXPECT_EQ(offset_to_next_cache_line(forge(1)),
102 I(LLVM_LIBC_CACHELINE_SIZE - 1));
103 EXPECT_EQ(offset_to_next_cache_line(forge(LLVM_LIBC_CACHELINE_SIZE)), I(0));
104 EXPECT_EQ(offset_to_next_cache_line(forge(LLVM_LIBC_CACHELINE_SIZE - 1)),
105 I(1));
106 }
107 } // namespace __llvm_libc
108