1 ; RUN: llc < %s -mtriple=armv7-apple-ios -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-IOS --check-prefix=CHECK
2 ; RUN: llc < %s -mtriple=thumbv7m-none-macho -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-DARWIN --check-prefix=CHECK
3 ; RUN: llc < %s -mtriple=arm-none-eabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
4 ; RUN: llc < %s -mtriple=arm-none-eabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
5 ; RUN: llc < %s -mtriple=arm-none-androideabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
6 ; RUN: llc < %s -mtriple=arm-none-gnueabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
7 ; RUN: llc < %s -mtriple=arm-none-gnueabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
8 ; RUN: llc < %s -mtriple=arm-none-musleabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
9 ; RUN: llc < %s -mtriple=arm-none-musleabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
11 define void @f1(ptr %dest, ptr %src) "frame-pointer"="all" {
15 ; CHECK-IOS: bl _memmove
16 ; CHECK-DARWIN: bl _memmove
17 ; CHECK-EABI: bl __aeabi_memmove
18 ; CHECK-GNUEABI: bl memmove
19 call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %src, i32 500, i1 false)
21 ; CHECK-IOS: bl _memcpy
22 ; CHECK-DARWIN: bl _memcpy
23 ; CHECK-EABI: bl __aeabi_memcpy
24 ; CHECK-GNUEABI: bl memcpy
25 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 500, i1 false)
27 ; EABI memset swaps arguments
28 ; CHECK-IOS: mov r1, #1
29 ; CHECK-IOS: bl _memset
30 ; CHECK-DARWIN: movs r1, #1
31 ; CHECK-DARWIN: bl _memset
32 ; CHECK-EABI: mov r2, #1
33 ; CHECK-EABI: bl __aeabi_memset
34 ; CHECK-GNUEABI: mov r1, #1
35 ; CHECK-GNUEABI: bl memset
36 call void @llvm.memset.p0.i32(ptr %dest, i8 1, i32 500, i1 false)
38 ; EABI uses memclr if value set to 0
39 ; CHECK-IOS: mov r1, #0
40 ; CHECK-IOS: bl _memset
41 ; CHECK-DARWIN: movs r1, #0
42 ; CHECK-DARWIN: bl _memset
43 ; CHECK-EABI: bl __aeabi_memclr
44 ; CHECK-GNUEABI: bl memset
45 call void @llvm.memset.p0.i32(ptr %dest, i8 0, i32 500, i1 false)
47 ; EABI uses aligned function variants if possible
49 ; CHECK-IOS: bl _memmove
50 ; CHECK-DARWIN: bl _memmove
51 ; CHECK-EABI: bl __aeabi_memmove4
52 ; CHECK-GNUEABI: bl memmove
53 call void @llvm.memmove.p0.p0.i32(ptr align 4 %dest, ptr align 4 %src, i32 500, i1 false)
55 ; CHECK-IOS: bl _memcpy
56 ; CHECK-DARWIN: bl _memcpy
57 ; CHECK-EABI: bl __aeabi_memcpy4
58 ; CHECK-GNUEABI: bl memcpy
59 call void @llvm.memcpy.p0.p0.i32(ptr align 4 %dest, ptr align 4 %src, i32 500, i1 false)
61 ; CHECK-IOS: bl _memset
62 ; CHECK-DARWIN: bl _memset
63 ; CHECK-EABI: bl __aeabi_memset4
64 ; CHECK-GNUEABI: bl memset
65 call void @llvm.memset.p0.i32(ptr align 4 %dest, i8 1, i32 500, i1 false)
67 ; CHECK-IOS: bl _memset
68 ; CHECK-DARWIN: bl _memset
69 ; CHECK-EABI: bl __aeabi_memclr4
70 ; CHECK-GNUEABI: bl memset
71 call void @llvm.memset.p0.i32(ptr align 4 %dest, i8 0, i32 500, i1 false)
73 ; CHECK-IOS: bl _memmove
74 ; CHECK-DARWIN: bl _memmove
75 ; CHECK-EABI: bl __aeabi_memmove8
76 ; CHECK-GNUEABI: bl memmove
77 call void @llvm.memmove.p0.p0.i32(ptr align 8 %dest, ptr align 8 %src, i32 500, i1 false)
79 ; CHECK-IOS: bl _memcpy
80 ; CHECK-DARWIN: bl _memcpy
81 ; CHECK-EABI: bl __aeabi_memcpy8
82 ; CHECK-GNUEABI: bl memcpy
83 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %dest, ptr align 8 %src, i32 500, i1 false)
85 ; CHECK-IOS: bl _memset
86 ; CHECK-DARWIN: bl _memset
87 ; CHECK-EABI: bl __aeabi_memset8
88 ; CHECK-GNUEABI: bl memset
89 call void @llvm.memset.p0.i32(ptr align 8 %dest, i8 1, i32 500, i1 false)
91 ; CHECK-IOS: bl _memset
92 ; CHECK-DARWIN: bl _memset
93 ; CHECK-EABI: bl __aeabi_memclr8
94 ; CHECK-GNUEABI: bl memset
95 call void @llvm.memset.p0.i32(ptr align 8 %dest, i8 0, i32 500, i1 false)
100 ; Check that alloca arguments to memory intrinsics are automatically aligned if at least 8 bytes in size
101 define void @f2(ptr %dest, i32 %n) "frame-pointer"="all" {
105 ; IOS (ARMv7) should 8-byte align, others should 4-byte align
106 ; CHECK-IOS: add r1, sp, #32
107 ; CHECK-IOS: bl _memmove
108 ; CHECK-DARWIN: add r1, sp, #28
109 ; CHECK-DARWIN: bl _memmove
110 ; CHECK-EABI: {{add r1, sp, #28|sub r1, r(7|11), #20}}
111 ; CHECK-EABI: bl __aeabi_memmove
112 ; CHECK-GNUEABI: {{add r1, sp, #28|sub r1, r(7|11), #20}}
113 ; CHECK-GNUEABI: bl memmove
114 %arr0 = alloca [9 x i8], align 1
115 call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %arr0, i32 %n, i1 false)
117 ; CHECK: add r1, sp, #16
118 ; CHECK-IOS: bl _memcpy
119 ; CHECK-DARWIN: bl _memcpy
120 ; CHECK-EABI: bl __aeabi_memcpy
121 ; CHECK-GNUEABI: bl memcpy
122 %arr1 = alloca [9 x i8], align 1
123 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %arr1, i32 %n, i1 false)
125 ; CHECK-IOS: mov r0, sp
126 ; CHECK-IOS: mov r1, #1
127 ; CHECK-IOS: bl _memset
128 ; CHECK-DARWIN: add r0, sp, #4
129 ; CHECK-DARWIN: movs r1, #1
130 ; CHECK-DARWIN: bl _memset
131 ; CHECK-EABI: add r0, sp, #4
132 ; CHECK-EABI: mov r2, #1
133 ; CHECK-EABI: bl __aeabi_memset
134 ; CHECK-GNUEABI: add r0, sp, #4
135 ; CHECK-GNUEABI: mov r1, #1
136 ; CHECK-GNUEABI: bl memset
137 %arr2 = alloca [9 x i8], align 1
138 call void @llvm.memset.p0.i32(ptr %arr2, i8 1, i32 %n, i1 false)
143 ; Check that alloca arguments are not aligned if less than 8 bytes in size
144 define void @f3(ptr %dest, i32 %n) "frame-pointer"="all" {
148 ; CHECK: {{add(.w)? r1, sp, #17|sub(.w)? r1, r(7|11), #15}}
149 ; CHECK-IOS: bl _memmove
150 ; CHECK-DARWIN: bl _memmove
151 ; CHECK-EABI: bl __aeabi_memmove
152 ; CHECK-GNUEABI: bl memmove
153 %arr0 = alloca [7 x i8], align 1
154 call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %arr0, i32 %n, i1 false)
156 ; CHECK: {{add(.w)? r1, sp, #10|sub(.w)? r1, r(7|11), #22}}
157 ; CHECK-IOS: bl _memcpy
158 ; CHECK-DARWIN: bl _memcpy
159 ; CHECK-EABI: bl __aeabi_memcpy
160 ; CHECK-GNUEABI: bl memcpy
161 %arr1 = alloca [7 x i8], align 1
162 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %arr1, i32 %n, i1 false)
164 ; CHECK: {{add(.w)? r0, sp, #3|sub(.w)? r0, r(7|11), #29}}
165 ; CHECK-IOS: mov r1, #1
166 ; CHECK-IOS: bl _memset
167 ; CHECK-DARWIN: movs r1, #1
168 ; CHECK-DARWIN: bl _memset
169 ; CHECK-EABI: mov r2, #1
170 ; CHECK-EABI: bl __aeabi_memset
171 ; CHECK-GNUEABI: mov r1, #1
172 ; CHECK-GNUEABI: bl memset
173 %arr2 = alloca [7 x i8], align 1
174 call void @llvm.memset.p0.i32(ptr %arr2, i8 1, i32 %n, i1 false)
179 ; Check that alloca arguments are not aligned if size+offset is less than 8 bytes
180 define void @f4(ptr %dest, i32 %n) "frame-pointer"="all" {
184 ; CHECK: {{add(.w)? r., sp, #23|sub(.w)? r., r(7|11), #17}}
185 ; CHECK-IOS: bl _memmove
186 ; CHECK-DARWIN: bl _memmove
187 ; CHECK-EABI: bl __aeabi_memmove
188 ; CHECK-GNUEABI: bl memmove
189 %arr0 = alloca [9 x i8], align 1
190 %0 = getelementptr inbounds [9 x i8], ptr %arr0, i32 0, i32 4
191 call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %0, i32 %n, i1 false)
193 ; CHECK: {{add(.w)? r., sp, #(10|14)|sub(.w) r., r(7|11), #26}}
194 ; CHECK-IOS: bl _memcpy
195 ; CHECK-DARWIN: bl _memcpy
196 ; CHECK-EABI: bl __aeabi_memcpy
197 ; CHECK-GNUEABI: bl memcpy
198 %arr1 = alloca [9 x i8], align 1
199 %1 = getelementptr inbounds [9 x i8], ptr %arr1, i32 0, i32 4
200 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %1, i32 %n, i1 false)
202 ; CHECK: {{add(.w)? r., sp, #(1|5)|sub(.w) r., r(7|11), #35}}
203 ; CHECK-IOS: mov r1, #1
204 ; CHECK-IOS: bl _memset
205 ; CHECK-DARWIN: movs r1, #1
206 ; CHECK-DARWIN: bl _memset
207 ; CHECK-EABI: mov r2, #1
208 ; CHECK-EABI: bl __aeabi_memset
209 ; CHECK-GNUEABI: mov r1, #1
210 ; CHECK-GNUEABI: bl memset
211 %arr2 = alloca [9 x i8], align 1
212 %2 = getelementptr inbounds [9 x i8], ptr %arr2, i32 0, i32 4
213 call void @llvm.memset.p0.i32(ptr %2, i8 1, i32 %n, i1 false)
218 ; Check that alloca arguments are not aligned if the offset is not a multiple of 4
219 define void @f5(ptr %dest, i32 %n) "frame-pointer"="all" {
223 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r(7|11), #21}}
224 ; CHECK-IOS: bl _memmove
225 ; CHECK-DARWIN: bl _memmove
226 ; CHECK-EABI: bl __aeabi_memmove
227 ; CHECK-GNUEABI: bl memmove
228 %arr0 = alloca [13 x i8], align 1
229 %0 = getelementptr inbounds [13 x i8], ptr %arr0, i32 0, i32 1
230 call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %0, i32 %n, i1 false)
232 ; CHECK: {{add(.w)? r., sp, #(10|14)|sub(.w)? r., r(7|11), #34}}
233 ; CHECK-IOS: bl _memcpy
234 ; CHECK-DARWIN: bl _memcpy
235 ; CHECK-EABI: bl __aeabi_memcpy
236 ; CHECK-GNUEABI: bl memcpy
237 %arr1 = alloca [13 x i8], align 1
238 %1 = getelementptr inbounds [13 x i8], ptr %arr1, i32 0, i32 1
239 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %1, i32 %n, i1 false)
241 ; CHECK: {{add(.w)? r., sp, #(1|5)|sub(.w)? r., r(7|11), #47}}
242 ; CHECK-IOS: mov r1, #1
243 ; CHECK-IOS: bl _memset
244 ; CHECK-DARWIN: movs r1, #1
245 ; CHECK-DARWIN: bl _memset
246 ; CHECK-EABI: mov r2, #1
247 ; CHECK-EABI: bl __aeabi_memset
248 ; CHECK-GNUEABI: mov r1, #1
249 ; CHECK-GNUEABI: bl memset
250 %arr2 = alloca [13 x i8], align 1
251 %2 = getelementptr inbounds [13 x i8], ptr %arr2, i32 0, i32 1
252 call void @llvm.memset.p0.i32(ptr %2, i8 1, i32 %n, i1 false)
257 ; Check that alloca arguments are not aligned if the offset is unknown
258 define void @f6(ptr %dest, i32 %n, i32 %i) "frame-pointer"="all" {
262 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r(7|11), #(25|29)}}
263 ; CHECK-IOS: bl _memmove
264 ; CHECK-DARWIN: bl _memmove
265 ; CHECK-EABI: bl __aeabi_memmove
266 ; CHECK-GNUEABI: bl memmove
267 %arr0 = alloca [13 x i8], align 1
268 %0 = getelementptr inbounds [13 x i8], ptr %arr0, i32 0, i32 %i
269 call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %0, i32 %n, i1 false)
271 ; CHECK: {{add(.w)? r., sp, #(10|14)|sub(.w)? r., r(7|11), #42}}
272 ; CHECK-IOS: bl _memcpy
273 ; CHECK-DARWIN: bl _memcpy
274 ; CHECK-EABI: bl __aeabi_memcpy
275 ; CHECK-GNUEABI: bl memcpy
276 %arr1 = alloca [13 x i8], align 1
277 %1 = getelementptr inbounds [13 x i8], ptr %arr1, i32 0, i32 %i
278 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %1, i32 %n, i1 false)
280 ; CHECK: {{add(.w)? r., sp, #(1|5)|sub(.w)? r., r(7|11), #55}}
281 ; CHECK-IOS: mov r1, #1
282 ; CHECK-IOS: bl _memset
283 ; CHECK-DARWIN: movs r1, #1
284 ; CHECK-DARWIN: bl _memset
285 ; CHECK-EABI: mov r2, #1
286 ; CHECK-EABI: bl __aeabi_memset
287 ; CHECK-GNUEABI: mov r1, #1
288 ; CHECK-GNUEABI: bl memset
289 %arr2 = alloca [13 x i8], align 1
290 %2 = getelementptr inbounds [13 x i8], ptr %arr2, i32 0, i32 %i
291 call void @llvm.memset.p0.i32(ptr %2, i8 1, i32 %n, i1 false)
296 ; Check that alloca arguments are not aligned if the GEP is not inbounds
297 define void @f7(ptr %dest, i32 %n) "frame-pointer"="all" {
301 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r(7|11), #21}}
302 ; CHECK-IOS: bl _memmove
303 ; CHECK-DARWIN: bl _memmove
304 ; CHECK-EABI: bl __aeabi_memmove
305 ; CHECK-GNUEABI: bl memmove
306 %arr0 = alloca [13 x i8], align 1
307 %0 = getelementptr [13 x i8], ptr %arr0, i32 0, i32 4
308 call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %0, i32 %n, i1 false)
310 ; CHECK: {{add(.w)? r., sp, #(10|14)|sub(.w)? r., r(7|11), #34}}
311 ; CHECK-IOS: bl _memcpy
312 ; CHECK-DARWIN: bl _memcpy
313 ; CHECK-EABI: bl __aeabi_memcpy
314 ; CHECK-GNUEABI: bl memcpy
315 %arr1 = alloca [13 x i8], align 1
316 %1 = getelementptr [13 x i8], ptr %arr1, i32 0, i32 4
317 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %1, i32 %n, i1 false)
319 ; CHECK: {{add(.w)? r., sp, #(1|5)|sub(.w)? r., r(7|11), #47}}
320 ; CHECK-IOS: mov r1, #1
321 ; CHECK-IOS: bl _memset
322 ; CHECK-DARWIN: movs r1, #1
323 ; CHECK-DARWIN: bl _memset
324 ; CHECK-EABI: mov r2, #1
325 ; CHECK-EABI: bl __aeabi_memset
326 ; CHECK-GNUEABI: mov r1, #1
327 ; CHECK-GNUEABI: bl memset
328 %arr2 = alloca [13 x i8], align 1
329 %2 = getelementptr [13 x i8], ptr %arr2, i32 0, i32 4
330 call void @llvm.memset.p0.i32(ptr %2, i8 1, i32 %n, i1 false)
335 ; Check that alloca arguments are not aligned when the offset is past the end of the allocation
336 define void @f8(ptr %dest, i32 %n) "frame-pointer"="all" {
340 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r(7|11), #21}}
341 ; CHECK-IOS: bl _memmove
342 ; CHECK-DARWIN: bl _memmove
343 ; CHECK-EABI: bl __aeabi_memmove
344 ; CHECK-GNUEABI: bl memmove
345 %arr0 = alloca [13 x i8], align 1
346 %0 = getelementptr inbounds [13 x i8], ptr %arr0, i32 0, i32 16
347 call void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %0, i32 %n, i1 false)
349 ; CHECK: {{add(.w)? r., sp, #(10|14)|sub(.w)? r., r(7|11), #34}}
350 ; CHECK-IOS: bl _memcpy
351 ; CHECK-DARWIN: bl _memcpy
352 ; CHECK-EABI: bl __aeabi_memcpy
353 ; CHECK-GNUEABI: bl memcpy
354 %arr1 = alloca [13 x i8], align 1
355 %1 = getelementptr inbounds [13 x i8], ptr %arr1, i32 0, i32 16
356 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %1, i32 %n, i1 false)
358 ; CHECK: {{add(.w)? r., sp, #(1|5)|sub(.w)? r., r(7|11), #47}}
359 ; CHECK-IOS: mov r1, #1
360 ; CHECK-IOS: bl _memset
361 ; CHECK-DARWIN: movs r1, #1
362 ; CHECK-DARWIN: bl _memset
363 ; CHECK-EABI: mov r2, #1
364 ; CHECK-EABI: bl __aeabi_memset
365 ; CHECK-GNUEABI: mov r1, #1
366 ; CHECK-GNUEABI: bl memset
367 %arr2 = alloca [13 x i8], align 1
368 %2 = getelementptr inbounds [13 x i8], ptr %arr2, i32 0, i32 16
369 call void @llvm.memset.p0.i32(ptr %2, i8 1, i32 %n, i1 false)
374 ; Check that global variables are aligned if they are large enough, but only if
375 ; they are defined in this object and don't have an explicit section.
376 @arr1 = global [7 x i8] c"\01\02\03\04\05\06\07", align 1
377 @arr2 = global [8 x i8] c"\01\02\03\04\05\06\07\08", align 1
378 @arr3 = global [7 x i8] c"\01\02\03\04\05\06\07", section "foo,bar", align 1
379 @arr4 = global [8 x i8] c"\01\02\03\04\05\06\07\08", section "foo,bar", align 1
380 @arr5 = weak global [7 x i8] c"\01\02\03\04\05\06\07", align 1
381 @arr6 = weak_odr global [7 x i8] c"\01\02\03\04\05\06\07", align 1
382 @arr7 = external global [7 x i8], align 1
383 @arr8 = internal global [128 x i8] undef
384 @arr9 = weak_odr global [128 x i8] undef
385 @arr10 = dso_local global [8 x i8] c"\01\02\03\04\05\06\07\08", align 1
386 define void @f9(ptr %dest, i32 %n) "frame-pointer"="all" {
388 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr @arr1, i32 %n, i1 false)
389 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr @arr2, i32 %n, i1 false)
390 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr @arr3, i32 %n, i1 false)
391 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr @arr4, i32 %n, i1 false)
392 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr @arr5, i32 %n, i1 false)
393 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr @arr6, i32 %n, i1 false)
394 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr @arr7, i32 %n, i1 false)
395 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr @arr8, i32 %n, i1 false)
396 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr @arr9, i32 %n, i1 false)
397 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr @arr10, i32 %n, i1 false)
401 ; CHECK: {{\.data|\.section.+data}}
402 ; CHECK-NOT: .p2align
404 ; CHECK-IOS: .p2align 3
405 ; CHECK-DARWIN: .p2align 2
406 ; CHECK-EABI-NOT: .p2align
407 ; CHECK-GNUEABI-NOT: .p2align
409 ; CHECK: {{\.section.+foo,bar}}
410 ; CHECK-NOT: .p2align
412 ; CHECK-NOT: .p2align
414 ; CHECK: {{\.data|\.section.+data}}
415 ; CHECK-NOT: .p2align
417 ; CHECK-NOT: .p2align
419 ; CHECK-IOS: arr8,128,4
420 ; CHECK-DARWIN: arr8,128,4
421 ; CHECK-EABI: arr8,128,16
422 ; CHECK-GNUEABI: arr8,128,16
425 ; CHECK-IOS: .p2align 3
426 ; CHECK-DARWIN: .p2align 2
427 ; CHECK-EABI: .p2align 2
428 ; CHECK-GNUEABI: .p2align 2
433 declare void @llvm.memmove.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind
434 declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind
435 declare void @llvm.memset.p0.i32(ptr nocapture, i8, i32, i1) nounwind