1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; Run with --no_x86_scrub_rip because we care a lot about how globals are
3 ; accessed in the code model.
5 ; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-STATIC
6 ; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-STATIC
7 ; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-STATIC
8 ; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-PIC
9 ; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-PIC
10 ; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-PIC
12 ; Generated from this C source:
14 ; static int static_data[10];
15 ; int global_data[10] = {1, 2};
16 ; extern int extern_data[10];
18 ; int *lea_static_data() { return &static_data[0]; }
19 ; int *lea_global_data() { return &global_data[0]; }
20 ; int *lea_extern_data() { return &extern_data[0]; }
22 ; static void static_fn(void) {}
23 ; void global_fn(void) {}
24 ; void extern_fn(void);
26 ; typedef void (*void_fn)(void);
27 ; void_fn lea_static_fn() { return &static_fn; }
28 ; void_fn lea_global_fn() { return &global_fn; }
29 ; void_fn lea_extern_fn() { return &extern_fn; }
32 ; ModuleID = 'model.c'
33 source_filename = "model.c"
34 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
35 target triple = "x86_64--linux"
37 @global_data = dso_local global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0], align 16
38 @static_data = internal global [10 x i32] zeroinitializer, align 16
39 @extern_data = external global [10 x i32], align 16
40 @thread_data = external thread_local global i32, align 4
43 define dso_local i32* @lea_static_data() #0 {
44 ; SMALL-STATIC-LABEL: lea_static_data:
45 ; SMALL-STATIC: # %bb.0:
46 ; SMALL-STATIC-NEXT: movl $static_data, %eax
47 ; SMALL-STATIC-NEXT: retq
49 ; MEDIUM-STATIC-LABEL: lea_static_data:
50 ; MEDIUM-STATIC: # %bb.0:
51 ; MEDIUM-STATIC-NEXT: movabsq $static_data, %rax
52 ; MEDIUM-STATIC-NEXT: retq
54 ; LARGE-STATIC-LABEL: lea_static_data:
55 ; LARGE-STATIC: # %bb.0:
56 ; LARGE-STATIC-NEXT: movabsq $static_data, %rax
57 ; LARGE-STATIC-NEXT: retq
59 ; SMALL-PIC-LABEL: lea_static_data:
61 ; SMALL-PIC-NEXT: leaq static_data(%rip), %rax
62 ; SMALL-PIC-NEXT: retq
64 ; MEDIUM-PIC-LABEL: lea_static_data:
65 ; MEDIUM-PIC: # %bb.0:
66 ; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
67 ; MEDIUM-PIC-NEXT: movabsq $static_data@GOTOFF, %rax
68 ; MEDIUM-PIC-NEXT: addq %rcx, %rax
69 ; MEDIUM-PIC-NEXT: retq
71 ; LARGE-PIC-LABEL: lea_static_data:
73 ; LARGE-PIC-NEXT: .L0$pb:
74 ; LARGE-PIC-NEXT: leaq .L0$pb(%rip), %rax
75 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L0$pb, %rcx
76 ; LARGE-PIC-NEXT: addq %rax, %rcx
77 ; LARGE-PIC-NEXT: movabsq $static_data@GOTOFF, %rax
78 ; LARGE-PIC-NEXT: addq %rcx, %rax
79 ; LARGE-PIC-NEXT: retq
80 ret i32* getelementptr inbounds ([10 x i32], [10 x i32]* @static_data, i64 0, i64 0)
83 define dso_local i32* @lea_global_data() #0 {
84 ; SMALL-STATIC-LABEL: lea_global_data:
85 ; SMALL-STATIC: # %bb.0:
86 ; SMALL-STATIC-NEXT: movl $global_data, %eax
87 ; SMALL-STATIC-NEXT: retq
89 ; MEDIUM-STATIC-LABEL: lea_global_data:
90 ; MEDIUM-STATIC: # %bb.0:
91 ; MEDIUM-STATIC-NEXT: movabsq $global_data, %rax
92 ; MEDIUM-STATIC-NEXT: retq
94 ; LARGE-STATIC-LABEL: lea_global_data:
95 ; LARGE-STATIC: # %bb.0:
96 ; LARGE-STATIC-NEXT: movabsq $global_data, %rax
97 ; LARGE-STATIC-NEXT: retq
99 ; SMALL-PIC-LABEL: lea_global_data:
100 ; SMALL-PIC: # %bb.0:
101 ; SMALL-PIC-NEXT: leaq global_data(%rip), %rax
102 ; SMALL-PIC-NEXT: retq
104 ; MEDIUM-PIC-LABEL: lea_global_data:
105 ; MEDIUM-PIC: # %bb.0:
106 ; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
107 ; MEDIUM-PIC-NEXT: movabsq $global_data@GOTOFF, %rax
108 ; MEDIUM-PIC-NEXT: addq %rcx, %rax
109 ; MEDIUM-PIC-NEXT: retq
111 ; LARGE-PIC-LABEL: lea_global_data:
112 ; LARGE-PIC: # %bb.0:
113 ; LARGE-PIC-NEXT: .L1$pb:
114 ; LARGE-PIC-NEXT: leaq .L1$pb(%rip), %rax
115 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx
116 ; LARGE-PIC-NEXT: addq %rax, %rcx
117 ; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax
118 ; LARGE-PIC-NEXT: addq %rcx, %rax
119 ; LARGE-PIC-NEXT: retq
120 ret i32* getelementptr inbounds ([10 x i32], [10 x i32]* @global_data, i64 0, i64 0)
123 define dso_local i32* @lea_extern_data() #0 {
124 ; SMALL-STATIC-LABEL: lea_extern_data:
125 ; SMALL-STATIC: # %bb.0:
126 ; SMALL-STATIC-NEXT: movl $extern_data, %eax
127 ; SMALL-STATIC-NEXT: retq
129 ; MEDIUM-STATIC-LABEL: lea_extern_data:
130 ; MEDIUM-STATIC: # %bb.0:
131 ; MEDIUM-STATIC-NEXT: movabsq $extern_data, %rax
132 ; MEDIUM-STATIC-NEXT: retq
134 ; LARGE-STATIC-LABEL: lea_extern_data:
135 ; LARGE-STATIC: # %bb.0:
136 ; LARGE-STATIC-NEXT: movabsq $extern_data, %rax
137 ; LARGE-STATIC-NEXT: retq
139 ; SMALL-PIC-LABEL: lea_extern_data:
140 ; SMALL-PIC: # %bb.0:
141 ; SMALL-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax
142 ; SMALL-PIC-NEXT: retq
144 ; MEDIUM-PIC-LABEL: lea_extern_data:
145 ; MEDIUM-PIC: # %bb.0:
146 ; MEDIUM-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax
147 ; MEDIUM-PIC-NEXT: retq
149 ; LARGE-PIC-LABEL: lea_extern_data:
150 ; LARGE-PIC: # %bb.0:
151 ; LARGE-PIC-NEXT: .L2$pb:
152 ; LARGE-PIC-NEXT: leaq .L2$pb(%rip), %rax
153 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx
154 ; LARGE-PIC-NEXT: addq %rax, %rcx
155 ; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax
156 ; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax
157 ; LARGE-PIC-NEXT: retq
158 ret i32* getelementptr inbounds ([10 x i32], [10 x i32]* @extern_data, i64 0, i64 0)
161 define dso_local i32 @load_global_data() #0 {
162 ; SMALL-STATIC-LABEL: load_global_data:
163 ; SMALL-STATIC: # %bb.0:
164 ; SMALL-STATIC-NEXT: movl global_data+8(%rip), %eax
165 ; SMALL-STATIC-NEXT: retq
167 ; MEDIUM-STATIC-LABEL: load_global_data:
168 ; MEDIUM-STATIC: # %bb.0:
169 ; MEDIUM-STATIC-NEXT: movabsq $global_data, %rax
170 ; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax
171 ; MEDIUM-STATIC-NEXT: retq
173 ; LARGE-STATIC-LABEL: load_global_data:
174 ; LARGE-STATIC: # %bb.0:
175 ; LARGE-STATIC-NEXT: movabsq $global_data, %rax
176 ; LARGE-STATIC-NEXT: movl 8(%rax), %eax
177 ; LARGE-STATIC-NEXT: retq
179 ; SMALL-PIC-LABEL: load_global_data:
180 ; SMALL-PIC: # %bb.0:
181 ; SMALL-PIC-NEXT: movl global_data+8(%rip), %eax
182 ; SMALL-PIC-NEXT: retq
184 ; MEDIUM-PIC-LABEL: load_global_data:
185 ; MEDIUM-PIC: # %bb.0:
186 ; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
187 ; MEDIUM-PIC-NEXT: movabsq $global_data@GOTOFF, %rcx
188 ; MEDIUM-PIC-NEXT: movl 8(%rax,%rcx), %eax
189 ; MEDIUM-PIC-NEXT: retq
191 ; LARGE-PIC-LABEL: load_global_data:
192 ; LARGE-PIC: # %bb.0:
193 ; LARGE-PIC-NEXT: .L3$pb:
194 ; LARGE-PIC-NEXT: leaq .L3$pb(%rip), %rax
195 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx
196 ; LARGE-PIC-NEXT: addq %rax, %rcx
197 ; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax
198 ; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax
199 ; LARGE-PIC-NEXT: retq
200 %rv = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @global_data, i64 0, i64 2)
204 define dso_local i32 @load_extern_data() #0 {
205 ; SMALL-STATIC-LABEL: load_extern_data:
206 ; SMALL-STATIC: # %bb.0:
207 ; SMALL-STATIC-NEXT: movl extern_data+8(%rip), %eax
208 ; SMALL-STATIC-NEXT: retq
210 ; MEDIUM-STATIC-LABEL: load_extern_data:
211 ; MEDIUM-STATIC: # %bb.0:
212 ; MEDIUM-STATIC-NEXT: movabsq $extern_data, %rax
213 ; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax
214 ; MEDIUM-STATIC-NEXT: retq
216 ; LARGE-STATIC-LABEL: load_extern_data:
217 ; LARGE-STATIC: # %bb.0:
218 ; LARGE-STATIC-NEXT: movabsq $extern_data, %rax
219 ; LARGE-STATIC-NEXT: movl 8(%rax), %eax
220 ; LARGE-STATIC-NEXT: retq
222 ; SMALL-PIC-LABEL: load_extern_data:
223 ; SMALL-PIC: # %bb.0:
224 ; SMALL-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax
225 ; SMALL-PIC-NEXT: movl 8(%rax), %eax
226 ; SMALL-PIC-NEXT: retq
228 ; MEDIUM-PIC-LABEL: load_extern_data:
229 ; MEDIUM-PIC: # %bb.0:
230 ; MEDIUM-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax
231 ; MEDIUM-PIC-NEXT: movl 8(%rax), %eax
232 ; MEDIUM-PIC-NEXT: retq
234 ; LARGE-PIC-LABEL: load_extern_data:
235 ; LARGE-PIC: # %bb.0:
236 ; LARGE-PIC-NEXT: .L4$pb:
237 ; LARGE-PIC-NEXT: leaq .L4$pb(%rip), %rax
238 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx
239 ; LARGE-PIC-NEXT: addq %rax, %rcx
240 ; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax
241 ; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax
242 ; LARGE-PIC-NEXT: movl 8(%rax), %eax
243 ; LARGE-PIC-NEXT: retq
244 %rv = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @extern_data, i64 0, i64 2)
248 define dso_local void @global_fn() #0 {
249 ; CHECK-LABEL: global_fn:
255 define internal void @static_fn() #0 {
256 ; CHECK-LABEL: static_fn:
262 declare void @extern_fn()
264 define dso_local void ()* @lea_static_fn() #0 {
265 ; SMALL-STATIC-LABEL: lea_static_fn:
266 ; SMALL-STATIC: # %bb.0:
267 ; SMALL-STATIC-NEXT: movl $static_fn, %eax
268 ; SMALL-STATIC-NEXT: retq
270 ; MEDIUM-STATIC-LABEL: lea_static_fn:
271 ; MEDIUM-STATIC: # %bb.0:
272 ; MEDIUM-STATIC-NEXT: movabsq $static_fn, %rax
273 ; MEDIUM-STATIC-NEXT: retq
275 ; LARGE-STATIC-LABEL: lea_static_fn:
276 ; LARGE-STATIC: # %bb.0:
277 ; LARGE-STATIC-NEXT: movabsq $static_fn, %rax
278 ; LARGE-STATIC-NEXT: retq
280 ; SMALL-PIC-LABEL: lea_static_fn:
281 ; SMALL-PIC: # %bb.0:
282 ; SMALL-PIC-NEXT: leaq static_fn(%rip), %rax
283 ; SMALL-PIC-NEXT: retq
285 ; MEDIUM-PIC-LABEL: lea_static_fn:
286 ; MEDIUM-PIC: # %bb.0:
287 ; MEDIUM-PIC-NEXT: movabsq $static_fn, %rax
288 ; MEDIUM-PIC-NEXT: retq
290 ; LARGE-PIC-LABEL: lea_static_fn:
291 ; LARGE-PIC: # %bb.0:
292 ; LARGE-PIC-NEXT: .L7$pb:
293 ; LARGE-PIC-NEXT: leaq .L7$pb(%rip), %rax
294 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L7$pb, %rcx
295 ; LARGE-PIC-NEXT: addq %rax, %rcx
296 ; LARGE-PIC-NEXT: movabsq $static_fn@GOTOFF, %rax
297 ; LARGE-PIC-NEXT: addq %rcx, %rax
298 ; LARGE-PIC-NEXT: retq
299 ret void ()* @static_fn
302 define dso_local void ()* @lea_global_fn() #0 {
303 ; SMALL-STATIC-LABEL: lea_global_fn:
304 ; SMALL-STATIC: # %bb.0:
305 ; SMALL-STATIC-NEXT: movl $global_fn, %eax
306 ; SMALL-STATIC-NEXT: retq
308 ; MEDIUM-STATIC-LABEL: lea_global_fn:
309 ; MEDIUM-STATIC: # %bb.0:
310 ; MEDIUM-STATIC-NEXT: movabsq $global_fn, %rax
311 ; MEDIUM-STATIC-NEXT: retq
313 ; LARGE-STATIC-LABEL: lea_global_fn:
314 ; LARGE-STATIC: # %bb.0:
315 ; LARGE-STATIC-NEXT: movabsq $global_fn, %rax
316 ; LARGE-STATIC-NEXT: retq
318 ; SMALL-PIC-LABEL: lea_global_fn:
319 ; SMALL-PIC: # %bb.0:
320 ; SMALL-PIC-NEXT: leaq global_fn(%rip), %rax
321 ; SMALL-PIC-NEXT: retq
323 ; MEDIUM-PIC-LABEL: lea_global_fn:
324 ; MEDIUM-PIC: # %bb.0:
325 ; MEDIUM-PIC-NEXT: movabsq $global_fn, %rax
326 ; MEDIUM-PIC-NEXT: retq
328 ; LARGE-PIC-LABEL: lea_global_fn:
329 ; LARGE-PIC: # %bb.0:
330 ; LARGE-PIC-NEXT: .L8$pb:
331 ; LARGE-PIC-NEXT: leaq .L8$pb(%rip), %rax
332 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L8$pb, %rcx
333 ; LARGE-PIC-NEXT: addq %rax, %rcx
334 ; LARGE-PIC-NEXT: movabsq $global_fn@GOTOFF, %rax
335 ; LARGE-PIC-NEXT: addq %rcx, %rax
336 ; LARGE-PIC-NEXT: retq
337 ret void ()* @global_fn
340 define dso_local void ()* @lea_extern_fn() #0 {
341 ; SMALL-STATIC-LABEL: lea_extern_fn:
342 ; SMALL-STATIC: # %bb.0:
343 ; SMALL-STATIC-NEXT: movl $extern_fn, %eax
344 ; SMALL-STATIC-NEXT: retq
346 ; MEDIUM-STATIC-LABEL: lea_extern_fn:
347 ; MEDIUM-STATIC: # %bb.0:
348 ; MEDIUM-STATIC-NEXT: movabsq $extern_fn, %rax
349 ; MEDIUM-STATIC-NEXT: retq
351 ; LARGE-STATIC-LABEL: lea_extern_fn:
352 ; LARGE-STATIC: # %bb.0:
353 ; LARGE-STATIC-NEXT: movabsq $extern_fn, %rax
354 ; LARGE-STATIC-NEXT: retq
356 ; SMALL-PIC-LABEL: lea_extern_fn:
357 ; SMALL-PIC: # %bb.0:
358 ; SMALL-PIC-NEXT: movq extern_fn@GOTPCREL(%rip), %rax
359 ; SMALL-PIC-NEXT: retq
361 ; MEDIUM-PIC-LABEL: lea_extern_fn:
362 ; MEDIUM-PIC: # %bb.0:
363 ; MEDIUM-PIC-NEXT: movq extern_fn@GOTPCREL(%rip), %rax
364 ; MEDIUM-PIC-NEXT: retq
366 ; LARGE-PIC-LABEL: lea_extern_fn:
367 ; LARGE-PIC: # %bb.0:
368 ; LARGE-PIC-NEXT: .L9$pb:
369 ; LARGE-PIC-NEXT: leaq .L9$pb(%rip), %rax
370 ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L9$pb, %rcx
371 ; LARGE-PIC-NEXT: addq %rax, %rcx
372 ; LARGE-PIC-NEXT: movabsq $extern_fn@GOT, %rax
373 ; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax
374 ; LARGE-PIC-NEXT: retq
375 ret void ()* @extern_fn
378 ; FIXME: The result is same for small, medium and large model, because we
379 ; specify pie option in the test case. And the type of tls is initial exec tls.
380 ; For pic code. The large model code for pic tls should be emitted as below.
383 ; leaq .L3(%rip), %rbx
384 ; movabsq $_GLOBAL_OFFSET_TABLE_-.L3, %r11
386 ; leaq thread_data@TLSGD(%rip), %rdi
387 ; movabsq $__tls_get_addr@PLTOFF, %rax
392 ; The medium and small model code for pic tls should be emitted as below.
394 ; leaq thread_data@TLSGD(%rip), %rdi
398 ; callq __tls_get_addr@PLT
401 define dso_local i32 @load_thread_data() #0 {
402 ; SMALL-STATIC-LABEL: load_thread_data:
403 ; SMALL-STATIC: # %bb.0:
404 ; SMALL-STATIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
405 ; SMALL-STATIC-NEXT: movl %fs:(%rax), %eax
406 ; SMALL-STATIC-NEXT: retq
408 ; MEDIUM-STATIC-LABEL: load_thread_data:
409 ; MEDIUM-STATIC: # %bb.0:
410 ; MEDIUM-STATIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
411 ; MEDIUM-STATIC-NEXT: movl %fs:(%rax), %eax
412 ; MEDIUM-STATIC-NEXT: retq
414 ; LARGE-STATIC-LABEL: load_thread_data:
415 ; LARGE-STATIC: # %bb.0:
416 ; LARGE-STATIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
417 ; LARGE-STATIC-NEXT: movl %fs:(%rax), %eax
418 ; LARGE-STATIC-NEXT: retq
420 ; SMALL-PIC-LABEL: load_thread_data:
421 ; SMALL-PIC: # %bb.0:
422 ; SMALL-PIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
423 ; SMALL-PIC-NEXT: movl %fs:(%rax), %eax
424 ; SMALL-PIC-NEXT: retq
426 ; MEDIUM-PIC-LABEL: load_thread_data:
427 ; MEDIUM-PIC: # %bb.0:
428 ; MEDIUM-PIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
429 ; MEDIUM-PIC-NEXT: movl %fs:(%rax), %eax
430 ; MEDIUM-PIC-NEXT: retq
432 ; LARGE-PIC-LABEL: load_thread_data:
433 ; LARGE-PIC: # %bb.0:
434 ; LARGE-PIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax
435 ; LARGE-PIC-NEXT: movl %fs:(%rax), %eax
436 ; LARGE-PIC-NEXT: retq
438 %1 = load i32, i32* @thread_data, align 4
442 attributes #0 = { noinline nounwind uwtable }
444 !llvm.module.flags = !{!0, !1, !2}
447 !0 = !{i32 1, !"wchar_size", i32 4}
448 !1 = !{i32 7, !"PIC Level", i32 2}
449 !2 = !{i32 7, !"PIE Level", i32 2}
450 !3 = !{!"clang version 7.0.0 "}