diff options
author | Vladislav Dzhidzhoev <vdzhidzhoev@accesssoftek.com> | 2024-01-11 17:08:12 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-11 17:08:12 +0100 |
commit | fc6faa1113e9069f41b5500db051210af0eea843 (patch) | |
tree | 105a76fe962bf21897f044fb563d7b5abd83a226 /llvm/unittests/Transforms/Utils/CloningTest.cpp | |
parent | 31ce0f1dda3caed829db09b9212eac54a8a28572 (diff) | |
download | llvm-fc6faa1113e9069f41b5500db051210af0eea843.zip llvm-fc6faa1113e9069f41b5500db051210af0eea843.tar.gz llvm-fc6faa1113e9069f41b5500db051210af0eea843.tar.bz2 |
[CloneFunction][DebugInfo] Avoid cloning DILocalVariables of inlined functions (#75385)
- [DebugMetadata][DwarfDebug] Support function-local types in lexical
block scopes (4/7)
- [CloneFunction][DebugInfo] Avoid cloning DILocalVariables of inlined
functions
This is a follow-up for https://reviews.llvm.org/D144006, fixing a crash
reported
in Chromium (https://reviews.llvm.org/D144006#4651955).
The first commit is added for convenience, as it has already been
accepted.
If DISubpogram was not cloned (e.g. we are cloning a function that has
other
functions inlined into it, and subprograms of the inlined functions are
not supposed to be cloned), it doesn't make sense to clone its
DILocalVariables as well.
Otherwise get duplicated DILocalVariables not tracked in their
subprogram's retainedNodes, that crash LTO with Chromium.
This is meant to be committed along with
https://reviews.llvm.org/D144006.
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) |