Index: llvm/lib/Object/IRSymtab.cpp =================================================================== --- llvm/lib/Object/IRSymtab.cpp +++ llvm/lib/Object/IRSymtab.cpp @@ -72,7 +72,7 @@ BumpPtrAllocator &Alloc) : Symtab(Symtab), StrtabBuilder(StrtabBuilder), Saver(Alloc) {} - DenseMap ComdatMap; + DenseMap ComdatMap; Mangler Mang; Triple TT; @@ -97,6 +97,8 @@ reinterpret_cast(Objs.data() + Objs.size())); } + int getComdatIndex(const Comdat *C, const Module *M); + Error addModule(Module *M); Error addSymbol(const ModuleSymbolTable &Msymtab, const SmallPtrSet &Used, @@ -140,6 +142,31 @@ return Error::success(); } +int Builder::getComdatIndex(const Comdat *C, const Module *M) { + auto P = ComdatMap.insert(std::make_pair(C, Comdats.size())); + if (P.second) { + if (TT.isOSBinFormatCOFF()) { + // Internal leaders do not affect symbol resolution, therefore they do not + // appear in the symbol table. + const GlobalValue *GV = M->getNamedValue(C->getName()); + if (GV->hasLocalLinkage()) { + P.first->second = -1; + return -1; + } + } + + std::string Name; + llvm::raw_string_ostream OS(Name); + Mangler::getNameWithPrefix(OS, C->getName(), M->getDataLayout()); + + storage::Comdat Comdat; + setStr(Comdat.Name, Saver.save(OS.str())); + Comdats.push_back(Comdat); + } + + return P.first->second; +} + Error Builder::addSymbol(const ModuleSymbolTable &Msymtab, const SmallPtrSet &Used, ModuleSymbolTable::Symbol Msym) { @@ -215,16 +242,8 @@ if (!Base) return make_error("Unable to determine comdat of alias!", inconvertibleErrorCode()); - if (const Comdat *C = Base->getComdat()) { - auto P = ComdatMap.insert(std::make_pair(C, Comdats.size())); - Sym.ComdatIndex = P.first->second; - - if (P.second) { - storage::Comdat Comdat; - setStr(Comdat.Name, C->getName()); - Comdats.push_back(Comdat); - } - } + if (const Comdat *C = Base->getComdat()) + Sym.ComdatIndex = getComdatIndex(C, GV->getParent()); if (TT.isOSBinFormatCOFF()) { emitLinkerFlagsForGlobalCOFF(COFFLinkerOptsOS, GV, TT, Mang); Index: llvm/test/LTO/Resolution/X86/symtab.ll =================================================================== --- llvm/test/LTO/Resolution/X86/symtab.ll +++ llvm/test/LTO/Resolution/X86/symtab.ll @@ -43,11 +43,19 @@ @g8 = common global i32 0, align 8 ; CHECK: D------- _g9 -; CHECK-NEXT: comdat g9 +; CHECK-NEXT: comdat _g9 $g9 = comdat any @g9 = global i32 0, comdat -; CHECK: D--WI--- _g10 -; CHECK-NEXT: comdat g9 +; CHECK-NOT: _g10 +$g10 = comdat any +@g10 = internal global i32 0, comdat + +; CHECK: D------- _g11 +; CHECK-NOT: comdat +@g11 = global i32 0, comdat($g10) + +; CHECK: D--WI--- _a1 +; CHECK-NEXT: comdat _g9 ; CHECK-NEXT: fallback _g9 -@g10 = weak alias i32, i32* @g9 +@a1 = weak alias i32, i32* @g9