[ARM] Align stack objects passed to memory intrinsics
[oota-llvm.git] / test / CodeGen / ARM / memfunc.ll
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
9 define void @f1() {
10 entry:
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
35 define void @f2(i8* %dest, i32 %n) {
36 entry:
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
75 define void @f3(i8* %dest, i32 %n) {
76 entry:
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
110 define void @f4(i8* %dest, i32 %n) {
111 entry:
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
145 define void @f5(i8* %dest, i32 %n) {
146 entry:
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
180 define void @f6(i8* %dest, i32 %n, i32 %i) {
181 entry:
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
215 define void @f7(i8* %dest, i32 %n) {
216 entry:
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
250 define void @f8(i8* %dest, i32 %n) {
251 entry:
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
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