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 @from = common global [500 x i32] zeroinitializer, align 4
7 @to = common global [500 x i32] zeroinitializer, align 4
14 ; CHECK-DARWIN: memmove
15 ; CHECK-EABI: __aeabi_memmove
16 call void @llvm.memmove.p0i8.p0i8.i32(i8* bitcast ([500 x i32]* @from to i8*), i8* bitcast ([500 x i32]* @to to i8*), i32 500, i32 0, i1 false)
19 ; CHECK-DARWIN: memcpy
20 ; CHECK-EABI: __aeabi_memcpy
21 call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast ([500 x i32]* @from to i8*), i8* bitcast ([500 x i32]* @to to i8*), i32 500, i32 0, i1 false)
23 ; EABI memset swaps arguments
24 ; CHECK-IOS: mov r1, #0
26 ; CHECK-DARWIN: movs r1, #0
27 ; CHECK-DARWIN: memset
28 ; CHECK-EABI: mov r2, #0
29 ; CHECK-EABI: __aeabi_memset
30 call void @llvm.memset.p0i8.i32(i8* bitcast ([500 x i32]* @from to i8*), i8 0, i32 500, i32 0, i1 false)
34 ; Check that alloca arguments to memory intrinsics are automatically aligned if at least 8 bytes in size
35 define void @f2(i8* %dest, i32 %n) {
39 ; IOS (ARMv7) should 8-byte align, others should 4-byte align
40 ; CHECK-IOS: add r1, sp, #32
42 ; CHECK-DARWIN: add r1, sp, #28
43 ; CHECK-DARWIN: memmove
44 ; CHECK-EABI: add r1, sp, #28
45 ; CHECK-EABI: __aeabi_memmove
46 %arr0 = alloca [9 x i8], align 1
47 %0 = bitcast [9 x i8]* %arr0 to i8*
48 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
50 ; CHECK: add r1, sp, #16
52 ; CHECK-DARWIN: memcpy
53 ; CHECK-EABI: __aeabi_memcpy
54 %arr1 = alloca [9 x i8], align 1
55 %1 = bitcast [9 x i8]* %arr1 to i8*
56 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
58 ; CHECK-IOS: mov r0, sp
59 ; CHECK-IOS: mov r1, #0
61 ; CHECK-DARINW: add r0, sp, #4
62 ; CHECK-DARWIN: movs r1, #0
63 ; CHECK-DARWIN: memset
64 ; CHECK-EABI: add r0, sp, #4
65 ; CHECK-EABI: mov r2, #0
66 ; CHECK-EABI: __aeabi_memset
67 %arr2 = alloca [9 x i8], align 1
68 %2 = bitcast [9 x i8]* %arr2 to i8*
69 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false)
74 ; Check that alloca arguments are not aligned if less than 8 bytes in size
75 define void @f3(i8* %dest, i32 %n) {
79 ; CHECK: {{add(.w)? r1, sp, #17|sub(.w)? r1, r7, #15}}
81 ; CHECK-DARWIN: memmove
82 ; CHECK-EABI: __aeabi_memmove
83 %arr0 = alloca [7 x i8], align 1
84 %0 = bitcast [7 x i8]* %arr0 to i8*
85 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
87 ; CHECK: {{add(.w)? r1, sp, #10}}
89 ; CHECK-DARWIN: memcpy
90 ; CHECK-EABI: __aeabi_memcpy
91 %arr1 = alloca [7 x i8], align 1
92 %1 = bitcast [7 x i8]* %arr1 to i8*
93 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
95 ; CHECK: {{add(.w)? r0, sp, #3}}
96 ; CHECK-IOS: mov r1, #0
98 ; CHECK-DARWIN: movs r1, #0
99 ; CHECK-DARWIN: memset
100 ; CHECK-EABI: mov r2, #0
101 ; CHECK-EABI: __aeabi_memset
102 %arr2 = alloca [7 x i8], align 1
103 %2 = bitcast [7 x i8]* %arr2 to i8*
104 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false)
109 ; Check that alloca arguments are not aligned if size+offset is less than 8 bytes
110 define void @f4(i8* %dest, i32 %n) {
114 ; CHECK: {{add(.w)? r., sp, #23|sub(.w)? r., r7, #17}}
116 ; CHECK-DARWIN: memmove
117 ; CHECK-EABI: __aeabi_memmove
118 %arr0 = alloca [9 x i8], align 1
119 %0 = getelementptr inbounds [9 x i8], [9 x i8]* %arr0, i32 0, i32 4
120 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
122 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
124 ; CHECK-DARWIN: memcpy
125 ; CHECK-EABI: __aeabi_memcpy
126 %arr1 = alloca [9 x i8], align 1
127 %1 = getelementptr inbounds [9 x i8], [9 x i8]* %arr1, i32 0, i32 4
128 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
130 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
131 ; CHECK-IOS: mov r1, #0
133 ; CHECK-DARWIN: movs r1, #0
134 ; CHECK-DARWIN: memset
135 ; CHECK-EABI: mov r2, #0
136 ; CHECK-EABI: __aeabi_memset
137 %arr2 = alloca [9 x i8], align 1
138 %2 = getelementptr inbounds [9 x i8], [9 x i8]* %arr2, i32 0, i32 4
139 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false)
144 ; Check that alloca arguments are not aligned if the offset is not a multiple of 4
145 define void @f5(i8* %dest, i32 %n) {
149 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
151 ; CHECK-DARWIN: memmove
152 ; CHECK-EABI: __aeabi_memmove
153 %arr0 = alloca [13 x i8], align 1
154 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 1
155 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
157 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
159 ; CHECK-DARWIN: memcpy
160 ; CHECK-EABI: __aeabi_memcpy
161 %arr1 = alloca [13 x i8], align 1
162 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 1
163 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
165 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
166 ; CHECK-IOS: mov r1, #0
168 ; CHECK-DARWIN: movs r1, #0
169 ; CHECK-DARWIN: memset
170 ; CHECK-EABI: mov r2, #0
171 ; CHECK-EABI: __aeabi_memset
172 %arr2 = alloca [13 x i8], align 1
173 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 1
174 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false)
179 ; Check that alloca arguments are not aligned if the offset is unknown
180 define void @f6(i8* %dest, i32 %n, i32 %i) {
184 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #25}}
186 ; CHECK-DARWIN: memmove
187 ; CHECK-EABI: __aeabi_memmove
188 %arr0 = alloca [13 x i8], align 1
189 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 %i
190 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
192 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
194 ; CHECK-DARWIN: memcpy
195 ; CHECK-EABI: __aeabi_memcpy
196 %arr1 = alloca [13 x i8], align 1
197 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 %i
198 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
200 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
201 ; CHECK-IOS: mov r1, #0
203 ; CHECK-DARWIN: movs r1, #0
204 ; CHECK-DARWIN: memset
205 ; CHECK-EABI: mov r2, #0
206 ; CHECK-EABI: __aeabi_memset
207 %arr2 = alloca [13 x i8], align 1
208 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 %i
209 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false)
214 ; Check that alloca arguments are not aligned if the GEP is not inbounds
215 define void @f7(i8* %dest, i32 %n) {
219 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
221 ; CHECK-DARWIN: memmove
222 ; CHECK-EABI: __aeabi_memmove
223 %arr0 = alloca [13 x i8], align 1
224 %0 = getelementptr [13 x i8], [13 x i8]* %arr0, i32 0, i32 4
225 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
227 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
229 ; CHECK-DARWIN: memcpy
230 ; CHECK-EABI: __aeabi_memcpy
231 %arr1 = alloca [13 x i8], align 1
232 %1 = getelementptr [13 x i8], [13 x i8]* %arr1, i32 0, i32 4
233 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
235 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
236 ; CHECK-IOS: mov r1, #0
238 ; CHECK-DARWIN: movs r1, #0
239 ; CHECK-DARWIN: memset
240 ; CHECK-EABI: mov r2, #0
241 ; CHECK-EABI: __aeabi_memset
242 %arr2 = alloca [13 x i8], align 1
243 %2 = getelementptr [13 x i8], [13 x i8]* %arr2, i32 0, i32 4
244 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false)
249 ; Check that alloca arguments are not aligned when the offset is past the end of the allocation
250 define void @f8(i8* %dest, i32 %n) {
254 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
256 ; CHECK-DARWIN: memmove
257 ; CHECK-EABI: __aeabi_memmove
258 %arr0 = alloca [13 x i8], align 1
259 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 16
260 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false)
262 ; CHECK: {{add(.w)? r., sp, #(10|14)}}
264 ; CHECK-DARWIN: memcpy
265 ; CHECK-EABI: __aeabi_memcpy
266 %arr1 = alloca [13 x i8], align 1
267 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 16
268 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false)
270 ; CHECK: {{add(.w)? r., sp, #(1|5)}}
271 ; CHECK-IOS: mov r1, #0
273 ; CHECK-DARWIN: movs r1, #0
274 ; CHECK-DARWIN: memset
275 ; CHECK-EABI: mov r2, #0
276 ; CHECK-EABI: __aeabi_memset
277 %arr2 = alloca [13 x i8], align 1
278 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 16
279 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false)
284 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
285 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
286 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind