Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 2057e74

Browse files
committed
Differential Revision: http://reviews.llvm.org/D19040
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267229 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 4fc8e6f commit 2057e74

File tree

4 files changed

+142
-8
lines changed

4 files changed

+142
-8
lines changed

lib/Target/X86/X86Subtarget.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,24 @@ ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const {
8383
} else if (!isTargetWin64()) {
8484
assert(isTargetELF() && "Unknown rip-relative target");
8585

86-
// Extra load is needed for all externally visible globals.
87-
if (!GV->hasLocalLinkage() && GV->hasDefaultVisibility())
86+
// Extra load is needed for all externally visible globals except with
87+
// PIE as the definition of the global in an executable is not
88+
// overridden.
89+
90+
if (!GV->hasLocalLinkage() && GV->hasDefaultVisibility() &&
91+
!isGlobalDefinedInPIE(GV, TM))
8892
return X86II::MO_GOTPCREL;
8993
}
9094

9195
return X86II::MO_NO_FLAG;
9296
}
9397

9498
if (isPICStyleGOT()) { // 32-bit ELF targets.
95-
// Extra load is needed for all externally visible.
96-
if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
99+
// Extra load is needed for all externally visible globals except with
100+
// PIE as the definition of the global in an executable is not overridden.
101+
102+
if (GV->hasLocalLinkage() || GV->hasHiddenVisibility() ||
103+
isGlobalDefinedInPIE(GV, TM))
97104
return X86II::MO_GOTOFF;
98105
return X86II::MO_GOT;
99106
}

lib/Target/X86/X86Subtarget.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,14 @@ class X86Subtarget final : public X86GenSubtargetInfo {
548548
}
549549
}
550550

551+
/// Determine if this global is defined in a Position Independent
552+
/// Executable (PIE) where its definition cannot be interposed.
553+
bool isGlobalDefinedInPIE(const GlobalValue *GV,
554+
const TargetMachine &TM) const {
555+
return TM.Options.PositionIndependentExecutable &&
556+
!GV->isDeclarationForLinker();
557+
}
558+
551559
/// ClassifyGlobalReference - Classify a global variable reference for the
552560
/// current subtarget according to how we should reference it in a non-pcrel
553561
/// context.

test/CodeGen/X86/emutls-pie.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ entry:
3939

4040
define i32 @f1() {
4141
; X32-LABEL: f1:
42-
; X32: movl __emutls_v.i@GOT(%ebx), %eax
42+
; X32: leal __emutls_v.i@GOTOFF(%ebx), %eax
4343
; X32-NEXT: movl %eax, (%esp)
4444
; X32-NEXT: calll __emutls_get_address@PLT
4545
; X32-NEXT: movl (%eax), %eax
4646
; X32-NEXT: addl $8, %esp
4747
; X32-NEXT: popl %ebx
4848
; X32-NEXT: retl
4949
; X64-LABEL: f1:
50-
; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi
50+
; X64: leaq __emutls_v.i(%rip), %rdi
5151
; X64-NEXT: callq __emutls_get_address@PLT
5252
; X64-NEXT: movl (%rax), %eax
5353
; X64-NEXT: popq %rcx
@@ -60,11 +60,11 @@ entry:
6060

6161
define i32* @f2() {
6262
; X32-LABEL: f2:
63-
; X32: movl __emutls_v.i@GOT(%ebx), %eax
63+
; X32: leal __emutls_v.i@GOTOFF(%ebx), %eax
6464
; X32-NEXT: movl %eax, (%esp)
6565
; X32-NEXT: calll __emutls_get_address@PLT
6666
; X64-LABEL: f2:
67-
; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi
67+
; X64: leaq __emutls_v.i(%rip), %rdi
6868
; X64-NEXT: callq __emutls_get_address@PLT
6969

7070
entry:

test/CodeGen/X86/global-access-pie.ll

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
; RUN: llc < %s -march=x86-64 -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic -enable-pie \
2+
; RUN: | FileCheck -check-prefix=X64 %s
3+
; RUN: llc < %s -emulated-tls -march=x86 -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic -enable-pie \
4+
; RUN: | FileCheck -check-prefix=X32 %s
5+
6+
; External Linkage
7+
@a = global i32 0, align 4
8+
9+
define i32 @my_access_global_a() #0 {
10+
; X32-LABEL: my_access_global_a:
11+
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
12+
; X32-NEXT: movl a@GOTOFF(%eax), %eax
13+
; X64-LABEL: my_access_global_a:
14+
; X64: movl a(%rip), %eax
15+
16+
entry:
17+
%0 = load i32, i32* @a, align 4
18+
ret i32 %0
19+
}
20+
21+
; WeakAny Linkage
22+
@b = weak global i32 0, align 4
23+
24+
define i32 @my_access_global_b() #0 {
25+
; X32-LABEL: my_access_global_b:
26+
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
27+
; X32-NEXT: movl b@GOTOFF(%eax), %eax
28+
; X64-LABEL: my_access_global_b:
29+
; X64: movl b(%rip), %eax
30+
31+
entry:
32+
%0 = load i32, i32* @b, align 4
33+
ret i32 %0
34+
}
35+
36+
; Internal Linkage
37+
@c = internal global i32 0, align 4
38+
39+
define i32 @my_access_global_c() #0 {
40+
; X32-LABEL: my_access_global_c:
41+
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
42+
; X32-NEXT: movl c@GOTOFF(%eax), %eax
43+
; X64-LABEL: my_access_global_c:
44+
; X64: movl c(%rip), %eax
45+
46+
entry:
47+
%0 = load i32, i32* @c, align 4
48+
ret i32 %0
49+
}
50+
51+
; External Linkage, only declaration.
52+
@d = external global i32, align 4
53+
54+
define i32 @my_access_global_load_d() #0 {
55+
; X32-LABEL: my_access_global_load_d:
56+
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
57+
; X32-NEXT: movl d@GOT(%eax), %eax
58+
; X32-NEXT: movl (%eax), %eax
59+
; X64-LABEL: my_access_global_load_d:
60+
; X64: movq d@GOTPCREL(%rip), %rax
61+
; X64-NEXT: movl (%rax), %eax
62+
63+
entry:
64+
%0 = load i32, i32* @d, align 4
65+
ret i32 %0
66+
}
67+
68+
; External Linkage, only declaration, store a value.
69+
70+
define i32 @my_access_global_store_d() #0 {
71+
; X32-LABEL: my_access_global_store_d:
72+
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
73+
; X32-NEXT: movl d@GOT(%eax), %eax
74+
; X32-NEXT: movl $2, (%eax)
75+
; X64-LABEL: my_access_global_store_d:
76+
; X64: movq d@GOTPCREL(%rip), %rax
77+
; X64-NEXT: movl $2, (%rax)
78+
79+
entry:
80+
store i32 2, i32* @d, align 4
81+
ret i32 0
82+
}
83+
84+
; External Linkage, function pointer access.
85+
declare i32 @access_fp(i32 ()*)
86+
declare i32 @foo()
87+
88+
define i32 @my_access_fp_foo() #0 {
89+
; X32-LABEL: my_access_fp_foo:
90+
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %ebx
91+
; X32-NEXT: movl foo@GOT(%ebx), %eax
92+
; X64-LABEL: my_access_fp_foo:
93+
; X64: movq foo@GOTPCREL(%rip), %rdi
94+
95+
entry:
96+
%call = call i32 @access_fp(i32 ()* @foo)
97+
ret i32 %call
98+
}
99+
100+
; LinkOnceODR Linkage, function pointer access.
101+
102+
$bar = comdat any
103+
104+
define linkonce_odr i32 @bar() comdat {
105+
entry:
106+
ret i32 0
107+
}
108+
109+
define i32 @my_access_fp_bar() #0 {
110+
; X32-LABEL: my_access_fp_bar:
111+
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %ebx
112+
; X32-NEXT: leal bar@GOTOFF(%ebx), %eax
113+
; X64-LABEL: my_access_fp_bar:
114+
; X64: leaq bar(%rip), %rdi
115+
116+
entry:
117+
%call = call i32 @access_fp(i32 ()* @bar)
118+
ret i32 %call
119+
}

0 commit comments

Comments
 (0)