xref: /llvm-project/llvm/test/CodeGen/ARM/memfunc.ll (revision 0dbcd654422312d694969e56e3b668e50d6a38f9)
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
6@from = common global [500 x i32] zeroinitializer, align 4
7@to = common global [500 x i32] zeroinitializer, align 4
8
9define void @f1() {
10entry:
11  ; CHECK-LABEL: f1
12
13  ; CHECK-IOS: memmove
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)
17
18  ; CHECK-IOS: memcpy
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)
22
23  ; EABI memset swaps arguments
24  ; CHECK-IOS: mov r1, #0
25  ; CHECK-IOS: memset
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)
31  unreachable
32}
33
34; Check that alloca arguments to memory intrinsics are automatically aligned if at least 8 bytes in size
35define void @f2(i8* %dest, i32 %n) {
36entry:
37  ; CHECK-LABEL: f2
38
39  ; IOS (ARMv7) should 8-byte align, others should 4-byte align
40  ; CHECK-IOS: add r1, sp, #32
41  ; CHECK-IOS: memmove
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)
49
50  ; CHECK: add r1, sp, #16
51  ; CHECK-IOS: memcpy
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)
57
58  ; CHECK-IOS: mov r0, sp
59  ; CHECK-IOS: mov r1, #0
60  ; CHECK-IOS: memset
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)
70
71  unreachable
72}
73
74; Check that alloca arguments are not aligned if less than 8 bytes in size
75define void @f3(i8* %dest, i32 %n) {
76entry:
77  ; CHECK-LABEL: f3
78
79  ; CHECK: {{add(.w)? r1, sp, #17|sub(.w)? r1, r7, #15}}
80  ; CHECK-IOS: memmove
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)
86
87  ; CHECK: {{add(.w)? r1, sp, #10}}
88  ; CHECK-IOS: memcpy
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)
94
95  ; CHECK: {{add(.w)? r0, sp, #3}}
96  ; CHECK-IOS: mov r1, #0
97  ; CHECK-IOS: memset
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)
105
106  unreachable
107}
108
109; Check that alloca arguments are not aligned if size+offset is less than 8 bytes
110define void @f4(i8* %dest, i32 %n) {
111entry:
112  ; CHECK-LABEL: f4
113
114  ; CHECK: {{add(.w)? r., sp, #23|sub(.w)? r., r7, #17}}
115  ; CHECK-IOS: memmove
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)
121
122  ; CHECK: {{add(.w)? r., sp, #(10|14)}}
123  ; CHECK-IOS: memcpy
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)
129
130  ; CHECK: {{add(.w)? r., sp, #(1|5)}}
131  ; CHECK-IOS: mov r1, #0
132  ; CHECK-IOS: memset
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)
140
141  unreachable
142}
143
144; Check that alloca arguments are not aligned if the offset is not a multiple of 4
145define void @f5(i8* %dest, i32 %n) {
146entry:
147  ; CHECK-LABEL: f5
148
149  ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
150  ; CHECK-IOS: memmove
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)
156
157  ; CHECK: {{add(.w)? r., sp, #(10|14)}}
158  ; CHECK-IOS: memcpy
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)
164
165  ; CHECK: {{add(.w)? r., sp, #(1|5)}}
166  ; CHECK-IOS: mov r1, #0
167  ; CHECK-IOS: memset
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)
175
176  unreachable
177}
178
179; Check that alloca arguments are not aligned if the offset is unknown
180define void @f6(i8* %dest, i32 %n, i32 %i) {
181entry:
182  ; CHECK-LABEL: f6
183
184  ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #25}}
185  ; CHECK-IOS: memmove
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)
191
192  ; CHECK: {{add(.w)? r., sp, #(10|14)}}
193  ; CHECK-IOS: memcpy
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)
199
200  ; CHECK: {{add(.w)? r., sp, #(1|5)}}
201  ; CHECK-IOS: mov r1, #0
202  ; CHECK-IOS: memset
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)
210
211  unreachable
212}
213
214; Check that alloca arguments are not aligned if the GEP is not inbounds
215define void @f7(i8* %dest, i32 %n) {
216entry:
217  ; CHECK-LABEL: f7
218
219  ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
220  ; CHECK-IOS: memmove
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)
226
227  ; CHECK: {{add(.w)? r., sp, #(10|14)}}
228  ; CHECK-IOS: memcpy
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)
234
235  ; CHECK: {{add(.w)? r., sp, #(1|5)}}
236  ; CHECK-IOS: mov r1, #0
237  ; CHECK-IOS: memset
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)
245
246  unreachable
247}
248
249; Check that alloca arguments are not aligned when the offset is past the end of the allocation
250define void @f8(i8* %dest, i32 %n) {
251entry:
252  ; CHECK-LABEL: f8
253
254  ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}}
255  ; CHECK-IOS: memmove
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)
261
262  ; CHECK: {{add(.w)? r., sp, #(10|14)}}
263  ; CHECK-IOS: memcpy
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)
269
270  ; CHECK: {{add(.w)? r., sp, #(1|5)}}
271  ; CHECK-IOS: mov r1, #0
272  ; CHECK-IOS: memset
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)
280
281  unreachable
282}
283
284declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
285declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
286declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
287