diff options
Diffstat (limited to 'llvm/unittests/Transforms/Utils/CloningTest.cpp')
-rw-r--r-- | llvm/unittests/Transforms/Utils/CloningTest.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp b/llvm/unittests/Transforms/Utils/CloningTest.cpp index 025771f..1f04663 100644 --- a/llvm/unittests/Transforms/Utils/CloningTest.cpp +++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp @@ -801,6 +801,111 @@ TEST(CloneFunction, CloneFunctionWithSubprograms) { EXPECT_FALSE(verifyModule(*ImplModule, &errs())); } +TEST(CloneFunction, CloneFunctionWithRetainedNodes) { + StringRef ImplAssembly = R"( + declare void @llvm.dbg.declare(metadata, metadata, metadata) + + define void @test() !dbg !3 { + call void @llvm.dbg.declare(metadata i8* undef, metadata !5, metadata !DIExpression()), !dbg !7 + call void @llvm.dbg.declare(metadata i8* undef, metadata !25, metadata !DIExpression()), !dbg !7 + ret void + } + + declare void @cloned() + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!2} + !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, enums: !{!14}) + !1 = !DIFile(filename: "test.cpp", directory: "") + !2 = !{i32 1, !"Debug Info Version", i32 3} + !3 = distinct !DISubprogram(name: "test", scope: !1, unit: !0, retainedNodes: !9) + !4 = distinct !DISubprogram(name: "inlined", scope: !1, unit: !0, retainedNodes: !{!5}) + !5 = !DILocalVariable(name: "awaitables", scope: !4, type: !23) + !6 = distinct !DILexicalBlock(scope: !4, file: !1, line: 1) + !7 = !DILocation(line: 1, scope: !6, inlinedAt: !8) + !8 = !DILocation(line: 10, scope: !3) + !9 = !{!15, !17, !18, !23} + !14 = distinct !DICompositeType(tag: DW_TAG_enumeration_type, scope: !0, file: !1, line: 13, size: 200, elements: !{}) + !15 = !DILocalVariable(name: "a", scope: !3) + !16 = distinct !DICompositeType(tag: DW_TAG_enumeration_type, scope: !3, file: !1, line: 13, size: 208, elements: !{}) + !17 = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "imported_l", file: !1, line: 14, scope: !3, entity: !16) + !18 = !DILabel(scope: !3, name: "l", file: !1, line: 22) + !22 = !DIBasicType(name: "real", size: 32, align: 32, encoding: DW_ATE_float) + !23 = !DIDerivedType(name: "local_float", tag: DW_TAG_const_type, baseType: !22, scope: !3) + !float_type = !{!23} + !25 = !DILocalVariable(name: "inlined2", scope: !4, type: !23) + !inlined2 = !{!25} + )"; + + LLVMContext Context; + SMDiagnostic Error; + + auto ImplModule = parseAssemblyString(ImplAssembly, Error, Context); + EXPECT_TRUE(ImplModule != nullptr); + auto *Func = ImplModule->getFunction("test"); + EXPECT_TRUE(Func != nullptr); + auto *ClonedFunc = ImplModule->getFunction("cloned"); + EXPECT_TRUE(ClonedFunc != nullptr); + + EXPECT_FALSE(verifyModule(*ImplModule, &errs())); + + ValueToValueMapTy VMap; + SmallVector<ReturnInst *, 8> Returns; + ClonedCodeInfo CCI; + CloneFunctionInto(ClonedFunc, Func, VMap, + CloneFunctionChangeType::GlobalChanges, Returns, "", &CCI); + + EXPECT_FALSE(verifyModule(*ImplModule, &errs())); + + // Check that retained and local types are copied. + DISubprogram *FuncSP = Func->getSubprogram(); + DISubprogram *ClonedSP = ClonedFunc->getSubprogram(); + EXPECT_NE(FuncSP, nullptr); + EXPECT_NE(ClonedSP, nullptr); + EXPECT_EQ(FuncSP->getRetainedNodes().size(), 4u); + EXPECT_EQ(FuncSP->getRetainedNodes().size(), + ClonedSP->getRetainedNodes().size()); + for (unsigned I = 0; I < FuncSP->getRetainedNodes().size(); ++I) { + auto *Node = FuncSP->getRetainedNodes()[I]; + auto *Copy = ClonedSP->getRetainedNodes()[I]; + + // Check that the order of retainedNodes is preserved by + // checking that the corresponding node has the same name. + if (auto *Var = dyn_cast<DILocalVariable>(Node)) { + auto *VarCopy = dyn_cast<DILocalVariable>(Copy); + EXPECT_NE(VarCopy, nullptr); + EXPECT_EQ(Var->getName(), VarCopy->getName()); + } else if (auto *Label = dyn_cast<DILabel>(Node)) { + auto *LabelCopy = dyn_cast<DILabel>(Copy); + EXPECT_NE(LabelCopy, nullptr); + EXPECT_EQ(Label->getName(), LabelCopy->getName()); + } else if (auto *IE = dyn_cast<DIImportedEntity>(Node)) { + auto *IECopy = dyn_cast<DIImportedEntity>(Copy); + EXPECT_NE(IECopy, nullptr); + EXPECT_EQ(IE->getName(), IECopy->getName()); + } else if (auto *Ty = dyn_cast<DIType>(Node)) { + auto *TyCopy = dyn_cast<DIType>(Copy); + EXPECT_NE(TyCopy, nullptr); + EXPECT_EQ(Ty->getName(), TyCopy->getName()); + } + + // Check that node was copied + EXPECT_NE(Node, Copy); + } + + auto *FloatType = dyn_cast<DIType>( + ImplModule->getNamedMetadata("float_type")->getOperand(0)); + EXPECT_EQ(FloatType->getName(), "local_float"); + EXPECT_TRUE(VMap.MD().contains(FloatType)); + EXPECT_NE(FloatType, VMap.MD()[FloatType]); + + auto *Inlined2 = dyn_cast<DILocalVariable>( + ImplModule->getNamedMetadata("inlined2")->getOperand(0)); + EXPECT_EQ(Inlined2->getName(), "inlined2"); + EXPECT_TRUE(VMap.MD().contains(Inlined2)); + EXPECT_EQ(Inlined2, VMap.MD()[Inlined2]); +} + TEST(CloneFunction, CloneFunctionWithInlinedSubprograms) { StringRef ImplAssembly = R"( declare void @llvm.dbg.declare(metadata, metadata, metadata) |