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
9 define void @f1(i8* %dest, i8* %src) {
13 ; CHECK-IOS: bl _memmove
14 ; CHECK-DARWIN: bl _memmove
15 ; CHECK-EABI: bl __aeabi_memmove
16 ; CHECK-GNUEABI: bl memmove
17 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 0, i1 false)
19 ; CHECK-IOS: bl _memcpy
20 ; CHECK-DARWIN: bl _memcpy
21 ; CHECK-EABI: bl __aeabi_memcpy
22 ; CHECK-GNUEABI: bl memcpy
23 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 0, i1 false)
25 ; EABI memset swaps arguments
26 ; CHECK-IOS: mov r1, #1
27 ; CHECK-IOS: bl _memset
28 ; CHECK-DARWIN: movs r1, #1
29 ; CHECK-DARWIN: bl _memset
30 ; CHECK-EABI: mov r2, #1
31 ; CHECK-EABI: bl __aeabi_memset
32 ; CHECK-GNUEABI: mov r1, #1
33 ; CHECK-GNUEABI: bl memset
34 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 0, i1 false)
36 ; EABI uses memclr if value set to 0
37 ; CHECK-IOS: mov r1, #0
38 ; CHECK-IOS: bl _memset
39 ; CHECK-DARWIN: movs r1, #0
40 ; CHECK-DARWIN: bl _memset
41 ; CHECK-EABI: bl __aeabi_memclr
42 ; CHECK-GNUEABI: bl memset
43 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 0, i1 false)
45 ; EABI uses aligned function variants if possible
47 ; CHECK-IOS: bl _memmove
48 ; CHECK-DARWIN: bl _memmove
49 ; CHECK-EABI: bl __aeabi_memmove4
50 ; CHECK-GNUEABI: bl memmove
51 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 4, i1 false)
53 ; CHECK-IOS: bl _memcpy
54 ; CHECK-DARWIN: bl _memcpy
55 ; CHECK-EABI: bl __aeabi_memcpy4
56 ; CHECK-GNUEABI: bl memcpy
57 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 4, i1 false)
59 ; CHECK-IOS: bl _memset
60 ; CHECK-DARWIN: bl _memset
61 ; CHECK-EABI: bl __aeabi_memset4
62 ; CHECK-GNUEABI: bl memset
63 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 4, i1 false)
65 ; CHECK-IOS: bl _memset
66 ; CHECK-DARWIN: bl _memset
67 ; CHECK-EABI: bl __aeabi_memclr4
68 ; CHECK-GNUEABI: bl memset
69 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 4, i1 false)
71 ; CHECK-IOS: bl _memmove
72 ; CHECK-DARWIN: bl _memmove
73 ; CHECK-EABI: bl __aeabi_memmove8
74 ; CHECK-GNUEABI: bl memmove
75 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false)
77 ; CHECK-IOS: bl _memcpy
78 ; CHECK-DARWIN: bl _memcpy
79 ; CHECK-EABI: bl __aeabi_memcpy8
80 ; CHECK-GNUEABI: bl memcpy
81 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false)
83 ; CHECK-IOS: bl _memset
84 ; CHECK-DARWIN: bl _memset
85 ; CHECK-EABI: bl __aeabi_memset8
86 ; CHECK-GNUEABI: bl memset
87 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 8, i1 false)
89 ; CHECK-IOS: bl _memset
90 ; CHECK-DARWIN: bl _memset
91 ; CHECK-EABI: bl __aeabi_memclr8
92 ; CHECK-GNUEABI: bl memset
93 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 8, i1 false)
98 ; Check that alloca arguments to memory intrinsics are automatically aligned if at least 8 bytes in size
99 define void @f2(i8* %dest, i32 %n) {
103 ; IOS (ARMv7) should 8-byte align, others should 4-byte align
104 ; CHECK-IOS: add r1, sp, #32
105 ; CHECK-IOS: bl _memmove
106 ; CHECK-DARWIN: add r1, sp, #28
107 ; CHECK-DARWIN: bl _memmove
108 ; CHECK-EABI: add r1, sp, #28
109 ; CHECK-EABI: bl __aeabi_memmove
110 ; CHECK-GNUEABI: add r1, sp, #28
111 ; CHECK-GNUEABI: bl memmove
112 %arr0 = alloca [9 x i8], align 1
113 %0 = bitcast [9 x i8]* %arr0 to i8*
114 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
116 ; CHECK: add r1, sp, #16
117 ; CHECK-IOS: bl _memcpy
118 ; CHECK-DARWIN: bl _memcpy
119 ; CHECK-EABI: bl __aeabi_memcpy
120 ; CHECK-GNUEABI: bl memcpy
121 %arr1 = alloca [9 x i8], align 1
122 %1 = bitcast [9 x i8]* %arr1 to i8*
123 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, 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 %2 = bitcast [9 x i8]* %arr2 to i8*
139 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
144 ; Check that alloca arguments are not aligned if less than 8 bytes in size
145 define void @f3(i8* %dest, i32 %n) {
149 ; CHECK: {{add(.w)? r1, sp, #17|sub(.w)? r1, r7, #15}}
150 ; CHECK-IOS: bl _memmove
151 ; CHECK-DARWIN: bl _memmove
152 ; CHECK-EABI: bl __aeabi_memmove
153 ; CHECK-GNUEABI: bl memmove
154 %arr0 = alloca [7 x i8], align 1
155 %0 = bitcast [7 x i8]* %arr0 to i8*
156 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
158 ; CHECK: {{add(.w)? r1, sp, #10}}
159 ; CHECK-IOS: bl _memcpy
160 ; CHECK-DARWIN: bl _memcpy
161 ; CHECK-EABI: bl __aeabi_memcpy
162 ; CHECK-GNUEABI: bl memcpy
163 %arr1 = alloca [7 x i8], align 1
164 %1 = bitcast [7 x i8]* %arr1 to i8*
165 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
167 ; CHECK: {{add(.w)? r0, sp, #3}}
168 ; CHECK-IOS: mov r1, #1
169 ; CHECK-IOS: bl _memset
170 ; CHECK-DARWIN: movs r1, #1
171 ; CHECK-DARWIN: bl _memset
172 ; CHECK-EABI: mov r2, #1
173 ; CHECK-EABI: bl __aeabi_memset
174 ; CHECK-GNUEABI: mov r1, #1
175 ; CHECK-GNUEABI: bl memset
176 %arr2 = alloca [7 x i8], align 1
177 %2 = bitcast [7 x i8]* %arr2 to i8*
178 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
183 ; Check that alloca arguments are not aligned if size+offset is less than 8 bytes
184 define void @f4(i8* %dest, i32 %n) {
188 ; CHECK: {{add(.w)? r., sp, #23|sub(.w)? r., r7, #17}}
189 ; CHECK-IOS: bl _memmove
190 ; CHECK-DARWIN: bl _memmove
191 ; CHECK-EABI: bl __aeabi_memmove
192 ; CHECK-GNUEABI: bl memmove
193 %arr0 = alloca [9 x i8], align 1
194 %0 = getelementptr inbounds [9 x i8], [9 x i8]* %arr0, i32 0, i32 4
195 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
197 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
198 ; CHECK-IOS: bl _memcpy
199 ; CHECK-DARWIN: bl _memcpy
200 ; CHECK-EABI: bl __aeabi_memcpy
201 ; CHECK-GNUEABI: bl memcpy
202 %arr1 = alloca [9 x i8], align 1
203 %1 = getelementptr inbounds [9 x i8], [9 x i8]* %arr1, i32 0, i32 4
204 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
206 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
207 ; CHECK-IOS: mov r1, #1
208 ; CHECK-IOS: bl _memset
209 ; CHECK-DARWIN: movs r1, #1
210 ; CHECK-DARWIN: bl _memset
211 ; CHECK-EABI: mov r2, #1
212 ; CHECK-EABI: bl __aeabi_memset
213 ; CHECK-GNUEABI: mov r1, #1
214 ; CHECK-GNUEABI: bl memset
215 %arr2 = alloca [9 x i8], align 1
216 %2 = getelementptr inbounds [9 x i8], [9 x i8]* %arr2, i32 0, i32 4
217 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
222 ; Check that alloca arguments are not aligned if the offset is not a multiple of 4
223 define void @f5(i8* %dest, i32 %n) {
227 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
228 ; CHECK-IOS: bl _memmove
229 ; CHECK-DARWIN: bl _memmove
230 ; CHECK-EABI: bl __aeabi_memmove
231 ; CHECK-GNUEABI: bl memmove
232 %arr0 = alloca [13 x i8], align 1
233 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 1
234 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
236 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
237 ; CHECK-IOS: bl _memcpy
238 ; CHECK-DARWIN: bl _memcpy
239 ; CHECK-EABI: bl __aeabi_memcpy
240 ; CHECK-GNUEABI: bl memcpy
241 %arr1 = alloca [13 x i8], align 1
242 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 1
243 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
245 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
246 ; CHECK-IOS: mov r1, #1
247 ; CHECK-IOS: bl _memset
248 ; CHECK-DARWIN: movs r1, #1
249 ; CHECK-DARWIN: bl _memset
250 ; CHECK-EABI: mov r2, #1
251 ; CHECK-EABI: bl __aeabi_memset
252 ; CHECK-GNUEABI: mov r1, #1
253 ; CHECK-GNUEABI: bl memset
254 %arr2 = alloca [13 x i8], align 1
255 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 1
256 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
261 ; Check that alloca arguments are not aligned if the offset is unknown
262 define void @f6(i8* %dest, i32 %n, i32 %i) {
266 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #25}}
267 ; CHECK-IOS: bl _memmove
268 ; CHECK-DARWIN: bl _memmove
269 ; CHECK-EABI: bl __aeabi_memmove
270 ; CHECK-GNUEABI: bl memmove
271 %arr0 = alloca [13 x i8], align 1
272 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 %i
273 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
275 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
276 ; CHECK-IOS: bl _memcpy
277 ; CHECK-DARWIN: bl _memcpy
278 ; CHECK-EABI: bl __aeabi_memcpy
279 ; CHECK-GNUEABI: bl memcpy
280 %arr1 = alloca [13 x i8], align 1
281 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 %i
282 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
284 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
285 ; CHECK-IOS: mov r1, #1
286 ; CHECK-IOS: bl _memset
287 ; CHECK-DARWIN: movs r1, #1
288 ; CHECK-DARWIN: bl _memset
289 ; CHECK-EABI: mov r2, #1
290 ; CHECK-EABI: bl __aeabi_memset
291 ; CHECK-GNUEABI: mov r1, #1
292 ; CHECK-GNUEABI: bl memset
293 %arr2 = alloca [13 x i8], align 1
294 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 %i
295 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
300 ; Check that alloca arguments are not aligned if the GEP is not inbounds
301 define void @f7(i8* %dest, i32 %n) {
305 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
306 ; CHECK-IOS: bl _memmove
307 ; CHECK-DARWIN: bl _memmove
308 ; CHECK-EABI: bl __aeabi_memmove
309 ; CHECK-GNUEABI: bl memmove
310 %arr0 = alloca [13 x i8], align 1
311 %0 = getelementptr [13 x i8], [13 x i8]* %arr0, i32 0, i32 4
312 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
314 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
315 ; CHECK-IOS: bl _memcpy
316 ; CHECK-DARWIN: bl _memcpy
317 ; CHECK-EABI: bl __aeabi_memcpy
318 ; CHECK-GNUEABI: bl memcpy
319 %arr1 = alloca [13 x i8], align 1
320 %1 = getelementptr [13 x i8], [13 x i8]* %arr1, i32 0, i32 4
321 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
323 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
324 ; CHECK-IOS: mov r1, #1
325 ; CHECK-IOS: bl _memset
326 ; CHECK-DARWIN: movs r1, #1
327 ; CHECK-DARWIN: bl _memset
328 ; CHECK-EABI: mov r2, #1
329 ; CHECK-EABI: bl __aeabi_memset
330 ; CHECK-GNUEABI: mov r1, #1
331 ; CHECK-GNUEABI: bl memset
332 %arr2 = alloca [13 x i8], align 1
333 %2 = getelementptr [13 x i8], [13 x i8]* %arr2, i32 0, i32 4
334 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
339 ; Check that alloca arguments are not aligned when the offset is past the end of the allocation
340 define void @f8(i8* %dest, i32 %n) {
344 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
345 ; CHECK-IOS: bl _memmove
346 ; CHECK-DARWIN: bl _memmove
347 ; CHECK-EABI: bl __aeabi_memmove
348 ; CHECK-GNUEABI: bl memmove
349 %arr0 = alloca [13 x i8], align 1
350 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 16
351 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
353 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
354 ; CHECK-IOS: bl _memcpy
355 ; CHECK-DARWIN: bl _memcpy
356 ; CHECK-EABI: bl __aeabi_memcpy
357 ; CHECK-GNUEABI: bl memcpy
358 %arr1 = alloca [13 x i8], align 1
359 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 16
360 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
362 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
363 ; CHECK-IOS: mov r1, #1
364 ; CHECK-IOS: bl _memset
365 ; CHECK-DARWIN: movs r1, #1
366 ; CHECK-DARWIN: bl _memset
367 ; CHECK-EABI: mov r2, #1
368 ; CHECK-EABI: bl __aeabi_memset
369 ; CHECK-GNUEABI: mov r1, #1
370 ; CHECK-GNUEABI: bl memset
371 %arr2 = alloca [13 x i8], align 1
372 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 16
373 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
378 ; Check that global variables are aligned if they are large enough, but only if
379 ; they are defined in this object and don't have an explicit section.
380 @arr1 = global [7 x i8] c"\01\02\03\04\05\06\07", align 1
381 @arr2 = global [8 x i8] c"\01\02\03\04\05\06\07\08", align 1
382 @arr3 = global [7 x i8] c"\01\02\03\04\05\06\07", section "foo,bar", align 1
383 @arr4 = global [8 x i8] c"\01\02\03\04\05\06\07\08", section "foo,bar", align 1
384 @arr5 = weak global [7 x i8] c"\01\02\03\04\05\06\07", align 1
385 @arr6 = weak_odr global [7 x i8] c"\01\02\03\04\05\06\07", align 1
386 @arr7 = external global [7 x i8], align 1
387 define void @f9(i8* %dest, i32 %n) {
389 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr1, i32 0, i32 0), i32 %n, i32 1, i1 false)
390 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @arr2, i32 0, i32 0), i32 %n, i32 1, i1 false)
391 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr3, i32 0, i32 0), i32 %n, i32 1, i1 false)
392 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @arr4, i32 0, i32 0), i32 %n, i32 1, i1 false)
393 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr5, i32 0, i32 0), i32 %n, i32 1, i1 false)
394 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr6, i32 0, i32 0), i32 %n, i32 1, i1 false)
395 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr7, i32 0, i32 0), i32 %n, i32 1, i1 false)
400 ; CHECK: {{\.data|\.section.+data}}
403 ; CHECK-IOS: .align 3
404 ; CHECK-DARWIN: .align 2
405 ; CHECK-EABI-NOT: .align
406 ; CHECK-GNUEABI-NOT: .align
408 ; CHECK: {{\.section.+foo,bar}}
413 ; CHECK: {{\.data|\.section.+data}}
420 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
421 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
422 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind