[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / ARM / indexed-mem.ll
blob295bb377d732cda71e84749edc51a3145233aec7
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=thumbv8m.main %s -o - | FileCheck %s --check-prefix=CHECK-V8M
3 ; RUN: llc -mtriple=armv8 %s -o - | FileCheck %s  --check-prefix=CHECK-V8A
5 define i32* @pre_inc_ldr(i32* %base, i32 %a) {
6 ; CHECK-V8M-LABEL: pre_inc_ldr:
7 ; CHECK-V8M:       @ %bb.0:
8 ; CHECK-V8M-NEXT:    ldr r2, [r0, #4]!
9 ; CHECK-V8M-NEXT:    add r1, r2
10 ; CHECK-V8M-NEXT:    str r1, [r0, #4]
11 ; CHECK-V8M-NEXT:    bx lr
13 ; CHECK-V8A-LABEL: pre_inc_ldr:
14 ; CHECK-V8A:       @ %bb.0:
15 ; CHECK-V8A-NEXT:    ldr r2, [r0, #4]!
16 ; CHECK-V8A-NEXT:    add r1, r2, r1
17 ; CHECK-V8A-NEXT:    str r1, [r0, #4]
18 ; CHECK-V8A-NEXT:    bx lr
19   %addr = getelementptr i32, i32* %base, i32 1
20   %ld = load i32, i32* %addr
21   %addr.1 = getelementptr i32, i32* %base, i32 2
22   %res = add i32 %ld, %a
23   store i32 %res, i32* %addr.1
24   ret i32* %addr
27 define i32* @pre_dec_ldr(i32* %base, i32 %a) {
28 ; CHECK-V8M-LABEL: pre_dec_ldr:
29 ; CHECK-V8M:       @ %bb.0:
30 ; CHECK-V8M-NEXT:    ldr r2, [r0, #-4]!
31 ; CHECK-V8M-NEXT:    add r1, r2
32 ; CHECK-V8M-NEXT:    str r1, [r0, #12]
33 ; CHECK-V8M-NEXT:    bx lr
35 ; CHECK-V8A-LABEL: pre_dec_ldr:
36 ; CHECK-V8A:       @ %bb.0:
37 ; CHECK-V8A-NEXT:    ldr r2, [r0, #-4]!
38 ; CHECK-V8A-NEXT:    add r1, r2, r1
39 ; CHECK-V8A-NEXT:    str r1, [r0, #12]
40 ; CHECK-V8A-NEXT:    bx lr
41   %addr = getelementptr i32, i32* %base, i32 -1
42   %ld = load i32, i32* %addr
43   %addr.1 = getelementptr i32, i32* %base, i32 2
44   %res = add i32 %ld, %a
45   store i32 %res, i32* %addr.1
46   ret i32* %addr
49 define i32* @post_inc_ldr(i32* %base, i32* %addr.2, i32 %a) {
50 ; CHECK-V8M-LABEL: post_inc_ldr:
51 ; CHECK-V8M:       @ %bb.0:
52 ; CHECK-V8M-NEXT:    ldr r3, [r0], #4
53 ; CHECK-V8M-NEXT:    add r2, r3
54 ; CHECK-V8M-NEXT:    str r2, [r1]
55 ; CHECK-V8M-NEXT:    bx lr
57 ; CHECK-V8A-LABEL: post_inc_ldr:
58 ; CHECK-V8A:       @ %bb.0:
59 ; CHECK-V8A-NEXT:    ldr r3, [r0], #4
60 ; CHECK-V8A-NEXT:    add r2, r3, r2
61 ; CHECK-V8A-NEXT:    str r2, [r1]
62 ; CHECK-V8A-NEXT:    bx lr
63   %addr = getelementptr i32, i32* %base, i32 0
64   %ld = load i32, i32* %addr
65   %addr.1 = getelementptr i32, i32* %base, i32 1
66   %res = add i32 %ld, %a
67   store i32 %res, i32* %addr.2
68   ret i32* %addr.1
71 define i32* @post_dec_ldr(i32* %base, i32* %addr.2, i32 %a) {
72 ; CHECK-V8M-LABEL: post_dec_ldr:
73 ; CHECK-V8M:       @ %bb.0:
74 ; CHECK-V8M-NEXT:    ldr r3, [r0], #-4
75 ; CHECK-V8M-NEXT:    add r2, r3
76 ; CHECK-V8M-NEXT:    str r2, [r1]
77 ; CHECK-V8M-NEXT:    bx lr
79 ; CHECK-V8A-LABEL: post_dec_ldr:
80 ; CHECK-V8A:       @ %bb.0:
81 ; CHECK-V8A-NEXT:    ldr r3, [r0], #-4
82 ; CHECK-V8A-NEXT:    add r2, r3, r2
83 ; CHECK-V8A-NEXT:    str r2, [r1]
84 ; CHECK-V8A-NEXT:    bx lr
85   %addr = getelementptr i32, i32* %base, i32 0
86   %ld = load i32, i32* %addr
87   %addr.1 = getelementptr i32, i32* %base, i32 -1
88   %res = add i32 %ld, %a
89   store i32 %res, i32* %addr.2
90   ret i32* %addr.1
93 define i32* @pre_inc_str(i32* %base, i32 %a, i32 %b) {
94 ; CHECK-V8M-LABEL: pre_inc_str:
95 ; CHECK-V8M:       @ %bb.0:
96 ; CHECK-V8M-NEXT:    add r1, r2
97 ; CHECK-V8M-NEXT:    str r1, [r0, #4]!
98 ; CHECK-V8M-NEXT:    bx lr
100 ; CHECK-V8A-LABEL: pre_inc_str:
101 ; CHECK-V8A:       @ %bb.0:
102 ; CHECK-V8A-NEXT:    add r1, r1, r2
103 ; CHECK-V8A-NEXT:    str r1, [r0, #4]!
104 ; CHECK-V8A-NEXT:    bx lr
105   %addr.1 = getelementptr i32, i32* %base, i32 1
106   %res = add i32 %a, %b
107   store i32 %res, i32* %addr.1
108   ret i32* %addr.1
111 define i32* @pre_dec_str(i32* %base, i32 %a, i32 %b) {
112 ; CHECK-V8M-LABEL: pre_dec_str:
113 ; CHECK-V8M:       @ %bb.0:
114 ; CHECK-V8M-NEXT:    add r1, r2
115 ; CHECK-V8M-NEXT:    str r1, [r0, #-4]!
116 ; CHECK-V8M-NEXT:    bx lr
118 ; CHECK-V8A-LABEL: pre_dec_str:
119 ; CHECK-V8A:       @ %bb.0:
120 ; CHECK-V8A-NEXT:    add r1, r1, r2
121 ; CHECK-V8A-NEXT:    str r1, [r0, #-4]!
122 ; CHECK-V8A-NEXT:    bx lr
123   %res = add i32 %a, %b
124   %addr.1 = getelementptr i32, i32* %base, i32 -1
125   store i32 %res, i32* %addr.1
126   ret i32* %addr.1
129 define i32* @post_inc_str(i32* %base, i32 %a, i32 %b) {
130 ; CHECK-V8M-LABEL: post_inc_str:
131 ; CHECK-V8M:       @ %bb.0:
132 ; CHECK-V8M-NEXT:    add r1, r2
133 ; CHECK-V8M-NEXT:    str r1, [r0], #4
134 ; CHECK-V8M-NEXT:    bx lr
136 ; CHECK-V8A-LABEL: post_inc_str:
137 ; CHECK-V8A:       @ %bb.0:
138 ; CHECK-V8A-NEXT:    add r1, r1, r2
139 ; CHECK-V8A-NEXT:    str r1, [r0], #4
140 ; CHECK-V8A-NEXT:    bx lr
141   %addr.1 = getelementptr i32, i32* %base, i32 1
142   %res = add i32 %a, %b
143   store i32 %res, i32* %base
144   ret i32* %addr.1
147 define i32* @post_dec_str(i32* %base, i32 %a, i32 %b) {
148 ; CHECK-V8M-LABEL: post_dec_str:
149 ; CHECK-V8M:       @ %bb.0:
150 ; CHECK-V8M-NEXT:    add r1, r2
151 ; CHECK-V8M-NEXT:    str r1, [r0], #-4
152 ; CHECK-V8M-NEXT:    bx lr
154 ; CHECK-V8A-LABEL: post_dec_str:
155 ; CHECK-V8A:       @ %bb.0:
156 ; CHECK-V8A-NEXT:    add r1, r1, r2
157 ; CHECK-V8A-NEXT:    str r1, [r0], #-4
158 ; CHECK-V8A-NEXT:    bx lr
159   %addr.1 = getelementptr i32, i32* %base, i32 -1
160   %res = add i32 %a, %b
161   store i32 %res, i32* %base
162   ret i32* %addr.1
165 ; TODO: Generate ldrd
166 define i32* @pre_inc_ldrd(i32* %base) {
167 ; CHECK-V8M-LABEL: pre_inc_ldrd:
168 ; CHECK-V8M:       @ %bb.0:
169 ; CHECK-V8M-NEXT:    ldr r1, [r0, #4]!
170 ; CHECK-V8M-NEXT:    ldr r2, [r0, #4]
171 ; CHECK-V8M-NEXT:    add r1, r2
172 ; CHECK-V8M-NEXT:    str r1, [r0, #8]
173 ; CHECK-V8M-NEXT:    bx lr
175 ; CHECK-V8A-LABEL: pre_inc_ldrd:
176 ; CHECK-V8A:       @ %bb.0:
177 ; CHECK-V8A-NEXT:    ldr r1, [r0, #4]!
178 ; CHECK-V8A-NEXT:    ldr r2, [r0, #4]
179 ; CHECK-V8A-NEXT:    add r1, r1, r2
180 ; CHECK-V8A-NEXT:    str r1, [r0, #8]
181 ; CHECK-V8A-NEXT:    bx lr
182   %addr = getelementptr i32, i32* %base, i32 1
183   %addr.1 = getelementptr i32, i32* %base, i32 2
184   %addr.2 = getelementptr i32, i32* %base, i32 3
185   %ld = load i32, i32* %addr
186   %ld.1 = load i32, i32* %addr.1
187   %res = add i32 %ld, %ld.1
188   store i32 %res, i32* %addr.2
189   ret i32* %addr
192 ; TODO: Generate ldrd
193 define i32* @pre_dec_ldrd(i32* %base) {
194 ; CHECK-V8M-LABEL: pre_dec_ldrd:
195 ; CHECK-V8M:       @ %bb.0:
196 ; CHECK-V8M-NEXT:    ldr r1, [r0, #-4]!
197 ; CHECK-V8M-NEXT:    ldr r2, [r0, #-4]
198 ; CHECK-V8M-NEXT:    add r1, r2
199 ; CHECK-V8M-NEXT:    str r1, [r0, #-8]
200 ; CHECK-V8M-NEXT:    bx lr
202 ; CHECK-V8A-LABEL: pre_dec_ldrd:
203 ; CHECK-V8A:       @ %bb.0:
204 ; CHECK-V8A-NEXT:    ldr r1, [r0, #-4]!
205 ; CHECK-V8A-NEXT:    ldr r2, [r0, #-4]
206 ; CHECK-V8A-NEXT:    add r1, r1, r2
207 ; CHECK-V8A-NEXT:    str r1, [r0, #-8]
208 ; CHECK-V8A-NEXT:    bx lr
209   %addr = getelementptr i32, i32* %base, i32 -1
210   %addr.1 = getelementptr i32, i32* %base, i32 -2
211   %addr.2 = getelementptr i32, i32* %base, i32 -3
212   %ld = load i32, i32* %addr
213   %ld.1 = load i32, i32* %addr.1
214   %res = add i32 %ld, %ld.1
215   store i32 %res, i32* %addr.2
216   ret i32* %addr
219 ; TODO: Generate post inc
220 define i32* @post_inc_ldrd(i32* %base, i32* %addr.3) {
221 ; CHECK-V8M-LABEL: post_inc_ldrd:
222 ; CHECK-V8M:       @ %bb.0:
223 ; CHECK-V8M-NEXT:    ldrd r2, r3, [r0], #8
224 ; CHECK-V8M-NEXT:    add r2, r3
225 ; CHECK-V8M-NEXT:    str r2, [r1]
226 ; CHECK-V8M-NEXT:    bx lr
228 ; CHECK-V8A-LABEL: post_inc_ldrd:
229 ; CHECK-V8A:       @ %bb.0:
230 ; CHECK-V8A-NEXT:    ldm r0!, {r2, r3}
231 ; CHECK-V8A-NEXT:    add r2, r2, r3
232 ; CHECK-V8A-NEXT:    str r2, [r1]
233 ; CHECK-V8A-NEXT:    bx lr
234   %addr = getelementptr i32, i32* %base, i32 0
235   %ld = load i32, i32* %addr
236   %addr.1 = getelementptr i32, i32* %base, i32 1
237   %ld.1 = load i32, i32* %addr.1
238   %addr.2 = getelementptr i32, i32* %base, i32 2
239   %res = add i32 %ld, %ld.1
240   store i32 %res, i32* %addr.3
241   ret i32* %addr.2
244 define i32* @pre_inc_str_multi(i32* %base) {
245 ; CHECK-V8M-LABEL: pre_inc_str_multi:
246 ; CHECK-V8M:       @ %bb.0:
247 ; CHECK-V8M-NEXT:    ldrd r1, r2, [r0]
248 ; CHECK-V8M-NEXT:    add r1, r2
249 ; CHECK-V8M-NEXT:    str r1, [r0, #8]!
250 ; CHECK-V8M-NEXT:    bx lr
252 ; CHECK-V8A-LABEL: pre_inc_str_multi:
253 ; CHECK-V8A:       @ %bb.0:
254 ; CHECK-V8A-NEXT:    ldm r0, {r1, r2}
255 ; CHECK-V8A-NEXT:    add r1, r1, r2
256 ; CHECK-V8A-NEXT:    str r1, [r0, #8]!
257 ; CHECK-V8A-NEXT:    bx lr
258   %addr = getelementptr i32, i32* %base, i32 0
259   %addr.1 = getelementptr i32, i32* %base, i32 1
260   %ld = load i32, i32* %addr
261   %ld.1 = load i32, i32* %addr.1
262   %res = add i32 %ld, %ld.1
263   %addr.2 = getelementptr i32, i32* %base, i32 2
264   store i32 %res, i32* %addr.2
265   ret i32* %addr.2
268 define i32* @pre_dec_str_multi(i32* %base) {
269 ; CHECK-V8M-LABEL: pre_dec_str_multi:
270 ; CHECK-V8M:       @ %bb.0:
271 ; CHECK-V8M-NEXT:    ldrd r1, r2, [r0]
272 ; CHECK-V8M-NEXT:    add r1, r2
273 ; CHECK-V8M-NEXT:    str r1, [r0, #-4]!
274 ; CHECK-V8M-NEXT:    bx lr
276 ; CHECK-V8A-LABEL: pre_dec_str_multi:
277 ; CHECK-V8A:       @ %bb.0:
278 ; CHECK-V8A-NEXT:    ldm r0, {r1, r2}
279 ; CHECK-V8A-NEXT:    add r1, r1, r2
280 ; CHECK-V8A-NEXT:    str r1, [r0, #-4]!
281 ; CHECK-V8A-NEXT:    bx lr
282   %addr = getelementptr i32, i32* %base, i32 0
283   %addr.1 = getelementptr i32, i32* %base, i32 1
284   %ld = load i32, i32* %addr
285   %ld.1 = load i32, i32* %addr.1
286   %res = add i32 %ld, %ld.1
287   %addr.2 = getelementptr i32, i32* %base, i32 -1
288   store i32 %res, i32* %addr.2
289   ret i32* %addr.2
292 define i32* @illegal_pre_inc_store_1(i32* %base) {
293 ; CHECK-V8M-LABEL: illegal_pre_inc_store_1:
294 ; CHECK-V8M:       @ %bb.0: @ %entry
295 ; CHECK-V8M-NEXT:    str r0, [r0, #8]
296 ; CHECK-V8M-NEXT:    adds r0, #8
297 ; CHECK-V8M-NEXT:    bx lr
299 ; CHECK-V8A-LABEL: illegal_pre_inc_store_1:
300 ; CHECK-V8A:       @ %bb.0: @ %entry
301 ; CHECK-V8A-NEXT:    str r0, [r0, #8]
302 ; CHECK-V8A-NEXT:    add r0, r0, #8
303 ; CHECK-V8A-NEXT:    bx lr
304 entry:
305   %ptr.to.use = getelementptr i32, i32* %base, i32 2
306   %ptr.to.store = ptrtoint i32* %base to i32
307   store i32 %ptr.to.store, i32* %ptr.to.use, align 4
308   ret i32* %ptr.to.use
311 define i32* @legal_pre_inc_store_needs_copy_1(i32* %base) {
312 ; CHECK-V8M-LABEL: legal_pre_inc_store_needs_copy_1:
313 ; CHECK-V8M:       @ %bb.0: @ %entry
314 ; CHECK-V8M-NEXT:    add.w r1, r0, #8
315 ; CHECK-V8M-NEXT:    str r1, [r0, #8]
316 ; CHECK-V8M-NEXT:    mov r0, r1
317 ; CHECK-V8M-NEXT:    bx lr
319 ; CHECK-V8A-LABEL: legal_pre_inc_store_needs_copy_1:
320 ; CHECK-V8A:       @ %bb.0: @ %entry
321 ; CHECK-V8A-NEXT:    add r1, r0, #8
322 ; CHECK-V8A-NEXT:    str r1, [r0, #8]
323 ; CHECK-V8A-NEXT:    mov r0, r1
324 ; CHECK-V8A-NEXT:    bx lr
325 entry:
326   %ptr.to.use = getelementptr i32, i32* %base, i32 2
327   %ptr.to.store = ptrtoint i32* %ptr.to.use to i32
328   store i32 %ptr.to.store, i32* %ptr.to.use, align 4
329   ret i32* %ptr.to.use
332 define i32* @legal_pre_inc_store_needs_copy_2(i32 %base) {
333 ; CHECK-V8M-LABEL: legal_pre_inc_store_needs_copy_2:
334 ; CHECK-V8M:       @ %bb.0: @ %entry
335 ; CHECK-V8M-NEXT:    str r0, [r0, #8]
336 ; CHECK-V8M-NEXT:    adds r0, #8
337 ; CHECK-V8M-NEXT:    bx lr
339 ; CHECK-V8A-LABEL: legal_pre_inc_store_needs_copy_2:
340 ; CHECK-V8A:       @ %bb.0: @ %entry
341 ; CHECK-V8A-NEXT:    str r0, [r0, #8]
342 ; CHECK-V8A-NEXT:    add r0, r0, #8
343 ; CHECK-V8A-NEXT:    bx lr
344 entry:
345   %ptr = inttoptr i32 %base to i32*
346   %ptr.to.use = getelementptr i32, i32* %ptr, i32 2
347   store i32 %base, i32* %ptr.to.use, align 4
348   ret i32* %ptr.to.use