diff --git a/llvm/lib/Transforms/Utils/CloneModule.cpp b/llvm/lib/Transforms/Utils/CloneModule.cpp --- a/llvm/lib/Transforms/Utils/CloneModule.cpp +++ b/llvm/lib/Transforms/Utils/CloneModule.cpp @@ -140,10 +140,18 @@ // Similarly, copy over function bodies now... // for (const Function &I : M) { - if (I.isDeclaration()) + Function *F = cast(VMap[&I]); + + if (I.isDeclaration()) { + // Copy over metadata for declarations since we're not doing it below in + // CloneFunctionInto(). + SmallVector, 1> MDs; + I.getAllMetadata(MDs); + for (auto MD : MDs) + F->addMetadata(MD.first, *MapMetadata(MD.second, VMap)); continue; + } - Function *F = cast(VMap[&I]); if (!ShouldCloneDefinition(&I)) { // Skip after setting the correct linkage for an external reference. F->setLinkage(GlobalValue::ExternalLinkage); diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp b/llvm/unittests/Transforms/Utils/CloningTest.cpp --- a/llvm/unittests/Transforms/Utils/CloningTest.cpp +++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp @@ -921,6 +921,10 @@ IBuilder.SetInsertPoint(Entry); IBuilder.CreateRetVoid(); + auto *G = + Function::Create(FuncType, GlobalValue::ExternalLinkage, "g", OldM); + G->addMetadata(LLVMContext::MD_type, *MDNode::get(C, {})); + // Finalize the debug info DBuilder.finalize(); } @@ -934,10 +938,10 @@ TEST_F(CloneModule, Verify) { // Confirm the old module is (still) valid. - EXPECT_FALSE(verifyModule(*OldM)); + EXPECT_FALSE(verifyModule(*OldM, &errs())); // Check the new module. - EXPECT_FALSE(verifyModule(*NewM)); + EXPECT_FALSE(verifyModule(*NewM, &errs())); } TEST_F(CloneModule, OldModuleUnchanged) { @@ -955,6 +959,11 @@ EXPECT_EQ(SP->getLine(), (unsigned)4); } +TEST_F(CloneModule, FunctionDeclarationMetadata) { + Function *NewF = NewM->getFunction("g"); + EXPECT_NE(nullptr, NewF->getMetadata(LLVMContext::MD_type)); +} + TEST_F(CloneModule, GlobalMetadata) { GlobalVariable *NewGV = NewM->getGlobalVariable("gv"); EXPECT_NE(nullptr, NewGV->getMetadata(LLVMContext::MD_type));