diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -290,9 +290,15 @@ // This is needed because this is what GNU gold plugin does and we have a // distributed build system that depends on that behavior. static void thinLTOCreateEmptyIndexFiles() { + DenseSet linkedBitCodeFiles; + for (BitcodeFile *f : ctx->bitcodeFiles) + linkedBitCodeFiles.insert(f->getName()); + for (BitcodeFile *f : ctx->lazyBitcodeFiles) { if (!f->lazy) continue; + if (linkedBitCodeFiles.contains(f->getName())) + continue; std::string path = replaceThinLTOSuffix(getThinLTOOutputFile(f->getName())); std::unique_ptr os = openFile(path + ".thinlto.bc"); if (!os) diff --git a/lld/test/ELF/lto/thinlto-index-only.ll b/lld/test/ELF/lto/thinlto-index-only.ll --- a/lld/test/ELF/lto/thinlto-index-only.ll +++ b/lld/test/ELF/lto/thinlto-index-only.ll @@ -42,6 +42,21 @@ ; RUN: ld.lld --plugin-opt=thinlto-index-only -shared dummy.o --start-lib 1.o --end-lib -o /dev/null ; RUN: ls 1.o.thinlto.bc +;; Ensure when the same bitcode object is given as both lazy and non-lazy, +;; LLD does not generate an empty index for the lazy object. +; RUN: rm -f 2.o.thinlto.bc +; RUN: ld.lld --plugin-opt=thinlto-index-only -shared 1.o 2.o --start-lib 2.o --end-lib -o /dev/null +; RUN: llvm-dis < 2.o.thinlto.bc | grep -q '\^0 = module:' +; RUN: rm -f 2.o.thinlto.bc +; RUN: ld.lld --plugin-opt=thinlto-index-only -shared --start-lib 2.o --end-lib 2.o 1.o -o /dev/null +; RUN: llvm-dis < 2.o.thinlto.bc | grep -q '\^0 = module:' + +;; Ensure when the same lazy bitcode object is given multiple times, +;; no empty index file is generated if one of the copies is linked. +; RUN: rm -f 2.o.thinlto.bc +; RUN: ld.lld --plugin-opt=thinlto-index-only -shared 1.o --start-lib 2.o --end-lib --start-lib 2.o --end-lib -o /dev/null +; RUN: llvm-dis < 2.o.thinlto.bc | grep -q '\^0 = module:' + ; NM: T f ;; The backend index for this module contains summaries from itself and