From f8c8b1a8b3c7a2c90a35079c257558664f97ff78 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 30 Nov 2020 16:21:54 +0100 Subject: [PATCH] [ThinLTO] Import symver directives for imported symbols (PR48214) When importing symbols from another module, also import any corresponding symver directives. Differential revision: https://reviews.llvm.org/D92335 --- lib/Linker/CMakeLists.txt | 1 + lib/Linker/IRMover.cpp | 25 ++++++++++++----- test/ThinLTO/X86/Inputs/import-symver-foo.ll | 12 +++++++++ test/ThinLTO/X86/import-symver.ll | 28 ++++++++++++++++++++ utils/gn/secondary/llvm/lib/Linker/BUILD.gn | 1 + 5 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 test/ThinLTO/X86/Inputs/import-symver-foo.ll create mode 100644 test/ThinLTO/X86/import-symver.ll diff --git a/lib/Linker/CMakeLists.txt b/lib/Linker/CMakeLists.txt index 5abfc8c02ef..a2a71de975b 100644 --- a/lib/Linker/CMakeLists.txt +++ b/lib/Linker/CMakeLists.txt @@ -10,6 +10,7 @@ add_llvm_component_library(LLVMLinker LINK_COMPONENTS Core + Object Support TransformUtils ) diff --git a/lib/Linker/IRMover.cpp b/lib/Linker/IRMover.cpp index 5a67266a9f4..b7a9beeeeb1 100644 --- a/lib/Linker/IRMover.cpp +++ b/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,12 +1439,6 @@ Error IRLinker::run() { DstM.setTargetTriple(SrcTriple.merge(DstTriple)); - // Append the module inline asm string. - if (!IsPerformingImport && !SrcM->getModuleInlineAsm().empty()) { - DstM.appendModuleInlineAsm(adjustInlineAsm(SrcM->getModuleInlineAsm(), - SrcTriple)); - } - // Loop over all of the linked values to compute type mappings. computeTypeMapping(); @@ -1474,6 +1469,24 @@ Error IRLinker::run() { // 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(); } diff --git a/test/ThinLTO/X86/Inputs/import-symver-foo.ll b/test/ThinLTO/X86/Inputs/import-symver-foo.ll new file mode 100644 index 00000000000..95545b433f9 --- /dev/null +++ b/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 +} diff --git a/test/ThinLTO/X86/import-symver.ll b/test/ThinLTO/X86/import-symver.ll new file mode 100644 index 00000000000..556c4fd992f --- /dev/null +++ b/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 +} diff --git a/utils/gn/secondary/llvm/lib/Linker/BUILD.gn b/utils/gn/secondary/llvm/lib/Linker/BUILD.gn index 42dbd92b48a..f16601825e1 100644 --- a/utils/gn/secondary/llvm/lib/Linker/BUILD.gn +++ b/utils/gn/secondary/llvm/lib/Linker/BUILD.gn @@ -2,6 +2,7 @@ static_library("Linker") { output_name = "LLVMLinker" deps = [ "//llvm/lib/IR", + "//llvm/lib/Object", "//llvm/lib/Support", "//llvm/lib/Transforms/Utils", ]