1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -verify-machineinstrs -mtriple=aarch64 -code-model=tiny -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK-PIC
3 ; RUN: llc -verify-machineinstrs -mtriple=aarch64 -code-model=tiny -relocation-model=pic -fast-isel < %s | FileCheck %s --check-prefix=CHECK-PIC
4 ; RUN: llc -verify-machineinstrs -mtriple=aarch64 -code-model=tiny -relocation-model=pic -global-isel < %s | FileCheck %s --check-prefix=CHECK-PIC-GLOBISEL
6 ; Note fast-isel tests here will fall back to isel
8 @src = external local_unnamed_addr global [65536 x i8], align 1
9 @dst = external global [65536 x i8], align 1
10 @ptr = external local_unnamed_addr global i8*, align 8
12 define dso_preemptable void @foo1() {
14 ; CHECK: // %bb.0: // %entry
15 ; CHECK-NEXT: ldr x8, :got:src
16 ; CHECK-NEXT: ldrb w8, [x8]
17 ; CHECK-NEXT: ldr x9, :got:dst
18 ; CHECK-NEXT: strb w8, [x9]
21 ; CHECK-GLOBISEL-LABEL: foo1:
22 ; CHECK-GLOBISEL: // %bb.0: // %entry
23 ; CHECK-GLOBISEL-NEXT: ldr x8, :got:src
24 ; CHECK-GLOBISEL-NEXT: ldrb w8, [x8]
25 ; CHECK-GLOBISEL-NEXT: ldr x9, :got:dst
26 ; CHECK-GLOBISEL-NEXT: strb w8, [x9]
27 ; CHECK-GLOBISEL-NEXT: ret
29 ; CHECK-PIC-LABEL: foo1:
30 ; CHECK-PIC: // %bb.0: // %entry
31 ; CHECK-PIC-NEXT: ldr x8, :got:src
32 ; CHECK-PIC-NEXT: ldrb w8, [x8]
33 ; CHECK-PIC-NEXT: ldr x9, :got:dst
34 ; CHECK-PIC-NEXT: strb w8, [x9]
37 ; CHECK-PIC-GLOBISEL-LABEL: foo1:
38 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
39 ; CHECK-PIC-GLOBISEL-NEXT: ldr x8, :got:src
40 ; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8]
41 ; CHECK-PIC-GLOBISEL-NEXT: ldr x9, :got:dst
42 ; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9]
43 ; CHECK-PIC-GLOBISEL-NEXT: ret
45 %0 = load i8, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @src, i64 0, i64 0), align 1
46 store i8 %0, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @dst, i64 0, i64 0), align 1
50 define dso_preemptable void @foo2() {
52 ; CHECK: // %bb.0: // %entry
53 ; CHECK-NEXT: ldr x8, :got:ptr
54 ; CHECK-NEXT: ldr x9, :got:dst
55 ; CHECK-NEXT: str x9, [x8]
58 ; CHECK-GLOBISEL-LABEL: foo2:
59 ; CHECK-GLOBISEL: // %bb.0: // %entry
60 ; CHECK-GLOBISEL-NEXT: ldr x8, :got:ptr
61 ; CHECK-GLOBISEL-NEXT: ldr x9, :got:dst
62 ; CHECK-GLOBISEL-NEXT: str x9, [x8]
63 ; CHECK-GLOBISEL-NEXT: ret
65 ; CHECK-PIC-LABEL: foo2:
66 ; CHECK-PIC: // %bb.0: // %entry
67 ; CHECK-PIC-NEXT: ldr x8, :got:ptr
68 ; CHECK-PIC-NEXT: ldr x9, :got:dst
69 ; CHECK-PIC-NEXT: str x9, [x8]
72 ; CHECK-PIC-GLOBISEL-LABEL: foo2:
73 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
74 ; CHECK-PIC-GLOBISEL-NEXT: ldr x8, :got:ptr
75 ; CHECK-PIC-GLOBISEL-NEXT: ldr x9, :got:dst
76 ; CHECK-PIC-GLOBISEL-NEXT: str x9, [x8]
77 ; CHECK-PIC-GLOBISEL-NEXT: ret
79 store i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @dst, i64 0, i64 0), i8** @ptr, align 8
83 define dso_preemptable void @foo3() {
84 ; FIXME: Needn't adr ptr
87 ; CHECK: // %bb.0: // %entry
88 ; CHECK-NEXT: ldr x8, :got:src
89 ; CHECK-NEXT: ldr x9, :got:ptr
90 ; CHECK-NEXT: ldrb w8, [x8]
91 ; CHECK-NEXT: ldr x9, [x9]
92 ; CHECK-NEXT: strb w8, [x9]
95 ; CHECK-GLOBISEL-LABEL: foo3:
96 ; CHECK-GLOBISEL: // %bb.0: // %entry
97 ; CHECK-GLOBISEL-NEXT: ldr x8, :got:src
98 ; CHECK-GLOBISEL-NEXT: ldr x9, :got:ptr
99 ; CHECK-GLOBISEL-NEXT: ldrb w8, [x8]
100 ; CHECK-GLOBISEL-NEXT: ldr x9, [x9]
101 ; CHECK-GLOBISEL-NEXT: strb w8, [x9]
102 ; CHECK-GLOBISEL-NEXT: ret
104 ; CHECK-PIC-LABEL: foo3:
105 ; CHECK-PIC: // %bb.0: // %entry
106 ; CHECK-PIC-NEXT: ldr x8, :got:src
107 ; CHECK-PIC-NEXT: ldr x9, :got:ptr
108 ; CHECK-PIC-NEXT: ldrb w8, [x8]
109 ; CHECK-PIC-NEXT: ldr x9, [x9]
110 ; CHECK-PIC-NEXT: strb w8, [x9]
111 ; CHECK-PIC-NEXT: ret
113 ; CHECK-PIC-GLOBISEL-LABEL: foo3:
114 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
115 ; CHECK-PIC-GLOBISEL-NEXT: ldr x8, :got:src
116 ; CHECK-PIC-GLOBISEL-NEXT: ldr x9, :got:ptr
117 ; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8]
118 ; CHECK-PIC-GLOBISEL-NEXT: ldr x9, [x9]
119 ; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9]
120 ; CHECK-PIC-GLOBISEL-NEXT: ret
122 %0 = load i8, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @src, i64 0, i64 0), align 1
123 %1 = load i8*, i8** @ptr, align 8
124 store i8 %0, i8* %1, align 1
128 @lsrc = internal global i8 0, align 4
129 @ldst = internal global i8 0, align 4
130 @lptr = internal global i8* null, align 8
132 define dso_preemptable void @bar1() {
134 ; CHECK: // %bb.0: // %entry
135 ; CHECK-NEXT: adr x8, lsrc
136 ; CHECK-NEXT: ldrb w8, [x8]
137 ; CHECK-NEXT: adr x9, ldst
138 ; CHECK-NEXT: strb w8, [x9]
141 ; CHECK-GLOBISEL-LABEL: bar1:
142 ; CHECK-GLOBISEL: // %bb.0: // %entry
143 ; CHECK-GLOBISEL-NEXT: adr x8, lsrc
144 ; CHECK-GLOBISEL-NEXT: ldrb w8, [x8]
145 ; CHECK-GLOBISEL-NEXT: adr x9, ldst
146 ; CHECK-GLOBISEL-NEXT: strb w8, [x9]
147 ; CHECK-GLOBISEL-NEXT: ret
149 ; CHECK-PIC-LABEL: bar1:
150 ; CHECK-PIC: // %bb.0: // %entry
151 ; CHECK-PIC-NEXT: adr x8, lsrc
152 ; CHECK-PIC-NEXT: adr x9, ldst
153 ; CHECK-PIC-NEXT: ldrb w8, [x8]
154 ; CHECK-PIC-NEXT: strb w8, [x9]
155 ; CHECK-PIC-NEXT: ret
157 ; CHECK-PIC-GLOBISEL-LABEL: bar1:
158 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
159 ; CHECK-PIC-GLOBISEL-NEXT: adr x8, lsrc
160 ; CHECK-PIC-GLOBISEL-NEXT: adr x9, ldst
161 ; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8]
162 ; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9]
163 ; CHECK-PIC-GLOBISEL-NEXT: ret
165 %0 = load i8, i8* @lsrc, align 4
166 store i8 %0, i8* @ldst, align 4
170 define dso_preemptable void @bar2() {
172 ; CHECK: // %bb.0: // %entry
173 ; CHECK-NEXT: adr x8, lptr
174 ; CHECK-NEXT: adr x9, ldst
175 ; CHECK-NEXT: str x9, [x8]
178 ; CHECK-GLOBISEL-LABEL: bar2:
179 ; CHECK-GLOBISEL: // %bb.0: // %entry
180 ; CHECK-GLOBISEL-NEXT: adr x8, lptr
181 ; CHECK-GLOBISEL-NEXT: adr x9, ldst
182 ; CHECK-GLOBISEL-NEXT: str x9, [x8]
183 ; CHECK-GLOBISEL-NEXT: ret
185 ; CHECK-PIC-LABEL: bar2:
186 ; CHECK-PIC: // %bb.0: // %entry
187 ; CHECK-PIC-NEXT: adr x8, lptr
188 ; CHECK-PIC-NEXT: adr x9, ldst
189 ; CHECK-PIC-NEXT: str x9, [x8]
190 ; CHECK-PIC-NEXT: ret
192 ; CHECK-PIC-GLOBISEL-LABEL: bar2:
193 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
194 ; CHECK-PIC-GLOBISEL-NEXT: adr x8, lptr
195 ; CHECK-PIC-GLOBISEL-NEXT: adr x9, ldst
196 ; CHECK-PIC-GLOBISEL-NEXT: str x9, [x8]
197 ; CHECK-PIC-GLOBISEL-NEXT: ret
199 store i8* @ldst, i8** @lptr, align 8
203 define dso_preemptable void @bar3() {
204 ; FIXME: Needn't adr lptr
207 ; CHECK: // %bb.0: // %entry
208 ; CHECK-NEXT: adr x8, lsrc
209 ; CHECK-NEXT: ldrb w8, [x8]
210 ; CHECK-NEXT: ldr x9, lptr
211 ; CHECK-NEXT: strb w8, [x9]
214 ; CHECK-GLOBISEL-LABEL: bar3:
215 ; CHECK-GLOBISEL: // %bb.0: // %entry
216 ; CHECK-GLOBISEL-NEXT: adr x8, lsrc
217 ; CHECK-GLOBISEL-NEXT: adr x9, lptr
218 ; CHECK-GLOBISEL-NEXT: ldrb w8, [x8]
219 ; CHECK-GLOBISEL-NEXT: ldr x9, [x9]
220 ; CHECK-GLOBISEL-NEXT: strb w8, [x9]
221 ; CHECK-GLOBISEL-NEXT: ret
223 ; CHECK-PIC-LABEL: bar3:
224 ; CHECK-PIC: // %bb.0: // %entry
225 ; CHECK-PIC-NEXT: adr x8, lsrc
226 ; CHECK-PIC-NEXT: ldr x9, lptr
227 ; CHECK-PIC-NEXT: ldrb w8, [x8]
228 ; CHECK-PIC-NEXT: strb w8, [x9]
229 ; CHECK-PIC-NEXT: ret
231 ; CHECK-PIC-GLOBISEL-LABEL: bar3:
232 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
233 ; CHECK-PIC-GLOBISEL-NEXT: adr x8, lsrc
234 ; CHECK-PIC-GLOBISEL-NEXT: adr x9, lptr
235 ; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8]
236 ; CHECK-PIC-GLOBISEL-NEXT: ldr x9, [x9]
237 ; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9]
238 ; CHECK-PIC-GLOBISEL-NEXT: ret
240 %0 = load i8, i8* @lsrc, align 4
241 %1 = load i8*, i8** @lptr, align 8
242 store i8 %0, i8* %1, align 1
247 @lbsrc = internal global [65536 x i8] zeroinitializer, align 4
248 @lbdst = internal global [65536 x i8] zeroinitializer, align 4
250 define dso_preemptable void @baz1() {
252 ; CHECK: // %bb.0: // %entry
253 ; CHECK-NEXT: adr x8, lbsrc
254 ; CHECK-NEXT: ldrb w8, [x8]
255 ; CHECK-NEXT: adr x9, lbdst
256 ; CHECK-NEXT: strb w8, [x9]
259 ; CHECK-GLOBISEL-LABEL: baz1:
260 ; CHECK-GLOBISEL: // %bb.0: // %entry
261 ; CHECK-GLOBISEL-NEXT: adr x8, lbsrc
262 ; CHECK-GLOBISEL-NEXT: ldrb w8, [x8]
263 ; CHECK-GLOBISEL-NEXT: adr x9, lbdst
264 ; CHECK-GLOBISEL-NEXT: strb w8, [x9]
265 ; CHECK-GLOBISEL-NEXT: ret
267 ; CHECK-PIC-LABEL: baz1:
268 ; CHECK-PIC: // %bb.0: // %entry
269 ; CHECK-PIC-NEXT: adr x8, lbsrc
270 ; CHECK-PIC-NEXT: adr x9, lbdst
271 ; CHECK-PIC-NEXT: ldrb w8, [x8]
272 ; CHECK-PIC-NEXT: strb w8, [x9]
273 ; CHECK-PIC-NEXT: ret
275 ; CHECK-PIC-GLOBISEL-LABEL: baz1:
276 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
277 ; CHECK-PIC-GLOBISEL-NEXT: adr x8, lbsrc
278 ; CHECK-PIC-GLOBISEL-NEXT: adr x9, lbdst
279 ; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8]
280 ; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9]
281 ; CHECK-PIC-GLOBISEL-NEXT: ret
283 %0 = load i8, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @lbsrc, i64 0, i64 0), align 4
284 store i8 %0, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @lbdst, i64 0, i64 0), align 4
288 define dso_preemptable void @baz2() {
290 ; CHECK: // %bb.0: // %entry
291 ; CHECK-NEXT: adr x8, lptr
292 ; CHECK-NEXT: adr x9, lbdst
293 ; CHECK-NEXT: str x9, [x8]
296 ; CHECK-GLOBISEL-LABEL: baz2:
297 ; CHECK-GLOBISEL: // %bb.0: // %entry
298 ; CHECK-GLOBISEL-NEXT: adr x8, lptr
299 ; CHECK-GLOBISEL-NEXT: adr x9, lbdst
300 ; CHECK-GLOBISEL-NEXT: str x9, [x8]
301 ; CHECK-GLOBISEL-NEXT: ret
303 ; CHECK-PIC-LABEL: baz2:
304 ; CHECK-PIC: // %bb.0: // %entry
305 ; CHECK-PIC-NEXT: adr x8, lptr
306 ; CHECK-PIC-NEXT: adr x9, lbdst
307 ; CHECK-PIC-NEXT: str x9, [x8]
308 ; CHECK-PIC-NEXT: ret
310 ; CHECK-PIC-GLOBISEL-LABEL: baz2:
311 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
312 ; CHECK-PIC-GLOBISEL-NEXT: adr x8, lptr
313 ; CHECK-PIC-GLOBISEL-NEXT: adr x9, lbdst
314 ; CHECK-PIC-GLOBISEL-NEXT: str x9, [x8]
315 ; CHECK-PIC-GLOBISEL-NEXT: ret
317 store i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @lbdst, i64 0, i64 0), i8** @lptr, align 8
321 define dso_preemptable void @baz3() {
322 ; FIXME: Needn't adr lptr
325 ; CHECK: // %bb.0: // %entry
326 ; CHECK-NEXT: adr x8, lbsrc
327 ; CHECK-NEXT: ldrb w8, [x8]
328 ; CHECK-NEXT: ldr x9, lptr
329 ; CHECK-NEXT: strb w8, [x9]
332 ; CHECK-GLOBISEL-LABEL: baz3:
333 ; CHECK-GLOBISEL: // %bb.0: // %entry
334 ; CHECK-GLOBISEL-NEXT: adr x8, lbsrc
335 ; CHECK-GLOBISEL-NEXT: adr x9, lptr
336 ; CHECK-GLOBISEL-NEXT: ldrb w8, [x8]
337 ; CHECK-GLOBISEL-NEXT: ldr x9, [x9]
338 ; CHECK-GLOBISEL-NEXT: strb w8, [x9]
339 ; CHECK-GLOBISEL-NEXT: ret
341 ; CHECK-PIC-LABEL: baz3:
342 ; CHECK-PIC: // %bb.0: // %entry
343 ; CHECK-PIC-NEXT: adr x8, lbsrc
344 ; CHECK-PIC-NEXT: ldr x9, lptr
345 ; CHECK-PIC-NEXT: ldrb w8, [x8]
346 ; CHECK-PIC-NEXT: strb w8, [x9]
347 ; CHECK-PIC-NEXT: ret
349 ; CHECK-PIC-GLOBISEL-LABEL: baz3:
350 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
351 ; CHECK-PIC-GLOBISEL-NEXT: adr x8, lbsrc
352 ; CHECK-PIC-GLOBISEL-NEXT: adr x9, lptr
353 ; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8]
354 ; CHECK-PIC-GLOBISEL-NEXT: ldr x9, [x9]
355 ; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9]
356 ; CHECK-PIC-GLOBISEL-NEXT: ret
358 %0 = load i8, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @lbsrc, i64 0, i64 0), align 4
359 %1 = load i8*, i8** @lptr, align 8
360 store i8 %0, i8* %1, align 1
365 declare void @func(...)
367 define dso_preemptable i8* @externfuncaddr() {
368 ; CHECK-LABEL: externfuncaddr:
369 ; CHECK: // %bb.0: // %entry
370 ; CHECK-NEXT: ldr x0, :got:func
373 ; CHECK-GLOBISEL-LABEL: externfuncaddr:
374 ; CHECK-GLOBISEL: // %bb.0: // %entry
375 ; CHECK-GLOBISEL-NEXT: ldr x0, :got:func
376 ; CHECK-GLOBISEL-NEXT: ret
378 ; CHECK-PIC-LABEL: externfuncaddr:
379 ; CHECK-PIC: // %bb.0: // %entry
380 ; CHECK-PIC-NEXT: ldr x0, :got:func
381 ; CHECK-PIC-NEXT: ret
383 ; CHECK-PIC-GLOBISEL-LABEL: externfuncaddr:
384 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
385 ; CHECK-PIC-GLOBISEL-NEXT: ldr x0, :got:func
386 ; CHECK-PIC-GLOBISEL-NEXT: ret
388 ret i8* bitcast (void (...)* @func to i8*)
391 define dso_preemptable i8* @localfuncaddr() {
392 ; CHECK-LABEL: localfuncaddr:
393 ; CHECK: // %bb.0: // %entry
394 ; CHECK-NEXT: adr x0, externfuncaddr
397 ; CHECK-GLOBISEL-LABEL: localfuncaddr:
398 ; CHECK-GLOBISEL: // %bb.0: // %entry
399 ; CHECK-GLOBISEL-NEXT: adr x0, externfuncaddr
400 ; CHECK-GLOBISEL-NEXT: ret
402 ; CHECK-PIC-LABEL: localfuncaddr:
403 ; CHECK-PIC: // %bb.0: // %entry
404 ; CHECK-PIC-NEXT: ldr x0, :got:externfuncaddr
405 ; CHECK-PIC-NEXT: ret
407 ; CHECK-PIC-GLOBISEL-LABEL: localfuncaddr:
408 ; CHECK-PIC-GLOBISEL: // %bb.0: // %entry
409 ; CHECK-PIC-GLOBISEL-NEXT: ldr x0, :got:externfuncaddr
410 ; CHECK-PIC-GLOBISEL-NEXT: ret
412 ret i8* bitcast (i8* ()* @externfuncaddr to i8*)