Skip to content

Commit

Permalink
[ThinLTO] Import symver directives for imported symbols (PR48214)
Browse files Browse the repository at this point in the history
When importing symbols from another module, also import any
corresponding symver directives.

Differential revision: https://reviews.llvm.org/D92335
  • Loading branch information
zmodem committed Dec 2, 2020
1 parent 45d8a78 commit 437c465
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 6 deletions.
1 change: 1 addition & 0 deletions llvm/lib/Linker/CMakeLists.txt
Expand Up @@ -10,6 +10,7 @@ add_llvm_component_library(LLVMLinker

LINK_COMPONENTS
Core
Object
Support
TransformUtils
)
25 changes: 19 additions & 6 deletions llvm/lib/Linker/IRMover.cpp
Expand Up @@ -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 <utility>
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();
}
Expand Down
12 changes: 12 additions & 0 deletions 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
}
28 changes: 28 additions & 0 deletions 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
}
1 change: 1 addition & 0 deletions llvm/utils/gn/secondary/llvm/lib/Linker/BUILD.gn
Expand Up @@ -2,6 +2,7 @@ static_library("Linker") {
output_name = "LLVMLinker"
deps = [
"//llvm/lib/IR",
"//llvm/lib/Object",
"//llvm/lib/Support",
"//llvm/lib/Transforms/Utils",
]
Expand Down

0 comments on commit 437c465

Please sign in to comment.