Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -713,7 +713,16 @@ template void BitcodeFile::parse(DenseSet &ComdatGroups) { - Obj = check(lto::InputFile::create(MB)); + + // Here we pass a new MemoryBufferRef which is identified by ArchiveName + + // member name + size of the archive. ThinLTO internally uses the memory buffer + // ref identifier to access its internal data structures and if two archives + // define two members with the same name, this causes a collision which results + // in only one of the objects taken in consideration at LTO time (which very likely + // causes undefined symbols later in the link). + Obj = check(lto::InputFile::create(MemoryBufferRef(MB.getBuffer(), Saver.save(ArchiveName + + MB.getBufferIdentifier() + + utostr(MB.getBuffer().size()))))); DenseSet KeptComdats; for (const auto &P : Obj->getComdatSymbolTable()) { StringRef N = Saver.save(P.first()); Index: test/ELF/lto/Inputs/thin1.ll =================================================================== --- /dev/null +++ test/ELF/lto/Inputs/thin1.ll @@ -0,0 +1,12 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-scei-ps4" + +define i32 @foo(i32 %goo) { +entry: + %goo.addr = alloca i32, align 4 + store i32 %goo, i32* %goo.addr, align 4 + %0 = load i32, i32* %goo.addr, align 4 + %1 = load i32, i32* %goo.addr, align 4 + %mul = mul nsw i32 %0, %1 + ret i32 %mul +} Index: test/ELF/lto/Inputs/thin2.ll =================================================================== --- /dev/null +++ test/ELF/lto/Inputs/thin2.ll @@ -0,0 +1,11 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-scei-ps4" + +define i32 @blah(i32 %meh) #0 { +entry: + %meh.addr = alloca i32, align 4 + store i32 %meh, i32* %meh.addr, align 4 + %0 = load i32, i32* %meh.addr, align 4 + %sub = sub nsw i32 %0, 48 + ret i32 %sub +} Index: test/ELF/lto/thin-archivecollision.ll =================================================================== --- /dev/null +++ test/ELF/lto/thin-archivecollision.ll @@ -0,0 +1,25 @@ +; RUN: opt -module-summary %s -o %t.o +; RUN: opt -module-summary %p/Inputs/thin1.ll -o %t.coll.o +; RUN: llvm-ar rcs %t1.a %t.coll.o +; RUN: opt -module-summary %p/Inputs/thin2.ll -o %t.coll.o +; RUN: llvm-ar rcsc %t2.a %t.coll.o + +; RUN: ld.lld %t.o %t1.a %t2.a -o %t +; RUN: llvm-nm %t | FileCheck %s + +; CHECK: T _start +; CHECK: T blah +; CHECK: T foo + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-scei-ps4" + +define i32 @_start() { +entry: + %call = call i32 @foo(i32 23) + %call1 = call i32 @blah(i32 37) + ret i32 0 +} + +declare i32 @foo(i32) #1 +declare i32 @blah(i32) #1