aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Transforms/Utils/CloningTest.cpp
diff options
context:
space:
mode:
authorKristina Bessonova <kbessonova@accesssoftek.com>2022-07-18 13:09:29 +0200
committerKristina Bessonova <kbessonova@accesssoftek.com>2022-07-18 13:14:52 +0200
commit44736c1d497f2c269f6ef86ef7bf0e47f4869a4d (patch)
treebf9fc1a23570ff397f34829a8e2cab501225e35a /llvm/unittests/Transforms/Utils/CloningTest.cpp
parent04e978ccba1e6c8b600b2fbad1a82b4b64ffc34b (diff)
downloadllvm-44736c1d497f2c269f6ef86ef7bf0e47f4869a4d.zip
llvm-44736c1d497f2c269f6ef86ef7bf0e47f4869a4d.tar.gz
llvm-44736c1d497f2c269f6ef86ef7bf0e47f4869a4d.tar.bz2
[CloneFunction][DebugInfo] Avoid cloning DILexicalBlocks of inlined subprograms
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 DILexicalBlocks as well. Otherwise we'll get duplicated DILexicalBlocks that may confuse debug info emission in AsmPrinter. I believe it also makes no sense cloning any DILocalVariables or maybe other local entities, if their parent subprogram was not cloned, cause they will be dangling and will not participate in futher emission. Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D127102
Diffstat (limited to 'llvm/unittests/Transforms/Utils/CloningTest.cpp')
-rw-r--r--llvm/unittests/Transforms/Utils/CloningTest.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp b/llvm/unittests/Transforms/Utils/CloningTest.cpp
index ac6c1e8..186714a 100644
--- a/llvm/unittests/Transforms/Utils/CloningTest.cpp
+++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp
@@ -799,6 +799,58 @@ TEST(CloneFunction, CloneFunctionWithSubprograms) {
EXPECT_FALSE(verifyModule(*ImplModule, &errs()));
}
+TEST(CloneFunction, CloneFunctionWithInlinedSubprograms) {
+ 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
+ ret void
+ }
+
+ declare void @cloned()
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!2}
+ !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1)
+ !1 = !DIFile(filename: "test.cpp", directory: "")
+ !2 = !{i32 1, !"Debug Info Version", i32 3}
+ !3 = distinct !DISubprogram(name: "test", scope: !0, unit: !0)
+ !4 = distinct !DISubprogram(name: "inlined", scope: !0, unit: !0, retainedNodes: !{!5})
+ !5 = !DILocalVariable(name: "awaitables", scope: !4)
+ !6 = distinct !DILexicalBlock(scope: !4, file: !1, line: 1)
+ !7 = !DILocation(line: 1, scope: !6, inlinedAt: !8)
+ !8 = !DILocation(line: 10, scope: !3)
+ )";
+
+ 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);
+
+ ValueToValueMapTy VMap;
+ SmallVector<ReturnInst *, 8> Returns;
+ ClonedCodeInfo CCI;
+ CloneFunctionInto(ClonedFunc, Func, VMap,
+ CloneFunctionChangeType::GlobalChanges, Returns, "", &CCI);
+
+ EXPECT_FALSE(verifyModule(*ImplModule, &errs()));
+
+ // Check that DILexicalBlock of inlined function was not cloned.
+ auto DbgDeclareI = Func->begin()->begin();
+ auto ClonedDbgDeclareI = ClonedFunc->begin()->begin();
+ const DebugLoc &DbgLoc = DbgDeclareI->getDebugLoc();
+ const DebugLoc &ClonedDbgLoc = ClonedDbgDeclareI->getDebugLoc();
+ EXPECT_NE(DbgLoc.get(), ClonedDbgLoc.get());
+ EXPECT_EQ(cast<DILexicalBlock>(DbgLoc.getScope()),
+ cast<DILexicalBlock>(ClonedDbgLoc.getScope()));
+}
+
TEST(CloneFunction, CloneFunctionToDifferentModule) {
StringRef ImplAssembly = R"(
define void @foo() {