Index: llvm/lib/Transforms/Utils/CloneFunction.cpp =================================================================== --- llvm/lib/Transforms/Utils/CloneFunction.cpp +++ llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -260,6 +260,9 @@ // visiting the metadata attached to global values, which would allow this // code to be deleted. Alternatively, perhaps give responsibility for this // update to CloneFunctionInto's callers. + if (!OldFunc->getParent()->getNamedMetadata("llvm.dbg.cu")) + return; + auto *NewModule = NewFunc->getParent(); auto *NMD = NewModule->getOrInsertNamedMetadata("llvm.dbg.cu"); // Avoid multiple insertions of the same DICompileUnit to NMD. Index: llvm/unittests/Transforms/Utils/CloningTest.cpp =================================================================== --- llvm/unittests/Transforms/Utils/CloningTest.cpp +++ llvm/unittests/Transforms/Utils/CloningTest.cpp @@ -849,6 +849,49 @@ EXPECT_FALSE(haveCompileUnitsInCommon(*ImplModule, *DeclModule)); } +TEST(CloneFunction, CloneFunctionToDifferentModuleNoCU) { + StringRef ImplAssembly = R"( + define void @foo() { + ret void + } + )"; + StringRef DeclAssembly = R"( + declare void @foo() + )"; + + LLVMContext Context; + SMDiagnostic Error; + + auto ImplModule = parseAssemblyString(ImplAssembly, Error, Context); + EXPECT_TRUE(ImplModule != nullptr); + EXPECT_TRUE(ImplModule->getNamedMetadata("llvm.dbg.cu") == nullptr); + auto *ImplFunction = ImplModule->getFunction("foo"); + EXPECT_TRUE(ImplFunction != nullptr); + + auto DeclModule = parseAssemblyString(DeclAssembly, Error, Context); + EXPECT_TRUE(DeclModule != nullptr); + // No DICompileUnits defined here. + EXPECT_TRUE(GetDICompileUnitCount(*DeclModule) == 0); + auto *DeclFunction = DeclModule->getFunction("foo"); + EXPECT_TRUE(DeclFunction != nullptr); + + EXPECT_FALSE(verifyModule(*ImplModule, &errs())); + EXPECT_FALSE(verifyModule(*DeclModule, &errs())); + + ValueToValueMapTy VMap; + VMap[ImplFunction] = DeclFunction; + // No args to map + SmallVector Returns; + CloneFunctionInto(DeclFunction, ImplFunction, VMap, + CloneFunctionChangeType::DifferentModule, Returns); + + EXPECT_FALSE(verifyModule(*ImplModule, &errs())); + EXPECT_FALSE(verifyModule(*DeclModule, &errs())); + // DeclModule should not have a compile unit because it didn't start with one + // and nor did ImplModule + EXPECT_TRUE(DeclModule->getNamedMetadata("llvm.dbg.cu") == nullptr); +} + class CloneModule : public ::testing::Test { protected: void SetUp() override {