mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
94a46bec1d
Variables declared with the dllimport attribute are accessed via a stub variable named __imp_<var>. In MinGW configurations, variables that aren't declared with a dllimport attribute might still end up imported from another DLL with runtime pseudo relocs. For x86_64, this avoids the risk that the target is out of range for a 32 bit PC relative reference, in case the target DLL is loaded further than 4 GB from the reference. It also avoids having to make the text section writable at runtime when doing the runtime fixups, which makes it worthwhile to do for i386 as well. Add stub variables for all dso local data references where a definition of the variable isn't visible within the module, since the DLL data autoimporting might make them imported even though they are marked as dso local within LLVM. Don't do this for variables that actually are defined within the same module, since we then know for sure that it actually is dso local. Don't do this for references to functions, since there's no need for runtime pseudo relocations for autoimporting them; if a function from a different DLL is called without the appropriate dllimport attribute, the call just gets routed via a thunk instead. GCC does something similar since 4.9 (when compiling with -mcmodel=medium or large; from that version, medium is the default code model for x86_64 mingw), but only for x86_64. Differential Revision: https://reviews.llvm.org/D51288 llvm-svn: 340942
95 lines
2.6 KiB
LLVM
95 lines
2.6 KiB
LLVM
; RUN: llc < %s -mtriple=x86_64-w64-mingw32 | FileCheck %s -check-prefix=CHECK-X64
|
|
; RUN: llc < %s -mtriple=i686-w64-mingw32 | FileCheck %s -check-prefix=CHECK-X86
|
|
|
|
@var = external local_unnamed_addr global i32, align 4
|
|
@dsolocalvar = external dso_local local_unnamed_addr global i32, align 4
|
|
@localvar = dso_local local_unnamed_addr global i32 0, align 4
|
|
@localcommon = common dso_local local_unnamed_addr global i32 0, align 4
|
|
@extvar = external dllimport local_unnamed_addr global i32, align 4
|
|
|
|
define dso_local i32 @getVar() {
|
|
; CHECK-X64-LABEL: getVar:
|
|
; CHECK-X64: movq .refptr.var(%rip), %rax
|
|
; CHECK-X64: movl (%rax), %eax
|
|
; CHECK-X64: retq
|
|
; CHECK-X86-LABEL: _getVar:
|
|
; CHECK-X86: movl .refptr._var, %eax
|
|
; CHECK-X86: movl (%eax), %eax
|
|
; CHECK-X86: retl
|
|
entry:
|
|
%0 = load i32, i32* @var, align 4
|
|
ret i32 %0
|
|
}
|
|
|
|
define dso_local i32 @getDsoLocalVar() {
|
|
; CHECK-X64-LABEL: getDsoLocalVar:
|
|
; CHECK-X64: movl dsolocalvar(%rip), %eax
|
|
; CHECK-X64: retq
|
|
; CHECK-X86-LABEL: _getDsoLocalVar:
|
|
; CHECK-X86: movl _dsolocalvar, %eax
|
|
; CHECK-X86: retl
|
|
entry:
|
|
%0 = load i32, i32* @dsolocalvar, align 4
|
|
ret i32 %0
|
|
}
|
|
|
|
define dso_local i32 @getLocalVar() {
|
|
; CHECK-X64-LABEL: getLocalVar:
|
|
; CHECK-X64: movl localvar(%rip), %eax
|
|
; CHECK-X64: retq
|
|
; CHECK-X86-LABEL: _getLocalVar:
|
|
; CHECK-X86: movl _localvar, %eax
|
|
; CHECK-X86: retl
|
|
entry:
|
|
%0 = load i32, i32* @localvar, align 4
|
|
ret i32 %0
|
|
}
|
|
|
|
define dso_local i32 @getLocalCommon() {
|
|
; CHECK-X64-LABEL: getLocalCommon:
|
|
; CHECK-X64: movl localcommon(%rip), %eax
|
|
; CHECK-X64: retq
|
|
; CHECK-X86-LABEL: _getLocalCommon:
|
|
; CHECK-X86: movl _localcommon, %eax
|
|
; CHECK-X86: retl
|
|
entry:
|
|
%0 = load i32, i32* @localcommon, align 4
|
|
ret i32 %0
|
|
}
|
|
|
|
define dso_local i32 @getExtVar() {
|
|
; CHECK-X64-LABEL: getExtVar:
|
|
; CHECK-X64: movq __imp_extvar(%rip), %rax
|
|
; CHECK-X64: movl (%rax), %eax
|
|
; CHECK-X64: retq
|
|
; CHECK-X86-LABEL: _getExtVar:
|
|
; CHECK-X86: movl __imp__extvar, %eax
|
|
; CHECK-X86: movl (%eax), %eax
|
|
; CHECK-X86: retl
|
|
entry:
|
|
%0 = load i32, i32* @extvar, align 4
|
|
ret i32 %0
|
|
}
|
|
|
|
define dso_local void @callFunc() {
|
|
; CHECK-X64-LABEL: callFunc:
|
|
; CHECK-X64: jmp otherFunc
|
|
; CHECK-X86-LABEL: _callFunc:
|
|
; CHECK-X86: jmp _otherFunc
|
|
entry:
|
|
tail call void @otherFunc()
|
|
ret void
|
|
}
|
|
|
|
declare dso_local void @otherFunc()
|
|
|
|
; CHECK-X64: .section .rdata$.refptr.var,"dr",discard,.refptr.var
|
|
; CHECK-X64: .globl .refptr.var
|
|
; CHECK-X64: .refptr.var:
|
|
; CHECK-X64: .quad var
|
|
|
|
; CHECK-X86: .section .rdata$.refptr._var,"dr",discard,.refptr._var
|
|
; CHECK-X86: .globl .refptr._var
|
|
; CHECK-X86: .refptr._var:
|
|
; CHECK-X86: .long _var
|