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