Index: llvm/trunk/lib/Linker/LinkModules.cpp =================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp +++ llvm/trunk/lib/Linker/LinkModules.cpp @@ -722,9 +722,21 @@ GV.setVisibility(GlobalValue::HiddenVisibility); if (isModuleExporting()) NewExportedValues.insert(&GV); - return; + } else + GV.setLinkage(getLinkage(&GV)); + + // Remove functions imported as available externally defs from comdats, + // as this is a declaration for the linker, and will be dropped eventually. + // It is illegal for comdats to contain declarations. + auto *GO = dyn_cast_or_null(&GV); + if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) { + // The IRMover should not have placed any imported declarations in + // a comdat, so the only declaration that should be in a comdat + // at this point would be a definition imported as available_externally. + assert(GO->hasAvailableExternallyLinkage() && + "Expected comdat on definition (possibly available external)"); + GO->setComdat(nullptr); } - GV.setLinkage(getLinkage(&GV)); } void ThinLTOGlobalProcessing::processGlobalsForThinLTO() { Index: llvm/trunk/test/Linker/Inputs/funcimport_comdat.ll =================================================================== --- llvm/trunk/test/Linker/Inputs/funcimport_comdat.ll +++ llvm/trunk/test/Linker/Inputs/funcimport_comdat.ll @@ -0,0 +1,4 @@ +define i32 @main() #0 { +entry: + ret i32 0 +} Index: llvm/trunk/test/Linker/funcimport_comdat.ll =================================================================== --- llvm/trunk/test/Linker/funcimport_comdat.ll +++ llvm/trunk/test/Linker/funcimport_comdat.ll @@ -0,0 +1,28 @@ +; Do setup work for all below tests: generate bitcode and combined index +; RUN: llvm-as -function-summary %s -o %t.bc +; RUN: llvm-as -function-summary %p/Inputs/funcimport_comdat.ll -o %t2.bc +; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc + +; Ensure linking of comdat containing external linkage global and function +; removes the imported available_externally defs from comdat. +; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=comdat1_func1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDAT +; IMPORTCOMDAT-NOT: $comdat1 = comdat any +; IMPORTCOMDAT-NOT: comdat($comdat1) + +; Ensure linking of comdat containing internal linkage function with alias +; removes the imported and promoted available_externally defs from comdat. +; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=comdat2_func1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDAT2 +; IMPORTCOMDAT2-NOT: $comdat2 = comdat any +; IMPORTCOMDAT2-NOT: comdat($comdat2) + +$comdat1 = comdat any +@comdat1_glob = global i32 0, comdat($comdat1) +define void @comdat1_func1() comdat($comdat1) { + ret void +} + +$comdat2 = comdat any +@comdat2_alias = alias void (), void ()* @comdat2_func1 +define internal void @comdat2_func1() comdat($comdat2) { + ret void +}