[AArch64] Properly handle dllimport of variables when using fast-isel

Differential Revision: https://reviews.llvm.org/D42567

llvm-svn: 323810
This commit is contained in:
Martin Storsjo 2018-01-30 19:50:51 +00:00
parent 61a29ded5d
commit 708498a164
3 changed files with 22 additions and 15 deletions

View File

@ -476,26 +476,27 @@ unsigned AArch64FastISel::materializeGV(const GlobalValue *GV) {
// ADRP + LDRX
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),
ADRPReg)
.addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGE);
.addGlobalAddress(GV, 0, AArch64II::MO_PAGE | OpFlags);
ResultReg = createResultReg(&AArch64::GPR64RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::LDRXui),
ResultReg)
.addReg(ADRPReg)
.addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGEOFF |
AArch64II::MO_NC);
.addReg(ADRPReg)
.addGlobalAddress(GV, 0,
AArch64II::MO_PAGEOFF | AArch64II::MO_NC | OpFlags);
} else {
// ADRP + ADDX
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),
ADRPReg)
.addGlobalAddress(GV, 0, AArch64II::MO_PAGE);
.addGlobalAddress(GV, 0, AArch64II::MO_PAGE | OpFlags);
ResultReg = createResultReg(&AArch64::GPR64spRegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADDXri),
ResultReg)
.addReg(ADRPReg)
.addGlobalAddress(GV, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC)
.addImm(0);
.addReg(ADRPReg)
.addGlobalAddress(GV, 0,
AArch64II::MO_PAGEOFF | AArch64II::MO_NC | OpFlags)
.addImm(0);
}
return ResultReg;
}

View File

@ -195,15 +195,18 @@ AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV,
if (TM.getCodeModel() == CodeModel::Large && isTargetMachO())
return AArch64II::MO_GOT;
unsigned Flags = GV->hasDLLImportStorageClass() ? AArch64II::MO_DLLIMPORT
: AArch64II::MO_NO_FLAG;
if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
return AArch64II::MO_GOT;
return AArch64II::MO_GOT | Flags;
// The small code model's direct accesses use ADRP, which cannot
// necessarily produce the value 0 (if the code is above 4GB).
if (useSmallAddressing() && GV->hasExternalWeakLinkage())
return AArch64II::MO_GOT;
return AArch64II::MO_GOT | Flags;
return AArch64II::MO_NO_FLAG;
return Flags;
}
unsigned char AArch64Subtarget::classifyGlobalFunctionReference(

View File

@ -1,4 +1,5 @@
; RUN: llc -mtriple aarch64-unknown-windows-msvc -filetype asm -o - %s | FileCheck %s
; RUN: llc -mtriple aarch64-unknown-windows-msvc -filetype asm -o - %s | FileCheck %s -check-prefixes=CHECK,DAG-ISEL
; RUN: llc -mtriple aarch64-unknown-windows-msvc -fast-isel -filetype asm -o - %s | FileCheck %s -check-prefixes=CHECK,FAST-ISEL
@var = external dllimport global i32
@ext = external global i32
@ -23,7 +24,9 @@ define i32 @get_ext() {
; CHECK-LABEL: get_ext
; CHECK: adrp x8, ext
; CHECK: ldr w0, [x8, ext]
; DAG-ISEL: ldr w0, [x8, ext]
; FAST-ISEL: add x8, x8, ext
; FAST-ISEL: ldr w0, [x8]
; CHECK: ret
define i32* @get_var_pointer() {
@ -31,8 +34,8 @@ define i32* @get_var_pointer() {
}
; CHECK-LABEL: get_var_pointer
; CHECK: adrp x0, __imp_var
; CHECK: ldr x0, [x0, __imp_var]
; CHECK: adrp [[REG1:x[0-9]+]], __imp_var
; CHECK: ldr {{x[0-9]+}}, {{\[}}[[REG1]], __imp_var]
; CHECK: ret
define i32 @call_external() {