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