xref: /llvm-project/libc/test/src/string/memory_utils/utils_test.cpp (revision 5ff3ff33ff930e4ec49da7910612d8a41eb068cb)
166d00febSPaula Toth //===-- Unittests for memory_utils ----------------------------------------===//
285314e9bSGuillaume Chatelet //
385314e9bSGuillaume Chatelet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
485314e9bSGuillaume Chatelet // See https://llvm.org/LICENSE.txt for license information.
585314e9bSGuillaume Chatelet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
685314e9bSGuillaume Chatelet //
785314e9bSGuillaume Chatelet //===----------------------------------------------------------------------===//
885314e9bSGuillaume Chatelet 
9d3d498fbSGuillaume Chatelet #include "src/__support/CPP/array.h"
10*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h"
1185314e9bSGuillaume Chatelet #include "src/string/memory_utils/utils.h"
12af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h"
1385314e9bSGuillaume Chatelet 
14*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
1585314e9bSGuillaume Chatelet 
16a786096fSGuillaume Chatelet using UINT = uintptr_t;
1785314e9bSGuillaume Chatelet 
1885314e9bSGuillaume Chatelet // Converts an offset into a pointer.
1985314e9bSGuillaume Chatelet const void *forge(size_t offset) {
2085314e9bSGuillaume Chatelet   return reinterpret_cast<const void *>(offset);
21961aeb7aSGuillaume Chatelet }
2285314e9bSGuillaume Chatelet 
23a786096fSGuillaume Chatelet TEST(LlvmLibcUtilsTest, DistanceToNextAligned) {
24a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_next_aligned<16>(forge(0)), UINT(16));
25a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_next_aligned<16>(forge(1)), UINT(15));
26a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_next_aligned<16>(forge(16)), UINT(16));
27a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_next_aligned<16>(forge(15)), UINT(1));
28a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_next_aligned<32>(forge(16)), UINT(16));
2985314e9bSGuillaume Chatelet }
3085314e9bSGuillaume Chatelet 
31a786096fSGuillaume Chatelet TEST(LlvmLibcUtilsTest, DistanceToAlignUp) {
32a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_align_up<16>(forge(0)), UINT(0));
33a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_align_up<16>(forge(1)), UINT(15));
34a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_align_up<16>(forge(16)), UINT(0));
35a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_align_up<16>(forge(15)), UINT(1));
36a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_align_up<32>(forge(16)), UINT(16));
3704a309ddSGuillaume Chatelet }
3804a309ddSGuillaume Chatelet 
39a786096fSGuillaume Chatelet TEST(LlvmLibcUtilsTest, DistanceToAlignDown) {
40a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_align_down<16>(forge(0)), UINT(0));
41a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_align_down<16>(forge(1)), UINT(1));
42a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_align_down<16>(forge(16)), UINT(0));
43a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_align_down<16>(forge(15)), UINT(15));
44a786096fSGuillaume Chatelet   EXPECT_EQ(distance_to_align_down<32>(forge(16)), UINT(16));
45060a43ceSGuillaume Chatelet }
46060a43ceSGuillaume Chatelet 
47060a43ceSGuillaume Chatelet TEST(LlvmLibcUtilsTest, Adjust2) {
48060a43ceSGuillaume Chatelet   char a, b;
49060a43ceSGuillaume Chatelet   const size_t base_size = 10;
50a786096fSGuillaume Chatelet   for (ptrdiff_t I = -2; I < 2; ++I) {
51060a43ceSGuillaume Chatelet     auto *p1 = &a;
52060a43ceSGuillaume Chatelet     auto *p2 = &b;
53060a43ceSGuillaume Chatelet     size_t size = base_size;
54060a43ceSGuillaume Chatelet     adjust(I, p1, p2, size);
55060a43ceSGuillaume Chatelet     EXPECT_EQ(intptr_t(p1), intptr_t(&a + I));
56060a43ceSGuillaume Chatelet     EXPECT_EQ(intptr_t(p2), intptr_t(&b + I));
57060a43ceSGuillaume Chatelet     EXPECT_EQ(size, base_size - I);
58060a43ceSGuillaume Chatelet   }
59060a43ceSGuillaume Chatelet }
60060a43ceSGuillaume Chatelet 
61060a43ceSGuillaume Chatelet TEST(LlvmLibcUtilsTest, Align2) {
62060a43ceSGuillaume Chatelet   char a, b;
63060a43ceSGuillaume Chatelet   const size_t base_size = 10;
64060a43ceSGuillaume Chatelet   {
65060a43ceSGuillaume Chatelet     auto *p1 = &a;
66060a43ceSGuillaume Chatelet     auto *p2 = &b;
67060a43ceSGuillaume Chatelet     size_t size = base_size;
68a786096fSGuillaume Chatelet     align_to_next_boundary<128, Arg::P1>(p1, p2, size);
69060a43ceSGuillaume Chatelet     EXPECT_TRUE(uintptr_t(p1) % 128 == 0);
70a786096fSGuillaume Chatelet     EXPECT_GT(p1, &a);
71a786096fSGuillaume Chatelet     EXPECT_GT(p2, &b);
72060a43ceSGuillaume Chatelet     EXPECT_EQ(size_t(p1 - &a), base_size - size);
73060a43ceSGuillaume Chatelet     EXPECT_EQ(size_t(p2 - &b), base_size - size);
74060a43ceSGuillaume Chatelet   }
75060a43ceSGuillaume Chatelet   {
76060a43ceSGuillaume Chatelet     auto *p1 = &a;
77060a43ceSGuillaume Chatelet     auto *p2 = &b;
78060a43ceSGuillaume Chatelet     size_t size = base_size;
79a786096fSGuillaume Chatelet     align_to_next_boundary<128, Arg::P2>(p1, p2, size);
80060a43ceSGuillaume Chatelet     EXPECT_TRUE(uintptr_t(p2) % 128 == 0);
81a786096fSGuillaume Chatelet     EXPECT_GT(p1, &a);
82a786096fSGuillaume Chatelet     EXPECT_GT(p2, &b);
83060a43ceSGuillaume Chatelet     EXPECT_EQ(size_t(p1 - &a), base_size - size);
84060a43ceSGuillaume Chatelet     EXPECT_EQ(size_t(p2 - &b), base_size - size);
85060a43ceSGuillaume Chatelet   }
86060a43ceSGuillaume Chatelet }
87060a43ceSGuillaume Chatelet 
882cfae7cdSGuillaume Chatelet TEST(LlvmLibcUtilsTest, DisjointBuffers) {
892cfae7cdSGuillaume Chatelet   char buf[3];
902cfae7cdSGuillaume Chatelet   const char *const a = buf + 0;
912cfae7cdSGuillaume Chatelet   const char *const b = buf + 1;
922cfae7cdSGuillaume Chatelet   EXPECT_TRUE(is_disjoint(a, b, 0));
932cfae7cdSGuillaume Chatelet   EXPECT_TRUE(is_disjoint(a, b, 1));
942cfae7cdSGuillaume Chatelet   EXPECT_FALSE(is_disjoint(a, b, 2));
952cfae7cdSGuillaume Chatelet 
962cfae7cdSGuillaume Chatelet   EXPECT_TRUE(is_disjoint(b, a, 0));
972cfae7cdSGuillaume Chatelet   EXPECT_TRUE(is_disjoint(b, a, 1));
982cfae7cdSGuillaume Chatelet   EXPECT_FALSE(is_disjoint(b, a, 2));
992cfae7cdSGuillaume Chatelet }
1002cfae7cdSGuillaume Chatelet 
101f4a35492SGuillaume Chatelet TEST(LlvmLibcUtilsTest, LoadStoreAligned) {
102f4a35492SGuillaume Chatelet   const uint64_t init = 0xDEAD'C0DE'BEEF'F00D;
103f4a35492SGuillaume Chatelet   CPtr const src = reinterpret_cast<CPtr>(&init);
104f4a35492SGuillaume Chatelet   uint64_t store;
105f4a35492SGuillaume Chatelet   Ptr const dst = reinterpret_cast<Ptr>(&store);
106f4a35492SGuillaume Chatelet 
107f4a35492SGuillaume Chatelet   using LoadFun = uint64_t (*)(CPtr);
108f4a35492SGuillaume Chatelet   using StoreFun = void (*)(uint64_t, Ptr);
109f4a35492SGuillaume Chatelet 
110f4a35492SGuillaume Chatelet   {
111f4a35492SGuillaume Chatelet     LoadFun ld = load_aligned<uint64_t, uint64_t>;
112f4a35492SGuillaume Chatelet     StoreFun st = store_aligned<uint64_t, uint64_t>;
113f4a35492SGuillaume Chatelet     const uint64_t loaded = ld(src);
114f4a35492SGuillaume Chatelet     EXPECT_EQ(init, loaded);
115f4a35492SGuillaume Chatelet     store = 0;
116f4a35492SGuillaume Chatelet     st(init, dst);
117f4a35492SGuillaume Chatelet     EXPECT_EQ(init, store);
118f4a35492SGuillaume Chatelet   }
119f4a35492SGuillaume Chatelet 
120f4a35492SGuillaume Chatelet   {
121f4a35492SGuillaume Chatelet     LoadFun ld = load_aligned<uint64_t, uint32_t, uint32_t>;
122f4a35492SGuillaume Chatelet     StoreFun st = store_aligned<uint64_t, uint32_t, uint32_t>;
123f4a35492SGuillaume Chatelet     const uint64_t loaded = ld(src);
124f4a35492SGuillaume Chatelet     EXPECT_EQ(init, loaded);
125f4a35492SGuillaume Chatelet     store = 0;
126f4a35492SGuillaume Chatelet     st(init, dst);
127f4a35492SGuillaume Chatelet     EXPECT_EQ(init, store);
128f4a35492SGuillaume Chatelet   }
129f4a35492SGuillaume Chatelet 
130f4a35492SGuillaume Chatelet   {
131f4a35492SGuillaume Chatelet     LoadFun ld = load_aligned<uint64_t, uint32_t, uint16_t, uint8_t, uint8_t>;
132f4a35492SGuillaume Chatelet     StoreFun st = store_aligned<uint64_t, uint32_t, uint16_t, uint8_t, uint8_t>;
133f4a35492SGuillaume Chatelet     const uint64_t loaded = ld(src);
134f4a35492SGuillaume Chatelet     EXPECT_EQ(init, loaded);
135f4a35492SGuillaume Chatelet     store = 0;
136f4a35492SGuillaume Chatelet     st(init, dst);
137f4a35492SGuillaume Chatelet     EXPECT_EQ(init, store);
138f4a35492SGuillaume Chatelet   }
139f4a35492SGuillaume Chatelet }
140f4a35492SGuillaume Chatelet 
141*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
142