Index: llvm/lib/Transforms/Utils/CloneModule.cpp =================================================================== --- llvm/lib/Transforms/Utils/CloneModule.cpp +++ llvm/lib/Transforms/Utils/CloneModule.cpp @@ -20,6 +20,15 @@ #include "llvm-c/Core.h" using namespace llvm; +static void copyComdat(GlobalObject *Dst, const GlobalObject *Src) { + const Comdat *SC = Src->getComdat(); + if (!SC) + return; + Comdat *DC = Dst->getParent()->getOrInsertComdat(SC->getName()); + DC->setSelectionKind(SC->getSelectionKind()); + Dst->setComdat(DC); +} + /// This is not as easy as it might seem because we have to worry about making /// copies of global variables and functions, and making their (initializers and /// references, respectively) refer to the right globals. @@ -124,6 +133,8 @@ I->getAllMetadata(MDs); for (auto MD : MDs) GV->addMetadata(MD.first, *MapMetadata(MD.second, VMap)); + + copyComdat(GV, &*I); } // Similarly, copy over function bodies now... @@ -153,6 +164,8 @@ if (I.hasPersonalityFn()) F->setPersonalityFn(MapValue(I.getPersonalityFn(), VMap)); + + copyComdat(F, &I); } // And aliases Index: llvm/unittests/Transforms/Utils/Cloning.cpp =================================================================== --- llvm/unittests/Transforms/Utils/Cloning.cpp +++ llvm/unittests/Transforms/Utils/Cloning.cpp @@ -405,10 +405,14 @@ void SetupModule() { OldM = new Module("", C); } void CreateOldModule() { + auto *CD = OldM->getOrInsertComdat("comdat"); + CD->setSelectionKind(Comdat::ExactMatch); + auto GV = new GlobalVariable( *OldM, Type::getInt32Ty(C), false, GlobalValue::ExternalLinkage, ConstantInt::get(Type::getInt32Ty(C), 1), "gv"); GV->addMetadata(LLVMContext::MD_type, *MDNode::get(C, {})); + GV->setComdat(CD); DIBuilder DBuilder(*OldM); IRBuilder<> IBuilder(C); @@ -419,6 +423,7 @@ auto *F = Function::Create(FuncType, GlobalValue::PrivateLinkage, "f", OldM); F->setPersonalityFn(PersFn); + F->setComdat(CD); // Create debug info auto *File = DBuilder.createFile("filename.c", "/file/dir/"); @@ -472,4 +477,15 @@ GlobalVariable *NewGV = NewM->getGlobalVariable("gv"); EXPECT_NE(nullptr, NewGV->getMetadata(LLVMContext::MD_type)); } + +TEST_F(CloneModule, Comdat) { + GlobalVariable *NewGV = NewM->getGlobalVariable("gv"); + auto *CD = NewGV->getComdat(); + ASSERT_NE(nullptr, CD); + EXPECT_EQ("comdat", CD->getName()); + EXPECT_EQ(Comdat::ExactMatch, CD->getSelectionKind()); + + Function *NewF = NewM->getFunction("f"); + EXPECT_EQ(CD, NewF->getComdat()); +} }