diff options
Diffstat (limited to 'llvm/unittests/IR')
-rw-r--r-- | llvm/unittests/IR/DebugInfoTest.cpp | 76 | ||||
-rw-r--r-- | llvm/unittests/IR/FunctionTest.cpp | 19 | ||||
-rw-r--r-- | llvm/unittests/IR/InstructionsTest.cpp | 67 | ||||
-rw-r--r-- | llvm/unittests/IR/ManglerTest.cpp | 3 |
4 files changed, 122 insertions, 43 deletions
diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp index 03333d5..475e0a9 100644 --- a/llvm/unittests/IR/DebugInfoTest.cpp +++ b/llvm/unittests/IR/DebugInfoTest.cpp @@ -1250,6 +1250,82 @@ TEST(MetadataTest, DbgVariableRecordConversionRoutines) { EXPECT_EQ(DVI2->getExpression(), Expr2); } +TEST(MetadataTest, InlinedAtMethodsWithMultipleLevels) { + LLVMContext C; + + // Create IR with 3 levels of inlining: + // main() calls inline1() which calls inline2() which calls inline3() + // We'll test from the perspective of code in inline3() + std::unique_ptr<Module> M = parseIR(C, R"( + define void @main() !dbg !10 { + ret void, !dbg !20 + } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!2} + + !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1) + !1 = !DIFile(filename: "test.c", directory: "/test") + !2 = !{i32 2, !"Debug Info Version", i32 3} + + ; Subprograms for each function in the call chain + !10 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 100, unit: !0) + !11 = distinct !DISubprogram(name: "inline1", scope: !1, file: !1, line: 200, unit: !0) + !12 = distinct !DISubprogram(name: "inline2", scope: !1, file: !1, line: 300, unit: !0) + !13 = distinct !DISubprogram(name: "inline3", scope: !1, file: !1, line: 400, unit: !0) + + ; Location in inline3 (line 401), inlined at location !21 + !20 = !DILocation(line: 401, column: 5, scope: !13, inlinedAt: !21) + + ; Location in inline2 (line 301) where inline3 was called, inlined at !22 + !21 = !DILocation(line: 301, column: 10, scope: !12, inlinedAt: !22) + + ; Location in inline1 (line 201) where inline2 was called, inlined at !23 + !22 = !DILocation(line: 201, column: 15, scope: !11, inlinedAt: !23) + + ; Location in main (line 101) where inline1 was called (no more inlinedAt) + !23 = !DILocation(line: 101, column: 3, scope: !10) + )"); + + ASSERT_TRUE(M); + + Function *MainFunc = M->getFunction("main"); + ASSERT_TRUE(MainFunc); + Instruction &RetInst = MainFunc->getEntryBlock().front(); + + // Use getDebugLoc() to get the location from the ret instruction. + const DILocation *InnermostLoc = RetInst.getDebugLoc().get(); + ASSERT_TRUE(InnermostLoc); + + // Test getScope() - should return the immediate scope (inline3). + DILocalScope *ImmediateScope = InnermostLoc->getScope(); + ASSERT_TRUE(ImmediateScope); + EXPECT_TRUE(isa<DISubprogram>(ImmediateScope)); + EXPECT_EQ(cast<DISubprogram>(ImmediateScope)->getName(), "inline3"); + + // Test getInlinedAt() - should return the next level in the inlining chain. + const DILocation *NextLevel = InnermostLoc->getInlinedAt(); + ASSERT_TRUE(NextLevel); + EXPECT_EQ(NextLevel->getLine(), 301u); + EXPECT_EQ(cast<DISubprogram>(NextLevel->getScope())->getName(), "inline2"); + + // Test getInlinedAtLocation() - should return the outermost location. + const DILocation *OutermostLoc = InnermostLoc->getInlinedAtLocation(); + ASSERT_TRUE(OutermostLoc); + EXPECT_EQ(OutermostLoc->getLine(), 101u); + EXPECT_EQ(OutermostLoc->getColumn(), 3u); + EXPECT_EQ(OutermostLoc->getInlinedAt(), nullptr); + EXPECT_EQ(cast<DISubprogram>(OutermostLoc->getScope())->getName(), "main"); + + // Test getInlinedAtScope() - should return the scope of the outermost + // location. + DILocalScope *InlinedAtScope = InnermostLoc->getInlinedAtScope(); + ASSERT_TRUE(InlinedAtScope); + EXPECT_TRUE(isa<DISubprogram>(InlinedAtScope)); + EXPECT_EQ(cast<DISubprogram>(InlinedAtScope)->getName(), "main"); + EXPECT_EQ(InlinedAtScope, OutermostLoc->getScope()); +} + // Test that the hashing function for DISubprograms representing methods produce // the same result after replacing their scope (the type containing the // subprogram) from a temporary DIType with the permanent one. diff --git a/llvm/unittests/IR/FunctionTest.cpp b/llvm/unittests/IR/FunctionTest.cpp index 7ba7584..8ed7699 100644 --- a/llvm/unittests/IR/FunctionTest.cpp +++ b/llvm/unittests/IR/FunctionTest.cpp @@ -625,4 +625,23 @@ TEST(FunctionTest, Personality) { EXPECT_FALSE(LLVMHasPersonalityFn(wrap(F))); } +TEST(FunctionTest, LLVMGetOrInsertFunction) { + LLVMContext Ctx; + Module M("test", Ctx); + Type *Int8Ty = Type::getInt8Ty(Ctx); + FunctionType *FTy = FunctionType::get(Int8Ty, false); + + // Create the function using the C API + LLVMValueRef FuncRef = LLVMGetOrInsertFunction(wrap(&M), "F", 1, wrap(FTy)); + + // Verify that the returned value is a function and has the correct type + Function *Func = unwrap<Function>(FuncRef); + EXPECT_EQ(Func->getName(), "F"); + EXPECT_EQ(Func->getFunctionType(), FTy); + + // Call LLVMGetOrInsertFunction again to ensure it returns the same function + LLVMValueRef FuncRef2 = LLVMGetOrInsertFunction(wrap(&M), "F", 1, wrap(FTy)); + EXPECT_EQ(FuncRef, FuncRef2); +} + } // end namespace diff --git a/llvm/unittests/IR/InstructionsTest.cpp b/llvm/unittests/IR/InstructionsTest.cpp index 21d4596..fe9e7e8 100644 --- a/llvm/unittests/IR/InstructionsTest.cpp +++ b/llvm/unittests/IR/InstructionsTest.cpp @@ -606,82 +606,63 @@ TEST(InstructionTest, ConstrainedTrans) { TEST(InstructionsTest, isEliminableCastPair) { LLVMContext C; + DataLayout DL1("p1:32:32"); - Type* Int16Ty = Type::getInt16Ty(C); - Type* Int32Ty = Type::getInt32Ty(C); - Type* Int64Ty = Type::getInt64Ty(C); - Type *Int64PtrTy = PointerType::get(C, 0); + Type *Int16Ty = Type::getInt16Ty(C); + Type *Int64Ty = Type::getInt64Ty(C); + Type *PtrTy64 = PointerType::get(C, 0); + Type *PtrTy32 = PointerType::get(C, 1); // Source and destination pointers have same size -> bitcast. EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt, - CastInst::IntToPtr, - Int64PtrTy, Int64Ty, Int64PtrTy, - Int32Ty, nullptr, Int32Ty), - CastInst::BitCast); - - // Source and destination have unknown sizes, but the same address space and - // the intermediate int is the maximum pointer size -> bitcast - EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt, - CastInst::IntToPtr, - Int64PtrTy, Int64Ty, Int64PtrTy, - nullptr, nullptr, nullptr), + CastInst::IntToPtr, PtrTy32, Int64Ty, + PtrTy32, &DL1), CastInst::BitCast); - // Source and destination have unknown sizes, but the same address space and - // the intermediate int is not the maximum pointer size -> nothing + // Source and destination have unknown sizes. EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt, - CastInst::IntToPtr, - Int64PtrTy, Int32Ty, Int64PtrTy, - nullptr, nullptr, nullptr), + CastInst::IntToPtr, PtrTy32, Int64Ty, + PtrTy32, nullptr), 0U); // Middle pointer big enough -> bitcast. EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr, - CastInst::PtrToInt, - Int64Ty, Int64PtrTy, Int64Ty, - nullptr, Int64Ty, nullptr), + CastInst::PtrToInt, Int64Ty, PtrTy64, + Int64Ty, &DL1), CastInst::BitCast); // Middle pointer too small -> fail. EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr, - CastInst::PtrToInt, - Int64Ty, Int64PtrTy, Int64Ty, - nullptr, Int32Ty, nullptr), + CastInst::PtrToInt, Int64Ty, PtrTy32, + Int64Ty, &DL1), 0U); // Test that we don't eliminate bitcasts between different address spaces, // or if we don't have available pointer size information. - DataLayout DL("e-p:32:32:32-p1:16:16:16-p2:64:64:64-i1:8:8-i8:8:8-i16:16:16" - "-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64" - "-v128:128:128-a:0:64-s:64:64-f80:128:128-n8:16:32:64-S128"); + DataLayout DL2("e-p:32:32:32-p1:16:16:16-p2:64:64:64-i1:8:8-i8:8:8-i16:16:16" + "-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64" + "-v128:128:128-a:0:64-s:64:64-f80:128:128-n8:16:32:64-S128"); Type *Int64PtrTyAS1 = PointerType::get(C, 1); Type *Int64PtrTyAS2 = PointerType::get(C, 2); - IntegerType *Int16SizePtr = DL.getIntPtrType(C, 1); - IntegerType *Int64SizePtr = DL.getIntPtrType(C, 2); - // Cannot simplify inttoptr, addrspacecast EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr, - CastInst::AddrSpaceCast, - Int16Ty, Int64PtrTyAS1, Int64PtrTyAS2, - nullptr, Int16SizePtr, Int64SizePtr), + CastInst::AddrSpaceCast, Int16Ty, + Int64PtrTyAS1, Int64PtrTyAS2, &DL2), 0U); // Cannot simplify addrspacecast, ptrtoint EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::AddrSpaceCast, - CastInst::PtrToInt, - Int64PtrTyAS1, Int64PtrTyAS2, Int16Ty, - Int64SizePtr, Int16SizePtr, nullptr), + CastInst::PtrToInt, Int64PtrTyAS1, + Int64PtrTyAS2, Int16Ty, &DL2), 0U); // Pass since the bitcast address spaces are the same - EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr, - CastInst::BitCast, - Int16Ty, Int64PtrTyAS1, Int64PtrTyAS1, - nullptr, nullptr, nullptr), + EXPECT_EQ(CastInst::isEliminableCastPair( + CastInst::IntToPtr, CastInst::BitCast, Int16Ty, Int64PtrTyAS1, + Int64PtrTyAS1, nullptr), CastInst::IntToPtr); - } TEST(InstructionsTest, CloneCall) { diff --git a/llvm/unittests/IR/ManglerTest.cpp b/llvm/unittests/IR/ManglerTest.cpp index bced6ff..bb0b3ed 100644 --- a/llvm/unittests/IR/ManglerTest.cpp +++ b/llvm/unittests/IR/ManglerTest.cpp @@ -243,6 +243,9 @@ TEST(ManglerTest, Arm64EC) { // public: int __cdecl Wrapper<struct A>::GetValue(struct WW<struct // A>::Z)const "?GetValue@?$Wrapper@UA@@@@$$hQEBAHUZ@?$WW@UA@@@@@Z", + + // MD5 symbol + "??@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@$$h@", }; for (const auto &Arm64ECName : Arm64ECNames) { |