Index: llvm/lib/Linker/CMakeLists.txt =================================================================== --- llvm/lib/Linker/CMakeLists.txt +++ llvm/lib/Linker/CMakeLists.txt @@ -10,6 +10,7 @@ LINK_COMPONENTS Core + Object Support TransformUtils ) Index: llvm/lib/Linker/IRMover.cpp =================================================================== --- llvm/lib/Linker/IRMover.cpp +++ llvm/lib/Linker/IRMover.cpp @@ -17,6 +17,7 @@ #include "llvm/IR/GVMaterializer.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/TypeFinder.h" +#include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Support/Error.h" #include "llvm/Transforms/Utils/Cloning.h" #include @@ -1438,17 +1439,6 @@ DstM.setTargetTriple(SrcTriple.merge(DstTriple)); - // Append the module inline asm string. - if (!IsPerformingImport && !SrcM->getModuleInlineAsm().empty()) { - std::string SrcModuleInlineAsm = adjustInlineAsm(SrcM->getModuleInlineAsm(), - SrcTriple); - if (DstM.getModuleInlineAsm().empty()) - DstM.setModuleInlineAsm(SrcModuleInlineAsm); - else - DstM.setModuleInlineAsm(DstM.getModuleInlineAsm() + "\n" + - SrcModuleInlineAsm); - } - // Loop over all of the linked values to compute type mappings. computeTypeMapping(); @@ -1479,6 +1469,24 @@ // are properly remapped. linkNamedMDNodes(); + if (!IsPerformingImport && !SrcM->getModuleInlineAsm().empty()) { + // Append the module inline asm string. + DstM.appendModuleInlineAsm(adjustInlineAsm(SrcM->getModuleInlineAsm(), + SrcTriple)); + } else if (IsPerformingImport) { + // Import any symver directives for symbols in DstM. + ModuleSymbolTable::CollectAsmSymvers(*SrcM, + [&](StringRef Name, StringRef Alias) { + if (DstM.getNamedValue(Name)) { + SmallString<256> S(".symver "); + S += Name; + S += ", "; + S += Alias; + DstM.appendModuleInlineAsm(S); + } + }); + } + // Merge the module flags into the DstM module. return linkModuleFlagsMetadata(); } Index: llvm/test/Linker/link-arm-and-thumb-module-inline-asm.ll =================================================================== --- llvm/test/Linker/link-arm-and-thumb-module-inline-asm.ll +++ llvm/test/Linker/link-arm-and-thumb-module-inline-asm.ll @@ -9,12 +9,11 @@ module asm "add r1, r2, r2" -; CHECK: .text -; CHECK-NEXT: .balign 4 -; CHECK-NEXT: .arm -; CHECK-NEXT: add r1, r2, r2 -; CHECK-NEXT: module asm -; CHECK-NEXT: .text -; CHECK-NEXT: .balign 2 -; CHECK-NEXT: .thumb -; CHECK-NEXT: orn r1, r2, r2 +; CHECK: module asm ".text" +; CHECK-NEXT: module asm ".balign 4" +; CHECK-NEXT: module asm ".arm" +; CHECK-NEXT: module asm "add r1, r2, r2" +; CHECK-NEXT: module asm ".text" +; CHECK-NEXT: module asm ".balign 2" +; CHECK-NEXT: module asm ".thumb" +; CHECK-NEXT: module asm "orn r1, r2, r2" Index: llvm/test/ThinLTO/X86/Inputs/import-symver-foo.ll =================================================================== --- /dev/null +++ llvm/test/ThinLTO/X86/Inputs/import-symver-foo.ll @@ -0,0 +1,12 @@ +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +module asm ".symver bar, bar@BAR_1.2.3" + +declare dso_local i32 @bar() + +define dso_local i32 @foo() { +entry: + %call = tail call i32 @bar() + ret i32 %call +} Index: llvm/test/ThinLTO/X86/import-symver.ll =================================================================== --- /dev/null +++ llvm/test/ThinLTO/X86/import-symver.ll @@ -0,0 +1,28 @@ +; RUN: opt -thinlto-bc %s -o %t1.bc +; RUN: opt -thinlto-bc %p/Inputs/import-symver-foo.ll -o %t2.bc +; RUN: llvm-lto -thinlto-action=thinlink %t1.bc %t2.bc -o %t3.index.bc + +; RUN: llvm-lto -thinlto-action=import -exported-symbol=main %t1.bc -thinlto-index=%t3.index.bc +; RUN: llvm-dis %t1.bc.thinlto.imported.bc -o - | FileCheck --check-prefix=IMPORT %s + +; RUN: llvm-lto -thinlto-action=import -exported-symbol=main -import-instr-limit=0 %t1.bc -thinlto-index=%t3.index.bc +; RUN: llvm-dis %t1.bc.thinlto.imported.bc -o - | FileCheck --check-prefix=NOIMPORT %s + +; When @bar gets imported, the symver must be imported too. +; IMPORT: module asm ".symver bar, bar@BAR_1.2.3" +; IMPORT: declare dso_local i32 @bar() + +; When @bar isn't imported, the symver is also not imported. +; NOIMPORT-NOT: module asm +; NOIMPORT-NOT: declare dso_local i32 @bar() + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare dso_local i32 @foo() + +define dso_local i32 @main() { +entry: + %call = tail call i32 @foo() + ret i32 %call +} Index: llvm/utils/gn/secondary/llvm/lib/Linker/BUILD.gn =================================================================== --- llvm/utils/gn/secondary/llvm/lib/Linker/BUILD.gn +++ llvm/utils/gn/secondary/llvm/lib/Linker/BUILD.gn @@ -2,6 +2,7 @@ output_name = "LLVMLinker" deps = [ "//llvm/lib/IR", + "//llvm/lib/Object", "//llvm/lib/Support", "//llvm/lib/Transforms/Utils", ]