Index: lib/LTO/LTOCodeGenerator.cpp =================================================================== --- lib/LTO/LTOCodeGenerator.cpp +++ lib/LTO/LTOCodeGenerator.cpp @@ -370,8 +370,8 @@ static void accumulateAndSortLibcalls(std::vector &Libcalls, const TargetLibraryInfo& TLI, - const TargetLowering *Lowering) -{ + const Module &Mod, + const TargetMachine &TM) { // TargetLibraryInfo has info on C runtime library calls on the current // target. for (unsigned I = 0, E = static_cast(LibFunc::NumLibFuncs); @@ -381,14 +381,21 @@ Libcalls.push_back(TLI.getName(F)); } - // TargetLowering has info on library calls that CodeGen expects to be - // available, both from the C runtime and compiler-rt. - if (Lowering) - for (unsigned I = 0, E = static_cast(RTLIB::UNKNOWN_LIBCALL); - I != E; ++I) - if (const char *Name - = Lowering->getLibcallName(static_cast(I))) - Libcalls.push_back(Name); + SmallPtrSet TLSet; + + for (const Function &F : Mod) { + const TargetLowering *Lowering = + TM.getSubtargetImpl(F)->getTargetLowering(); + + if (Lowering && TLSet.insert(Lowering).second) + // TargetLowering has info on library calls that CodeGen expects to be + // available, both from the C runtime and compiler-rt. + for (unsigned I = 0, E = static_cast(RTLIB::UNKNOWN_LIBCALL); + I != E; ++I) + if (const char *Name = + Lowering->getLibcallName(static_cast(I))) + Libcalls.push_back(Name); + } array_pod_sort(Libcalls.begin(), Libcalls.end()); Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()), @@ -412,8 +419,8 @@ std::vector Libcalls; TargetLibraryInfoImpl TLII(Triple(TargetMach->getTargetTriple())); TargetLibraryInfo TLI(TLII); - accumulateAndSortLibcalls( - Libcalls, TLI, TargetMach->getSubtargetImpl()->getTargetLowering()); + + accumulateAndSortLibcalls(Libcalls, TLI, *mergedModule, *TargetMach); for (Module::iterator f = mergedModule->begin(), e = mergedModule->end(); f != e; ++f) Index: test/LTO/runtime-library-subtarget.ll =================================================================== --- /dev/null +++ test/LTO/runtime-library-subtarget.ll @@ -0,0 +1,18 @@ +; Check that user-defined runtime library function __addsf3vfp is not removed +; +; RUN: llvm-as <%s >%t1 +; RUN: llvm-lto -o %t2 %t1 -mcpu arm1176jz-s +; RUN: llvm-nm %t2 | FileCheck %s + +target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" +target triple = "thumbv7-apple-ios" + +; CHECK: ___addsf3vfp + +define float @__addsf3vfp(float %a, float %b) #0 { +entry: + %add = fadd float %a, %b + ret float %add +} + +attributes #0 = { "target-cpu"="arm1176jzf-s"} Index: tools/llvm-lto/llvm-lto.cpp =================================================================== --- tools/llvm-lto/llvm-lto.cpp +++ tools/llvm-lto/llvm-lto.cpp @@ -217,6 +217,8 @@ for (unsigned i = 0; i < KeptDSOSyms.size(); ++i) CodeGen.addMustPreserveSymbol(KeptDSOSyms[i].c_str()); + CodeGen.setCpu(MCPU.c_str()); + std::string attrs; for (unsigned i = 0; i < MAttrs.size(); ++i) { if (i > 0)