Index: include/llvm/LTO/LTO.h =================================================================== --- include/llvm/LTO/LTO.h +++ include/llvm/LTO/LTO.h @@ -387,7 +387,7 @@ ArrayRef Res); Error runRegularLTO(AddOutputFn AddOutput); - Error runThinLTO(AddOutputFn AddOutput); + Error runThinLTO(AddOutputFn AddOutput, bool HasRegularLTO); mutable bool CalledGetMaxTasks = false; }; Index: lib/LTO/LTO.cpp =================================================================== --- lib/LTO/LTO.cpp +++ lib/LTO/LTO.cpp @@ -410,11 +410,15 @@ } Error LTO::run(AddOutputFn AddOutput) { + // Save the status of having a regularLTO combined module, as + // this is needed for generating the ThinLTO Task ID, and + // the CombinedModule will be moved at the end of runRegularLTO. + bool HasRegularLTO = RegularLTO.CombinedModule != nullptr; // Invoke regular LTO if there was a regular LTO module to start with. - if (RegularLTO.CombinedModule) + if (HasRegularLTO) if (auto E = runRegularLTO(AddOutput)) return E; - return runThinLTO(AddOutput); + return runThinLTO(AddOutput, HasRegularLTO); } Error LTO::runRegularLTO(AddOutputFn AddOutput) { @@ -696,7 +700,7 @@ }; } -Error LTO::runThinLTO(AddOutputFn AddOutput) { +Error LTO::runThinLTO(AddOutputFn AddOutput, bool HasRegularLTO) { if (ThinLTO.ModuleMap.empty()) return Error(); @@ -753,9 +757,8 @@ // ParallelCodeGenParallelismLevel if an LTO module is present, as tasks 0 // through ParallelCodeGenParallelismLevel-1 are reserved for parallel code // generation partitions. - unsigned Task = RegularLTO.CombinedModule - ? RegularLTO.ParallelCodeGenParallelismLevel - : 0; + unsigned Task = + HasRegularLTO ? RegularLTO.ParallelCodeGenParallelismLevel : 0; unsigned Partition = 1; for (auto &Mod : ThinLTO.ModuleMap) { Index: test/LTO/Resolution/X86/Inputs/mixed_lto.ll =================================================================== --- /dev/null +++ test/LTO/Resolution/X86/Inputs/mixed_lto.ll @@ -0,0 +1,6 @@ +target triple = "x86_64-unknown-linux-gnu" +declare i32 @g() +define i32 @main() { + call i32 @g() + ret i32 0 +} Index: test/LTO/Resolution/X86/mixed_lto.ll =================================================================== --- /dev/null +++ test/LTO/Resolution/X86/mixed_lto.ll @@ -0,0 +1,19 @@ +; Test mixed-mode LTO (mix of regular and thin LTO objects) +; RUN: opt %s -o %t1.o +; RUN: opt -module-summary %p/Inputs/mixed_lto.ll -o %t2.o + +; RUN: llvm-lto2 -o %t3.o %t2.o %t1.o -r %t2.o,main,px -r %t2.o,g, -r %t1.o,g,px + +; Task 0 is the regular LTO file (this file) +; RUN: nm %t3.o.0 | FileCheck %s --check-prefix=NM0 +; NM0: T g + +; Task 1 is the (first) ThinLTO file (Inputs/mixed_lto.ll) +; RUN: nm %t3.o.1 | FileCheck %s --check-prefix=NM1 +; NM1-DAG: T main +; NM1-DAG: U g + +target triple = "x86_64-unknown-linux-gnu" +define i32 @g() { + ret i32 0 +} Index: test/tools/gold/X86/Inputs/mixed_lto.ll =================================================================== --- /dev/null +++ test/tools/gold/X86/Inputs/mixed_lto.ll @@ -0,0 +1,6 @@ +target triple = "x86_64-unknown-linux-gnu" +declare i32 @g() +define i32 @main() { + call i32 @g() + ret i32 0 +} Index: test/tools/gold/X86/mixed_lto.ll =================================================================== --- /dev/null +++ test/tools/gold/X86/mixed_lto.ll @@ -0,0 +1,18 @@ +; Test mixed-mode LTO (mix of regular and thin LTO objects) +; RUN: opt %s -o %t.o +; RUN: opt -module-summary %p/Inputs/mixed_lto.ll -o %t2.o + +; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: -shared \ +; RUN: --plugin-opt=thinlto \ +; RUN: --plugin-opt=-import-instr-limit=0 \ +; RUN: -o %t3.o %t2.o %t.o +; RUN: nm %t3.o | FileCheck %s + +; CHECK-DAG: T main +; CHECK-DAG: T g + +target triple = "x86_64-unknown-linux-gnu" +define i32 @g() { + ret i32 0 +}