1 ; RUN: llc -mtriple x86_64-pc-linux -relocation-model=static < %s | \
2 ; RUN: FileCheck --check-prefixes=COMMON,STATIC %s
3 ; RUN: llc -mtriple x86_64-pc-linux -relocation-model=pic < %s | \
4 ; RUN: FileCheck --check-prefixes=COMMON,CHECK %s
5 ; RUN: llc -mtriple x86_64-pc-linux -relocation-model=dynamic-no-pic < %s | \
6 ; RUN: FileCheck --check-prefixes=COMMON,CHECK %s
10 ; RUN: llc -mtriple i386-pc-linux \
11 ; RUN: -relocation-model=pic < %s | FileCheck --check-prefix=CHECK32 %s
15 @strong_default_global = global i32 42
16 define ptr @get_strong_default_global() {
17 ret ptr @strong_default_global
19 ; CHECK: movq strong_default_global@GOTPCREL(%rip), %rax
20 ; STATIC: movq strong_default_global@GOTPCREL(%rip), %rax
21 ; CHECK32: movl strong_default_global@GOT(%eax), %eax
23 @strong_hidden_global = hidden global i32 42
24 define ptr @get_hidden_default_global() {
25 ret ptr @strong_hidden_global
27 ; CHECK: leaq strong_hidden_global(%rip), %rax
28 ; STATIC: movl $strong_hidden_global, %eax
29 ; CHECK32: leal strong_hidden_global@GOTOFF(%eax), %eax
31 @weak_default_global = weak global i32 42
32 define ptr @get_weak_default_global() {
33 ret ptr @weak_default_global
35 ; CHECK: movq weak_default_global@GOTPCREL(%rip), %rax
36 ; STATIC: movq weak_default_global@GOTPCREL(%rip), %rax
37 ; CHECK32: movl weak_default_global@GOT(%eax), %eax
39 @external_default_global = external global i32
40 define ptr @get_external_default_global() {
41 ret ptr @external_default_global
43 ; CHECK: movq external_default_global@GOTPCREL(%rip), %rax
44 ; STATIC: movq external_default_global@GOTPCREL(%rip), %rax
45 ; CHECK32: movl external_default_global@GOT(%eax), %eax
47 @strong_local_global = dso_local global i32 42
48 define ptr @get_strong_local_global() {
49 ret ptr @strong_local_global
51 ; CHECK: leaq .Lstrong_local_global$local(%rip), %rax
52 ; STATIC: movl $strong_local_global, %eax
53 ; CHECK32: leal .Lstrong_local_global$local@GOTOFF(%eax), %eax
55 @weak_local_global = weak dso_local global i32 42
56 define ptr @get_weak_local_global() {
57 ret ptr @weak_local_global
59 ; CHECK: leaq weak_local_global(%rip), %rax
60 ; STATIC: movl $weak_local_global, %eax
61 ; CHECK32: leal weak_local_global@GOTOFF(%eax), %eax
63 @external_local_global = external dso_local global i32
64 define ptr @get_external_local_global() {
65 ret ptr @external_local_global
67 ; CHECK: leaq external_local_global(%rip), %rax
68 ; STATIC: movl $external_local_global, %eax
69 ; CHECK32: leal external_local_global@GOTOFF(%eax), %eax
72 @strong_preemptable_global = dso_preemptable global i32 42
73 define ptr @get_strong_preemptable_global() {
74 ret ptr @strong_preemptable_global
76 ; CHECK: movq strong_preemptable_global@GOTPCREL(%rip), %rax
77 ; STATIC: movq strong_preemptable_global@GOTPCREL(%rip), %rax
78 ; CHECK32: movl strong_preemptable_global@GOT(%eax), %eax
80 @weak_preemptable_global = weak dso_preemptable global i32 42
81 define ptr @get_weak_preemptable_global() {
82 ret ptr @weak_preemptable_global
84 ; CHECK: movq weak_preemptable_global@GOTPCREL(%rip), %rax
85 ; STATIC: movq weak_preemptable_global@GOTPCREL(%rip), %rax
86 ; CHECK32: movl weak_preemptable_global@GOT(%eax), %eax
88 @external_preemptable_global = external dso_preemptable global i32
89 define ptr @get_external_preemptable_global() {
90 ret ptr @external_preemptable_global
92 ; CHECK: movq external_preemptable_global@GOTPCREL(%rip), %rax
93 ; STATIC: movq external_preemptable_global@GOTPCREL(%rip), %rax
94 ; CHECK32: movl external_preemptable_global@GOT(%eax), %eax
97 @aliasee = global i32 42
99 @strong_default_alias = alias i32, ptr @aliasee
100 define ptr @get_strong_default_alias() {
101 ret ptr @strong_default_alias
103 ; CHECK: movq strong_default_alias@GOTPCREL(%rip), %rax
104 ; STATIC: movq strong_default_alias@GOTPCREL(%rip), %rax
105 ; CHECK32: movl strong_default_alias@GOT(%eax), %eax
107 @strong_hidden_alias = hidden alias i32, ptr @aliasee
108 define ptr @get_strong_hidden_alias() {
109 ret ptr @strong_hidden_alias
111 ; CHECK: leaq strong_hidden_alias(%rip), %rax
112 ; STATIC: movl $strong_hidden_alias, %eax
113 ; CHECK32: leal strong_hidden_alias@GOTOFF(%eax), %eax
115 @weak_default_alias = weak alias i32, ptr @aliasee
116 define ptr @get_weak_default_alias() {
117 ret ptr @weak_default_alias
119 ; CHECK: movq weak_default_alias@GOTPCREL(%rip), %rax
120 ; STATIC: movq weak_default_alias@GOTPCREL(%rip), %rax
121 ; CHECK32: movl weak_default_alias@GOT(%eax), %eax
123 @strong_local_alias = dso_local alias i32, ptr @aliasee
124 define ptr @get_strong_local_alias() {
125 ret ptr @strong_local_alias
127 ; CHECK: leaq .Lstrong_local_alias$local(%rip), %rax
128 ; STATIC: movl $strong_local_alias, %eax
129 ; CHECK32: leal .Lstrong_local_alias$local@GOTOFF(%eax), %eax
131 @weak_local_alias = weak dso_local alias i32, ptr @aliasee
132 define ptr @get_weak_local_alias() {
133 ret ptr @weak_local_alias
135 ; CHECK: leaq weak_local_alias(%rip), %rax
136 ; STATIC: movl $weak_local_alias, %eax
137 ; CHECK32: leal weak_local_alias@GOTOFF(%eax), %eax
140 @strong_preemptable_alias = dso_preemptable alias i32, ptr @aliasee
141 define ptr @get_strong_preemptable_alias() {
142 ret ptr @strong_preemptable_alias
144 ; CHECK: movq strong_preemptable_alias@GOTPCREL(%rip), %rax
145 ; STATIC: movq strong_preemptable_alias@GOTPCREL(%rip), %rax
146 ; CHECK32: movl strong_preemptable_alias@GOT(%eax), %eax
148 @weak_preemptable_alias = weak dso_preemptable alias i32, ptr @aliasee
149 define ptr @get_weak_preemptable_alias() {
150 ret ptr @weak_preemptable_alias
152 ; CHECK: movq weak_preemptable_alias@GOTPCREL(%rip), %rax
153 ; STATIC: movq weak_preemptable_alias@GOTPCREL(%rip), %rax
154 ; CHECK32: movl weak_preemptable_alias@GOT(%eax), %eax
158 define void @strong_default_function() {
161 define ptr @get_strong_default_function() {
162 ret ptr @strong_default_function
164 ; CHECK: movq strong_default_function@GOTPCREL(%rip), %rax
165 ; STATIC: movq strong_default_function@GOTPCREL(%rip), %rax
166 ; CHECK32: movl strong_default_function@GOT(%eax), %eax
168 define hidden void @strong_hidden_function() {
171 define ptr @get_strong_hidden_function() {
172 ret ptr @strong_hidden_function
174 ; CHECK: leaq strong_hidden_function(%rip), %rax
175 ; STATIC: movl $strong_hidden_function, %eax
176 ; CHECK32: leal strong_hidden_function@GOTOFF(%eax), %eax
178 define weak void @weak_default_function() {
181 define ptr @get_weak_default_function() {
182 ret ptr @weak_default_function
184 ; CHECK: movq weak_default_function@GOTPCREL(%rip), %rax
185 ; STATIC: movq weak_default_function@GOTPCREL(%rip), %rax
186 ; CHECK32: movl weak_default_function@GOT(%eax), %eax
188 declare void @external_default_function()
189 define ptr @get_external_default_function() {
190 ret ptr @external_default_function
192 ; CHECK: movq external_default_function@GOTPCREL(%rip), %rax
193 ; STATIC: movq external_default_function@GOTPCREL(%rip), %rax
194 ; CHECK32: movl external_default_function@GOT(%eax), %eax
196 define dso_local void @strong_local_function() {
199 define ptr @get_strong_local_function() {
200 ret ptr @strong_local_function
202 ; COMMON: {{^}}strong_local_function:
203 ; CHECK-NEXT: .Lstrong_local_function$local:
204 ; CHECK: leaq .Lstrong_local_function$local(%rip), %rax
205 ; STATIC: movl $strong_local_function, %eax
206 ; CHECK32: leal .Lstrong_local_function$local@GOTOFF(%eax), %eax
208 define weak dso_local void @weak_local_function() {
211 define ptr @get_weak_local_function() {
212 ret ptr @weak_local_function
214 ; CHECK: leaq weak_local_function(%rip), %rax
215 ; STATIC: movl $weak_local_function, %eax
216 ; CHECK32: leal weak_local_function@GOTOFF(%eax), %eax
218 declare dso_local void @external_local_function()
219 define ptr @get_external_local_function() {
220 ret ptr @external_local_function
222 ; CHECK: leaq external_local_function(%rip), %rax
223 ; STATIC: movl $external_local_function, %eax
224 ; CHECK32: leal external_local_function@GOTOFF(%eax), %eax
227 define dso_preemptable void @strong_preemptable_function() {
230 define ptr @get_strong_preemptable_function() {
231 ret ptr @strong_preemptable_function
233 ; CHECK: movq strong_preemptable_function@GOTPCREL(%rip), %rax
234 ; STATIC: movq strong_preemptable_function@GOTPCREL(%rip), %rax
235 ; CHECK32: movl strong_preemptable_function@GOT(%eax), %eax
237 define weak dso_preemptable void @weak_preemptable_function() {
240 define ptr @get_weak_preemptable_function() {
241 ret ptr @weak_preemptable_function
243 ; CHECK: movq weak_preemptable_function@GOTPCREL(%rip), %rax
244 ; STATIC: movq weak_preemptable_function@GOTPCREL(%rip), %rax
245 ; CHECK32: movl weak_preemptable_function@GOT(%eax), %eax
247 declare dso_preemptable void @external_preemptable_function()
248 define ptr @get_external_preemptable_function() {
249 ret ptr @external_preemptable_function
251 ; CHECK: movq external_preemptable_function@GOTPCREL(%rip), %rax
252 ; STATIC: movq external_preemptable_function@GOTPCREL(%rip), %rax
253 ; CHECK32: movl external_preemptable_function@GOT(%eax), %eax
255 $comdat_nodeduplicate_local = comdat nodeduplicate
256 $comdat_nodeduplicate_preemptable = comdat nodeduplicate
257 $comdat_any_local = comdat any
259 ;; -fpic -fno-semantic-interposition may add dso_local. Some instrumentation
260 ;; may add comdat nodeduplicate. We should use local aliases to make the symbol
261 ;; non-preemptible in the linker.
262 define dso_local ptr @comdat_nodeduplicate_local() comdat {
263 ret ptr @comdat_nodeduplicate_local
265 ; CHECK: leaq .Lcomdat_nodeduplicate_local$local(%rip), %rax
266 ; STATIC: movl $comdat_nodeduplicate_local, %eax
268 define dso_preemptable ptr @comdat_nodeduplicate_preemptable() comdat {
269 ret ptr @comdat_nodeduplicate_preemptable
271 ; CHECK: movq comdat_nodeduplicate_preemptable@GOTPCREL(%rip), %rax
272 ; STATIC: movq comdat_nodeduplicate_preemptable@GOTPCREL(%rip), %rax
274 ;; Check the behavior for the invalid construct.
275 define dso_local ptr @comdat_any_local() comdat {
276 ret ptr @comdat_any_local
278 ; CHECK: leaq comdat_any_local(%rip), %rax
279 ; STATIC: movl $comdat_any_local, %eax
281 !llvm.module.flags = !{!0}
282 !0 = !{i32 7, !"PIC Level", i32 2}
284 ; COMMON: {{^}}strong_local_global:
285 ; CHECK-NEXT: .Lstrong_local_global$local:
287 ; COMMON: .globl strong_default_alias
288 ; COMMON-NEXT: .set strong_default_alias, aliasee
289 ; COMMON-NEXT: .globl strong_hidden_alias
290 ; COMMON-NEXT: .hidden strong_hidden_alias
291 ; COMMON-NEXT: .set strong_hidden_alias, aliasee
292 ; COMMON-NEXT: .weak weak_default_alias
293 ; COMMON-NEXT: .set weak_default_alias, aliasee
294 ; COMMON-NEXT: .globl strong_local_alias
295 ; COMMON-NEXT: .set strong_local_alias, aliasee
296 ; CHECK-NEXT: .set .Lstrong_local_alias$local, aliasee
297 ; COMMON-NEXT: .weak weak_local_alias
298 ; COMMON-NEXT: .set weak_local_alias, aliasee
299 ; COMMON-NEXT: .globl strong_preemptable_alias
300 ; COMMON-NEXT: .set strong_preemptable_alias, aliasee
301 ; COMMON-NEXT: .weak weak_preemptable_alias
302 ; COMMON-NEXT: .set weak_preemptable_alias, aliasee