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/macros/config.h" 11 #include "src/string/memory_utils/utils.h" 12 #include "test/UnitTest/Test.h" 13 14 namespace LIBC_NAMESPACE_DECL { 15 16 using UINT = uintptr_t; 17 18 // Converts an offset into a pointer. 19 const void *forge(size_t offset) { 20 return reinterpret_cast<const void *>(offset); 21 } 22 23 TEST(LlvmLibcUtilsTest, DistanceToNextAligned) { 24 EXPECT_EQ(distance_to_next_aligned<16>(forge(0)), UINT(16)); 25 EXPECT_EQ(distance_to_next_aligned<16>(forge(1)), UINT(15)); 26 EXPECT_EQ(distance_to_next_aligned<16>(forge(16)), UINT(16)); 27 EXPECT_EQ(distance_to_next_aligned<16>(forge(15)), UINT(1)); 28 EXPECT_EQ(distance_to_next_aligned<32>(forge(16)), UINT(16)); 29 } 30 31 TEST(LlvmLibcUtilsTest, DistanceToAlignUp) { 32 EXPECT_EQ(distance_to_align_up<16>(forge(0)), UINT(0)); 33 EXPECT_EQ(distance_to_align_up<16>(forge(1)), UINT(15)); 34 EXPECT_EQ(distance_to_align_up<16>(forge(16)), UINT(0)); 35 EXPECT_EQ(distance_to_align_up<16>(forge(15)), UINT(1)); 36 EXPECT_EQ(distance_to_align_up<32>(forge(16)), UINT(16)); 37 } 38 39 TEST(LlvmLibcUtilsTest, DistanceToAlignDown) { 40 EXPECT_EQ(distance_to_align_down<16>(forge(0)), UINT(0)); 41 EXPECT_EQ(distance_to_align_down<16>(forge(1)), UINT(1)); 42 EXPECT_EQ(distance_to_align_down<16>(forge(16)), UINT(0)); 43 EXPECT_EQ(distance_to_align_down<16>(forge(15)), UINT(15)); 44 EXPECT_EQ(distance_to_align_down<32>(forge(16)), UINT(16)); 45 } 46 47 TEST(LlvmLibcUtilsTest, Adjust2) { 48 char a, b; 49 const size_t base_size = 10; 50 for (ptrdiff_t I = -2; I < 2; ++I) { 51 auto *p1 = &a; 52 auto *p2 = &b; 53 size_t size = base_size; 54 adjust(I, p1, p2, size); 55 EXPECT_EQ(intptr_t(p1), intptr_t(&a + I)); 56 EXPECT_EQ(intptr_t(p2), intptr_t(&b + I)); 57 EXPECT_EQ(size, base_size - I); 58 } 59 } 60 61 TEST(LlvmLibcUtilsTest, Align2) { 62 char a, b; 63 const size_t base_size = 10; 64 { 65 auto *p1 = &a; 66 auto *p2 = &b; 67 size_t size = base_size; 68 align_to_next_boundary<128, Arg::P1>(p1, p2, size); 69 EXPECT_TRUE(uintptr_t(p1) % 128 == 0); 70 EXPECT_GT(p1, &a); 71 EXPECT_GT(p2, &b); 72 EXPECT_EQ(size_t(p1 - &a), base_size - size); 73 EXPECT_EQ(size_t(p2 - &b), base_size - size); 74 } 75 { 76 auto *p1 = &a; 77 auto *p2 = &b; 78 size_t size = base_size; 79 align_to_next_boundary<128, Arg::P2>(p1, p2, size); 80 EXPECT_TRUE(uintptr_t(p2) % 128 == 0); 81 EXPECT_GT(p1, &a); 82 EXPECT_GT(p2, &b); 83 EXPECT_EQ(size_t(p1 - &a), base_size - size); 84 EXPECT_EQ(size_t(p2 - &b), base_size - size); 85 } 86 } 87 88 TEST(LlvmLibcUtilsTest, DisjointBuffers) { 89 char buf[3]; 90 const char *const a = buf + 0; 91 const char *const b = buf + 1; 92 EXPECT_TRUE(is_disjoint(a, b, 0)); 93 EXPECT_TRUE(is_disjoint(a, b, 1)); 94 EXPECT_FALSE(is_disjoint(a, b, 2)); 95 96 EXPECT_TRUE(is_disjoint(b, a, 0)); 97 EXPECT_TRUE(is_disjoint(b, a, 1)); 98 EXPECT_FALSE(is_disjoint(b, a, 2)); 99 } 100 101 TEST(LlvmLibcUtilsTest, LoadStoreAligned) { 102 const uint64_t init = 0xDEAD'C0DE'BEEF'F00D; 103 CPtr const src = reinterpret_cast<CPtr>(&init); 104 uint64_t store; 105 Ptr const dst = reinterpret_cast<Ptr>(&store); 106 107 using LoadFun = uint64_t (*)(CPtr); 108 using StoreFun = void (*)(uint64_t, Ptr); 109 110 { 111 LoadFun ld = load_aligned<uint64_t, uint64_t>; 112 StoreFun st = store_aligned<uint64_t, uint64_t>; 113 const uint64_t loaded = ld(src); 114 EXPECT_EQ(init, loaded); 115 store = 0; 116 st(init, dst); 117 EXPECT_EQ(init, store); 118 } 119 120 { 121 LoadFun ld = load_aligned<uint64_t, uint32_t, uint32_t>; 122 StoreFun st = store_aligned<uint64_t, uint32_t, uint32_t>; 123 const uint64_t loaded = ld(src); 124 EXPECT_EQ(init, loaded); 125 store = 0; 126 st(init, dst); 127 EXPECT_EQ(init, store); 128 } 129 130 { 131 LoadFun ld = load_aligned<uint64_t, uint32_t, uint16_t, uint8_t, uint8_t>; 132 StoreFun st = store_aligned<uint64_t, uint32_t, uint16_t, uint8_t, uint8_t>; 133 const uint64_t loaded = ld(src); 134 EXPECT_EQ(init, loaded); 135 store = 0; 136 st(init, dst); 137 EXPECT_EQ(init, store); 138 } 139 } 140 141 } // namespace LIBC_NAMESPACE_DECL 142