xref: /llvm-project/llvm/unittests/ExecutionEngine/Orc/ExecutorAddressTest.cpp (revision 81c0f3023fc38e3ea720045407a17f47653ea2ac)
1c0d88999SLang Hames //===--------- ExecutorAddrTest.cpp - Unit tests for ExecutorAddr ---------===//
2c0d88999SLang Hames //
3c0d88999SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c0d88999SLang Hames // See https://llvm.org/LICENSE.txt for license information.
5c0d88999SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c0d88999SLang Hames //
7c0d88999SLang Hames //===----------------------------------------------------------------------===//
8c0d88999SLang Hames 
9c0d88999SLang Hames #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
10c0d88999SLang Hames #include "OrcTestCommon.h"
11*81c0f302SLang Hames #include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
12c0d88999SLang Hames 
13c0d88999SLang Hames using namespace llvm;
14c0d88999SLang Hames using namespace llvm::orc;
15c0d88999SLang Hames 
16c0d88999SLang Hames namespace {
17c0d88999SLang Hames 
18c0d88999SLang Hames TEST(ExecutorAddrTest, DefaultAndNull) {
19c0d88999SLang Hames   // Check that default constructed values and isNull behave as expected.
20c0d88999SLang Hames 
21c0d88999SLang Hames   ExecutorAddr Default;
22c0d88999SLang Hames   ExecutorAddr Null(0);
23c0d88999SLang Hames   ExecutorAddr NonNull(1);
24c0d88999SLang Hames 
25c0d88999SLang Hames   EXPECT_TRUE(Null.isNull());
26c0d88999SLang Hames   EXPECT_EQ(Default, Null);
27c0d88999SLang Hames 
28c0d88999SLang Hames   EXPECT_FALSE(NonNull.isNull());
29c0d88999SLang Hames   EXPECT_NE(Default, NonNull);
30c0d88999SLang Hames }
31c0d88999SLang Hames 
32c0d88999SLang Hames TEST(ExecutorAddrTest, Ordering) {
33c0d88999SLang Hames   // Check that ordering operations.
34c0d88999SLang Hames   ExecutorAddr A1(1), A2(2);
35c0d88999SLang Hames 
36c0d88999SLang Hames   EXPECT_LE(A1, A1);
37c0d88999SLang Hames   EXPECT_LT(A1, A2);
38c0d88999SLang Hames   EXPECT_GT(A2, A1);
39c0d88999SLang Hames   EXPECT_GE(A2, A2);
40c0d88999SLang Hames }
41c0d88999SLang Hames 
42c0d88999SLang Hames TEST(ExecutorAddrTest, PtrConversion) {
43c0d88999SLang Hames   // Test toPtr / fromPtr round-tripping.
44c0d88999SLang Hames   int X = 0;
45c0d88999SLang Hames   auto XAddr = ExecutorAddr::fromPtr(&X);
46c0d88999SLang Hames   int *XPtr = XAddr.toPtr<int *>();
47c0d88999SLang Hames 
48c0d88999SLang Hames   EXPECT_EQ(XPtr, &X);
49c0d88999SLang Hames }
50c0d88999SLang Hames 
5198616cfcSLang Hames static void F() {}
5298616cfcSLang Hames 
5398616cfcSLang Hames TEST(ExecutorAddrTest, PtrConversionWithFunctionType) {
5498616cfcSLang Hames   // Test that function types (as opposed to function pointer types) can be
5598616cfcSLang Hames   // used with toPtr.
5698616cfcSLang Hames   auto FAddr = ExecutorAddr::fromPtr(F);
5798616cfcSLang Hames   void (*FPtr)() = FAddr.toPtr<void()>();
5898616cfcSLang Hames 
5998616cfcSLang Hames   EXPECT_EQ(FPtr, &F);
6098616cfcSLang Hames }
6198616cfcSLang Hames 
62f828135fSLang Hames TEST(ExecutorAddrTest, WrappingAndUnwrapping) {
63f828135fSLang Hames   constexpr uintptr_t RawAddr = 0x123456;
64f828135fSLang Hames   int *RawPtr = (int *)RawAddr;
65f828135fSLang Hames 
66f828135fSLang Hames   constexpr uintptr_t TagOffset = 8 * (sizeof(uintptr_t) - 1);
67f828135fSLang Hames   uintptr_t TagVal = 0xA5;
68f828135fSLang Hames   uintptr_t TagBits = TagVal << TagOffset;
69f828135fSLang Hames   void *TaggedPtr = (void *)((uintptr_t)RawPtr | TagBits);
70f828135fSLang Hames 
71f828135fSLang Hames   ExecutorAddr EA =
72f828135fSLang Hames       ExecutorAddr::fromPtr(TaggedPtr, ExecutorAddr::Untag(8, TagOffset));
73f828135fSLang Hames 
74f828135fSLang Hames   EXPECT_EQ(EA.getValue(), RawAddr);
75f828135fSLang Hames 
76f828135fSLang Hames   void *ReconstitutedTaggedPtr =
77f828135fSLang Hames       EA.toPtr<void *>(ExecutorAddr::Tag(TagVal, TagOffset));
78f828135fSLang Hames 
79f828135fSLang Hames   EXPECT_EQ(TaggedPtr, ReconstitutedTaggedPtr);
80f828135fSLang Hames }
81f828135fSLang Hames 
82c0d88999SLang Hames TEST(ExecutorAddrTest, AddrRanges) {
83c0d88999SLang Hames   ExecutorAddr A0(0), A1(1), A2(2), A3(3);
84c0d88999SLang Hames   ExecutorAddrRange R0(A0, A1), R1(A1, A2), R2(A2, A3), R3(A0, A2), R4(A1, A3);
85c0d88999SLang Hames   //     012
86c0d88999SLang Hames   // R0: #      -- Before R1
87c0d88999SLang Hames   // R1:  #     --
88c0d88999SLang Hames   // R2:   #    -- After R1
89c0d88999SLang Hames   // R3: ##     -- Overlaps R1 start
90c0d88999SLang Hames   // R4:  ##    -- Overlaps R1 end
91c0d88999SLang Hames 
92c0d88999SLang Hames   EXPECT_EQ(R1, ExecutorAddrRange(A1, A2));
9337f1b7a3SLang Hames   EXPECT_EQ(R1, ExecutorAddrRange(A1, ExecutorAddrDiff(1)));
94c0d88999SLang Hames   EXPECT_NE(R1, R2);
95c0d88999SLang Hames 
96c0d88999SLang Hames   EXPECT_TRUE(R1.contains(A1));
97c0d88999SLang Hames   EXPECT_FALSE(R1.contains(A0));
98c0d88999SLang Hames   EXPECT_FALSE(R1.contains(A2));
99c0d88999SLang Hames 
100c0d88999SLang Hames   EXPECT_FALSE(R1.overlaps(R0));
101c0d88999SLang Hames   EXPECT_FALSE(R1.overlaps(R2));
102c0d88999SLang Hames   EXPECT_TRUE(R1.overlaps(R3));
103c0d88999SLang Hames   EXPECT_TRUE(R1.overlaps(R4));
104c0320e73SLang Hames 
105c0320e73SLang Hames   EXPECT_LE(R0, R0);
106c0320e73SLang Hames   EXPECT_LT(R0, R1);
107c0320e73SLang Hames   EXPECT_GE(R0, R0);
108c0320e73SLang Hames   EXPECT_GT(R1, R0);
109c0d88999SLang Hames }
110c0d88999SLang Hames 
111*81c0f302SLang Hames TEST(ExecutorSymbolDef, PointerConversion) {
112*81c0f302SLang Hames   int X = 0;
113*81c0f302SLang Hames 
114*81c0f302SLang Hames   auto XHiddenSym = ExecutorSymbolDef::fromPtr(&X);
115*81c0f302SLang Hames   int *XHiddenPtr = XHiddenSym.toPtr<int *>();
116*81c0f302SLang Hames 
117*81c0f302SLang Hames   auto XExportedSym = ExecutorSymbolDef::fromPtr(&X, JITSymbolFlags::Exported);
118*81c0f302SLang Hames   int *XExportedPtr = XExportedSym.toPtr<int *>();
119*81c0f302SLang Hames 
120*81c0f302SLang Hames   EXPECT_EQ(XHiddenPtr, &X);
121*81c0f302SLang Hames   EXPECT_EQ(XExportedPtr, &X);
122*81c0f302SLang Hames 
123*81c0f302SLang Hames   EXPECT_EQ(XHiddenSym.getFlags(), JITSymbolFlags());
124*81c0f302SLang Hames   EXPECT_EQ(XExportedSym.getFlags(), JITSymbolFlags::Exported);
125*81c0f302SLang Hames }
126*81c0f302SLang Hames 
127*81c0f302SLang Hames TEST(ExecutorSymbolDef, FunctionPointerConversion) {
128*81c0f302SLang Hames   auto FHiddenSym = ExecutorSymbolDef::fromPtr(&F);
129*81c0f302SLang Hames   void (*FHiddenPtr)() = FHiddenSym.toPtr<void()>();
130*81c0f302SLang Hames 
131*81c0f302SLang Hames   auto FExportedSym = ExecutorSymbolDef::fromPtr(&F, JITSymbolFlags::Exported);
132*81c0f302SLang Hames   void (*FExportedPtr)() = FExportedSym.toPtr<void()>();
133*81c0f302SLang Hames 
134*81c0f302SLang Hames   EXPECT_EQ(FHiddenPtr, &F);
135*81c0f302SLang Hames   EXPECT_EQ(FExportedPtr, &F);
136*81c0f302SLang Hames 
137*81c0f302SLang Hames   EXPECT_EQ(FHiddenSym.getFlags(), JITSymbolFlags::Callable);
138*81c0f302SLang Hames   EXPECT_EQ(FExportedSym.getFlags(),
139*81c0f302SLang Hames             JITSymbolFlags::Exported | JITSymbolFlags::Callable);
140*81c0f302SLang Hames }
141*81c0f302SLang Hames 
142c0d88999SLang Hames } // namespace
143