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
6 define void @f1(i8* %dest, i8* %src) {
11 ; CHECK-DARWIN: memmove
12 ; CHECK-EABI: __aeabi_memmove
13 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 0, i1 false)
16 ; CHECK-DARWIN: memcpy
17 ; CHECK-EABI: __aeabi_memcpy
18 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 0, i1 false)
20 ; EABI memset swaps arguments
21 ; CHECK-IOS: mov r1, #1
23 ; CHECK-DARWIN: movs r1, #1
24 ; CHECK-DARWIN: memset
25 ; CHECK-EABI: mov r2, #1
26 ; CHECK-EABI: __aeabi_memset
27 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 0, i1 false)
29 ; EABI uses memclr if value set to 0
30 ; CHECK-IOS: mov r1, #0
32 ; CHECK-DARWIN: movs r1, #0
33 ; CHECK-DARWIN: memset
34 ; CHECK-EABI: __aeabi_memclr
35 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 0, i1 false)
37 ; EABI uses aligned function variants if possible
40 ; CHECK-DARWIN: memmove
41 ; CHECK-EABI: __aeabi_memmove4
42 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 4, i1 false)
45 ; CHECK-DARWIN: memcpy
46 ; CHECK-EABI: __aeabi_memcpy4
47 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 4, i1 false)
50 ; CHECK-DARWIN: memset
51 ; CHECK-EABI: __aeabi_memset4
52 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 4, i1 false)
55 ; CHECK-DARWIN: memset
56 ; CHECK-EABI: __aeabi_memclr4
57 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 4, i1 false)
60 ; CHECK-DARWIN: memmove
61 ; CHECK-EABI: __aeabi_memmove8
62 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false)
65 ; CHECK-DARWIN: memcpy
66 ; CHECK-EABI: __aeabi_memcpy8
67 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false)
70 ; CHECK-DARWIN: memset
71 ; CHECK-EABI: __aeabi_memset8
72 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 8, i1 false)
75 ; CHECK-DARWIN: memset
76 ; CHECK-EABI: __aeabi_memclr8
77 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 8, i1 false)
82 ; Check that alloca arguments to memory intrinsics are automatically aligned if at least 8 bytes in size
83 define void @f2(i8* %dest, i32 %n) {
87 ; IOS (ARMv7) should 8-byte align, others should 4-byte align
88 ; CHECK-IOS: add r1, sp, #32
90 ; CHECK-DARWIN: add r1, sp, #28
91 ; CHECK-DARWIN: memmove
92 ; CHECK-EABI: add r1, sp, #28
93 ; CHECK-EABI: __aeabi_memmove
94 %arr0 = alloca [9 x i8], align 1
95 %0 = bitcast [9 x i8]* %arr0 to i8*
96 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
98 ; CHECK: add r1, sp, #16
100 ; CHECK-DARWIN: memcpy
101 ; CHECK-EABI: __aeabi_memcpy
102 %arr1 = alloca [9 x i8], align 1
103 %1 = bitcast [9 x i8]* %arr1 to i8*
104 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
106 ; CHECK-IOS: mov r0, sp
107 ; CHECK-IOS: mov r1, #1
109 ; CHECK-DARWIN: add r0, sp, #4
110 ; CHECK-DARWIN: movs r1, #1
111 ; CHECK-DARWIN: memset
112 ; CHECK-EABI: add r0, sp, #4
113 ; CHECK-EABI: mov r2, #1
114 ; CHECK-EABI: __aeabi_memset
115 %arr2 = alloca [9 x i8], align 1
116 %2 = bitcast [9 x i8]* %arr2 to i8*
117 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
122 ; Check that alloca arguments are not aligned if less than 8 bytes in size
123 define void @f3(i8* %dest, i32 %n) {
127 ; CHECK: {{add(.w)? r1, sp, #17|sub(.w)? r1, r7, #15}}
129 ; CHECK-DARWIN: memmove
130 ; CHECK-EABI: __aeabi_memmove
131 %arr0 = alloca [7 x i8], align 1
132 %0 = bitcast [7 x i8]* %arr0 to i8*
133 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
135 ; CHECK: {{add(.w)? r1, sp, #10}}
137 ; CHECK-DARWIN: memcpy
138 ; CHECK-EABI: __aeabi_memcpy
139 %arr1 = alloca [7 x i8], align 1
140 %1 = bitcast [7 x i8]* %arr1 to i8*
141 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
143 ; CHECK: {{add(.w)? r0, sp, #3}}
144 ; CHECK-IOS: mov r1, #1
146 ; CHECK-DARWIN: movs r1, #1
147 ; CHECK-DARWIN: memset
148 ; CHECK-EABI: mov r2, #1
149 ; CHECK-EABI: __aeabi_memset
150 %arr2 = alloca [7 x i8], align 1
151 %2 = bitcast [7 x i8]* %arr2 to i8*
152 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
157 ; Check that alloca arguments are not aligned if size+offset is less than 8 bytes
158 define void @f4(i8* %dest, i32 %n) {
162 ; CHECK: {{add(.w)? r., sp, #23|sub(.w)? r., r7, #17}}
164 ; CHECK-DARWIN: memmove
165 ; CHECK-EABI: __aeabi_memmove
166 %arr0 = alloca [9 x i8], align 1
167 %0 = getelementptr inbounds [9 x i8], [9 x i8]* %arr0, i32 0, i32 4
168 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
170 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
172 ; CHECK-DARWIN: memcpy
173 ; CHECK-EABI: __aeabi_memcpy
174 %arr1 = alloca [9 x i8], align 1
175 %1 = getelementptr inbounds [9 x i8], [9 x i8]* %arr1, i32 0, i32 4
176 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
178 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
179 ; CHECK-IOS: mov r1, #1
181 ; CHECK-DARWIN: movs r1, #1
182 ; CHECK-DARWIN: memset
183 ; CHECK-EABI: mov r2, #1
184 ; CHECK-EABI: __aeabi_memset
185 %arr2 = alloca [9 x i8], align 1
186 %2 = getelementptr inbounds [9 x i8], [9 x i8]* %arr2, i32 0, i32 4
187 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
192 ; Check that alloca arguments are not aligned if the offset is not a multiple of 4
193 define void @f5(i8* %dest, i32 %n) {
197 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
199 ; CHECK-DARWIN: memmove
200 ; CHECK-EABI: __aeabi_memmove
201 %arr0 = alloca [13 x i8], align 1
202 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 1
203 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
205 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
207 ; CHECK-DARWIN: memcpy
208 ; CHECK-EABI: __aeabi_memcpy
209 %arr1 = alloca [13 x i8], align 1
210 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 1
211 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
213 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
214 ; CHECK-IOS: mov r1, #1
216 ; CHECK-DARWIN: movs r1, #1
217 ; CHECK-DARWIN: memset
218 ; CHECK-EABI: mov r2, #1
219 ; CHECK-EABI: __aeabi_memset
220 %arr2 = alloca [13 x i8], align 1
221 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 1
222 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
227 ; Check that alloca arguments are not aligned if the offset is unknown
228 define void @f6(i8* %dest, i32 %n, i32 %i) {
232 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #25}}
234 ; CHECK-DARWIN: memmove
235 ; CHECK-EABI: __aeabi_memmove
236 %arr0 = alloca [13 x i8], align 1
237 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 %i
238 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
240 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
242 ; CHECK-DARWIN: memcpy
243 ; CHECK-EABI: __aeabi_memcpy
244 %arr1 = alloca [13 x i8], align 1
245 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 %i
246 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
248 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
249 ; CHECK-IOS: mov r1, #1
251 ; CHECK-DARWIN: movs r1, #1
252 ; CHECK-DARWIN: memset
253 ; CHECK-EABI: mov r2, #1
254 ; CHECK-EABI: __aeabi_memset
255 %arr2 = alloca [13 x i8], align 1
256 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 %i
257 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
262 ; Check that alloca arguments are not aligned if the GEP is not inbounds
263 define void @f7(i8* %dest, i32 %n) {
267 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
269 ; CHECK-DARWIN: memmove
270 ; CHECK-EABI: __aeabi_memmove
271 %arr0 = alloca [13 x i8], align 1
272 %0 = getelementptr [13 x i8], [13 x i8]* %arr0, i32 0, i32 4
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)}}
277 ; CHECK-DARWIN: memcpy
278 ; CHECK-EABI: __aeabi_memcpy
279 %arr1 = alloca [13 x i8], align 1
280 %1 = getelementptr [13 x i8], [13 x i8]* %arr1, i32 0, i32 4
281 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
283 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
284 ; CHECK-IOS: mov r1, #1
286 ; CHECK-DARWIN: movs r1, #1
287 ; CHECK-DARWIN: memset
288 ; CHECK-EABI: mov r2, #1
289 ; CHECK-EABI: __aeabi_memset
290 %arr2 = alloca [13 x i8], align 1
291 %2 = getelementptr [13 x i8], [13 x i8]* %arr2, i32 0, i32 4
292 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
297 ; Check that alloca arguments are not aligned when the offset is past the end of the allocation
298 define void @f8(i8* %dest, i32 %n) {
302 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
304 ; CHECK-DARWIN: memmove
305 ; CHECK-EABI: __aeabi_memmove
306 %arr0 = alloca [13 x i8], align 1
307 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 16
308 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
310 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
312 ; CHECK-DARWIN: memcpy
313 ; CHECK-EABI: __aeabi_memcpy
314 %arr1 = alloca [13 x i8], align 1
315 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 16
316 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
318 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
319 ; CHECK-IOS: mov r1, #1
321 ; CHECK-DARWIN: movs r1, #1
322 ; CHECK-DARWIN: memset
323 ; CHECK-EABI: mov r2, #1
324 ; CHECK-EABI: __aeabi_memset
325 %arr2 = alloca [13 x i8], align 1
326 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 16
327 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false)
332 ; Check that global variables are aligned if they are large enough, but only if
333 ; they are defined in this object and don't have an explicit section.
334 @arr1 = global [7 x i8] c"\01\02\03\04\05\06\07", align 1
335 @arr2 = global [8 x i8] c"\01\02\03\04\05\06\07\08", align 1
336 @arr3 = global [7 x i8] c"\01\02\03\04\05\06\07", section "foo,bar", align 1
337 @arr4 = global [8 x i8] c"\01\02\03\04\05\06\07\08", section "foo,bar", align 1
338 @arr5 = weak global [7 x i8] c"\01\02\03\04\05\06\07", align 1
339 @arr6 = weak_odr global [7 x i8] c"\01\02\03\04\05\06\07", align 1
340 @arr7 = external global [7 x i8], align 1
341 define void @f9(i8* %dest, i32 %n) {
343 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)
344 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)
345 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)
346 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)
347 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)
348 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)
349 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)
354 ; CHECK: {{\.data|\.section.+data}}
357 ; CHECK-IOS: .align 3
358 ; CHECK-DARWIN: .align 2
359 ; CHECK-EABI: .align 2
361 ; CHECK: {{\.section.+foo,bar}}
366 ; CHECK: {{\.data|\.section.+data}}
373 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
374 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
375 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind