[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / AArch64 / arm64-indexed-memory.ll
blob7dcd6e25ae1f12e788ed4961e91ec9330792c497
1 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-redzone | FileCheck %s
3 define i64* @store64(i64* %ptr, i64 %index, i64 %spacing) {
4 ; CHECK-LABEL: store64:
5 ; CHECK: str x{{[0-9+]}}, [x{{[0-9+]}}], #8
6 ; CHECK: ret
7   %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 1
8   store i64 %spacing, i64* %ptr, align 4
9   ret i64* %incdec.ptr
12 define i64* @store64idxpos256(i64* %ptr, i64 %index, i64 %spacing) {
13 ; CHECK-LABEL: store64idxpos256:
14 ; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256
15 ; CHECK: str x{{[0-9+]}}, [x{{[0-9+]}}]
16 ; CHECK: ret
17   %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 32
18   store i64 %spacing, i64* %ptr, align 4
19   ret i64* %incdec.ptr
22 define i64* @store64idxneg256(i64* %ptr, i64 %index, i64 %spacing) {
23 ; CHECK-LABEL: store64idxneg256:
24 ; CHECK: str x{{[0-9+]}}, [x{{[0-9+]}}], #-256
25 ; CHECK: ret
26   %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 -32
27   store i64 %spacing, i64* %ptr, align 4
28   ret i64* %incdec.ptr
31 define i32* @store32(i32* %ptr, i32 %index, i32 %spacing) {
32 ; CHECK-LABEL: store32:
33 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #4
34 ; CHECK: ret
35   %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 1
36   store i32 %spacing, i32* %ptr, align 4
37   ret i32* %incdec.ptr
40 define i32* @store32idxpos256(i32* %ptr, i32 %index, i32 %spacing) {
41 ; CHECK-LABEL: store32idxpos256:
42 ; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256
43 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}]
44 ; CHECK: ret
45   %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 64
46   store i32 %spacing, i32* %ptr, align 4
47   ret i32* %incdec.ptr
50 define i32* @store32idxneg256(i32* %ptr, i32 %index, i32 %spacing) {
51 ; CHECK-LABEL: store32idxneg256:
52 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #-256
53 ; CHECK: ret
54   %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 -64
55   store i32 %spacing, i32* %ptr, align 4
56   ret i32* %incdec.ptr
59 define i16* @store16(i16* %ptr, i16 %index, i16 %spacing) {
60 ; CHECK-LABEL: store16:
61 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #2
62 ; CHECK: ret
63   %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 1
64   store i16 %spacing, i16* %ptr, align 4
65   ret i16* %incdec.ptr
68 define i16* @store16idxpos256(i16* %ptr, i16 %index, i16 %spacing) {
69 ; CHECK-LABEL: store16idxpos256:
70 ; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256
71 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}]
72 ; CHECK: ret
73   %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 128
74   store i16 %spacing, i16* %ptr, align 4
75   ret i16* %incdec.ptr
78 define i16* @store16idxneg256(i16* %ptr, i16 %index, i16 %spacing) {
79 ; CHECK-LABEL: store16idxneg256:
80 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #-256
81 ; CHECK: ret
82   %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 -128
83   store i16 %spacing, i16* %ptr, align 4
84   ret i16* %incdec.ptr
87 define i8* @store8(i8* %ptr, i8 %index, i8 %spacing) {
88 ; CHECK-LABEL: store8:
89 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #1
90 ; CHECK: ret
91   %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 1
92   store i8 %spacing, i8* %ptr, align 4
93   ret i8* %incdec.ptr
96 define i8* @store8idxpos256(i8* %ptr, i8 %index, i8 %spacing) {
97 ; CHECK-LABEL: store8idxpos256:
98 ; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256
99 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}]
100 ; CHECK: ret
101   %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 256
102   store i8 %spacing, i8* %ptr, align 4
103   ret i8* %incdec.ptr
106 define i8* @store8idxneg256(i8* %ptr, i8 %index, i8 %spacing) {
107 ; CHECK-LABEL: store8idxneg256:
108 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #-256
109 ; CHECK: ret
110   %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 -256
111   store i8 %spacing, i8* %ptr, align 4
112   ret i8* %incdec.ptr
115 define i32* @truncst64to32(i32* %ptr, i32 %index, i64 %spacing) {
116 ; CHECK-LABEL: truncst64to32:
117 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #4
118 ; CHECK: ret
119   %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 1
120   %trunc = trunc i64 %spacing to i32
121   store i32 %trunc, i32* %ptr, align 4
122   ret i32* %incdec.ptr
125 define i16* @truncst64to16(i16* %ptr, i16 %index, i64 %spacing) {
126 ; CHECK-LABEL: truncst64to16:
127 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #2
128 ; CHECK: ret
129   %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 1
130   %trunc = trunc i64 %spacing to i16
131   store i16 %trunc, i16* %ptr, align 4
132   ret i16* %incdec.ptr
135 define i8* @truncst64to8(i8* %ptr, i8 %index, i64 %spacing) {
136 ; CHECK-LABEL: truncst64to8:
137 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #1
138 ; CHECK: ret
139   %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 1
140   %trunc = trunc i64 %spacing to i8
141   store i8 %trunc, i8* %ptr, align 4
142   ret i8* %incdec.ptr
146 define half* @storef16(half* %ptr, half %index, half %spacing) nounwind {
147 ; CHECK-LABEL: storef16:
148 ; CHECK: str h{{[0-9+]}}, [x{{[0-9+]}}], #2
149 ; CHECK: ret
150   %incdec.ptr = getelementptr inbounds half, half* %ptr, i64 1
151   store half %spacing, half* %ptr, align 2
152   ret half* %incdec.ptr
155 define float* @storef32(float* %ptr, float %index, float %spacing) {
156 ; CHECK-LABEL: storef32:
157 ; CHECK: str s{{[0-9+]}}, [x{{[0-9+]}}], #4
158 ; CHECK: ret
159   %incdec.ptr = getelementptr inbounds float, float* %ptr, i64 1
160   store float %spacing, float* %ptr, align 4
161   ret float* %incdec.ptr
164 define double* @storef64(double* %ptr, double %index, double %spacing) {
165 ; CHECK-LABEL: storef64:
166 ; CHECK: str d{{[0-9+]}}, [x{{[0-9+]}}], #8
167 ; CHECK: ret
168   %incdec.ptr = getelementptr inbounds double, double* %ptr, i64 1
169   store double %spacing, double* %ptr, align 4
170   ret double* %incdec.ptr
174 define double* @pref64(double* %ptr, double %spacing) {
175 ; CHECK-LABEL: pref64:
176 ; CHECK:      str d0, [x0, #32]!
177 ; CHECK-NEXT: ret
178   %incdec.ptr = getelementptr inbounds double, double* %ptr, i64 4
179   store double %spacing, double* %incdec.ptr, align 4
180   ret double *%incdec.ptr
183 define float* @pref32(float* %ptr, float %spacing) {
184 ; CHECK-LABEL: pref32:
185 ; CHECK:      str s0, [x0, #12]!
186 ; CHECK-NEXT: ret
187   %incdec.ptr = getelementptr inbounds float, float* %ptr, i64 3
188   store float %spacing, float* %incdec.ptr, align 4
189   ret float *%incdec.ptr
192 define half* @pref16(half* %ptr, half %spacing) nounwind {
193 ; CHECK-LABEL: pref16:
194 ; CHECK:      str h0, [x0, #6]!
195 ; CHECK-NEXT: ret
196   %incdec.ptr = getelementptr inbounds half, half* %ptr, i64 3
197   store half %spacing, half* %incdec.ptr, align 2
198   ret half *%incdec.ptr
201 define i64* @pre64(i64* %ptr, i64 %spacing) {
202 ; CHECK-LABEL: pre64:
203 ; CHECK:      str x1, [x0, #16]!
204 ; CHECK-NEXT: ret
205   %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 2
206   store i64 %spacing, i64* %incdec.ptr, align 4
207   ret i64 *%incdec.ptr
210 define i64* @pre64idxpos256(i64* %ptr, i64 %spacing) {
211 ; CHECK-LABEL: pre64idxpos256:
212 ; CHECK:      add x8, x0, #256
213 ; CHECK-NEXT: str x1, [x0, #256]
214 ; CHECK-NEXT: mov x0, x8
215 ; CHECK-NEXT: ret
216   %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 32
217   store i64 %spacing, i64* %incdec.ptr, align 4
218   ret i64 *%incdec.ptr
221 define i64* @pre64idxneg256(i64* %ptr, i64 %spacing) {
222 ; CHECK-LABEL: pre64idxneg256:
223 ; CHECK:      str x1, [x0, #-256]!
224 ; CHECK-NEXT: ret
225   %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 -32
226   store i64 %spacing, i64* %incdec.ptr, align 4
227   ret i64 *%incdec.ptr
230 define i32* @pre32(i32* %ptr, i32 %spacing) {
231 ; CHECK-LABEL: pre32:
232 ; CHECK:      str w1, [x0, #8]!
233 ; CHECK-NEXT: ret
234   %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 2
235   store i32 %spacing, i32* %incdec.ptr, align 4
236   ret i32 *%incdec.ptr
239 define i32* @pre32idxpos256(i32* %ptr, i32 %spacing) {
240 ; CHECK-LABEL: pre32idxpos256:
241 ; CHECK:      add x8, x0, #256
242 ; CHECK-NEXT: str w1, [x0, #256]
243 ; CHECK-NEXT: mov x0, x8
244 ; CHECK-NEXT: ret
245   %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 64
246   store i32 %spacing, i32* %incdec.ptr, align 4
247   ret i32 *%incdec.ptr
250 define i32* @pre32idxneg256(i32* %ptr, i32 %spacing) {
251 ; CHECK-LABEL: pre32idxneg256:
252 ; CHECK:      str w1, [x0, #-256]!
253 ; CHECK-NEXT: ret
254   %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 -64
255   store i32 %spacing, i32* %incdec.ptr, align 4
256   ret i32 *%incdec.ptr
259 define i16* @pre16(i16* %ptr, i16 %spacing) {
260 ; CHECK-LABEL: pre16:
261 ; CHECK:      strh w1, [x0, #4]!
262 ; CHECK-NEXT: ret
263   %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 2
264   store i16 %spacing, i16* %incdec.ptr, align 4
265   ret i16 *%incdec.ptr
268 define i16* @pre16idxpos256(i16* %ptr, i16 %spacing) {
269 ; CHECK-LABEL: pre16idxpos256:
270 ; CHECK:      add x8, x0, #256
271 ; CHECK-NEXT: strh w1, [x0, #256]
272 ; CHECK-NEXT: mov x0, x8
273 ; CHECK-NEXT: ret
274   %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 128
275   store i16 %spacing, i16* %incdec.ptr, align 4
276   ret i16 *%incdec.ptr
279 define i16* @pre16idxneg256(i16* %ptr, i16 %spacing) {
280 ; CHECK-LABEL: pre16idxneg256:
281 ; CHECK:      strh w1, [x0, #-256]!
282 ; CHECK-NEXT: ret
283   %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 -128
284   store i16 %spacing, i16* %incdec.ptr, align 4
285   ret i16 *%incdec.ptr
288 define i8* @pre8(i8* %ptr, i8 %spacing) {
289 ; CHECK-LABEL: pre8:
290 ; CHECK:      strb w1, [x0, #2]!
291 ; CHECK-NEXT: ret
292   %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 2
293   store i8 %spacing, i8* %incdec.ptr, align 4
294   ret i8 *%incdec.ptr
297 define i8* @pre8idxpos256(i8* %ptr, i8 %spacing) {
298 ; CHECK-LABEL: pre8idxpos256:
299 ; CHECK:      add x8, x0, #256
300 ; CHECK-NEXT: strb w1, [x0, #256]
301 ; CHECK-NEXT: mov x0, x8
302 ; CHECK-NEXT: ret
303   %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 256
304   store i8 %spacing, i8* %incdec.ptr, align 4
305   ret i8 *%incdec.ptr
308 define i8* @pre8idxneg256(i8* %ptr, i8 %spacing) {
309 ; CHECK-LABEL: pre8idxneg256:
310 ; CHECK:      strb w1, [x0, #-256]!
311 ; CHECK-NEXT: ret
312   %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 -256
313   store i8 %spacing, i8* %incdec.ptr, align 4
314   ret i8 *%incdec.ptr
317 define i32* @pretrunc64to32(i32* %ptr, i64 %spacing) {
318 ; CHECK-LABEL: pretrunc64to32:
319 ; CHECK:      str w1, [x0, #8]!
320 ; CHECK-NEXT: ret
321   %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 2
322   %trunc = trunc i64 %spacing to i32
323   store i32 %trunc, i32* %incdec.ptr, align 4
324   ret i32 *%incdec.ptr
327 define i16* @pretrunc64to16(i16* %ptr, i64 %spacing) {
328 ; CHECK-LABEL: pretrunc64to16:
329 ; CHECK:      strh w1, [x0, #4]!
330 ; CHECK-NEXT: ret
331   %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 2
332   %trunc = trunc i64 %spacing to i16
333   store i16 %trunc, i16* %incdec.ptr, align 4
334   ret i16 *%incdec.ptr
337 define i8* @pretrunc64to8(i8* %ptr, i64 %spacing) {
338 ; CHECK-LABEL: pretrunc64to8:
339 ; CHECK:      strb w1, [x0, #2]!
340 ; CHECK-NEXT: ret
341   %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 2
342   %trunc = trunc i64 %spacing to i8
343   store i8 %trunc, i8* %incdec.ptr, align 4
344   ret i8 *%incdec.ptr
347 ;-----
348 ; Pre-indexed loads
349 ;-----
350 define double* @preidxf64(double* %src, double* %out) {
351 ; CHECK-LABEL: preidxf64:
352 ; CHECK: ldr     d0, [x0, #8]!
353 ; CHECK: str     d0, [x1]
354 ; CHECK: ret
355   %ptr = getelementptr inbounds double, double* %src, i64 1
356   %tmp = load double, double* %ptr, align 4
357   store double %tmp, double* %out, align 4
358   ret double* %ptr
361 define float* @preidxf32(float* %src, float* %out) {
362 ; CHECK-LABEL: preidxf32:
363 ; CHECK: ldr     s0, [x0, #4]!
364 ; CHECK: str     s0, [x1]
365 ; CHECK: ret
366   %ptr = getelementptr inbounds float, float* %src, i64 1
367   %tmp = load float, float* %ptr, align 4
368   store float %tmp, float* %out, align 4
369   ret float* %ptr
372 define half* @preidxf16(half* %src, half* %out) {
373 ; CHECK-LABEL: preidxf16:
374 ; CHECK: ldr     h0, [x0, #2]!
375 ; CHECK: str     h0, [x1]
376 ; CHECK: ret
377   %ptr = getelementptr inbounds half, half* %src, i64 1
378   %tmp = load half, half* %ptr, align 2
379   store half %tmp, half* %out, align 2
380   ret half* %ptr
383 define i64* @preidx64(i64* %src, i64* %out) {
384 ; CHECK-LABEL: preidx64:
385 ; CHECK: ldr     x[[REG:[0-9]+]], [x0, #8]!
386 ; CHECK: str     x[[REG]], [x1]
387 ; CHECK: ret
388   %ptr = getelementptr inbounds i64, i64* %src, i64 1
389   %tmp = load i64, i64* %ptr, align 4
390   store i64 %tmp, i64* %out, align 4
391   ret i64* %ptr
394 define i32* @preidx32(i32* %src, i32* %out) {
395 ; CHECK: ldr     w[[REG:[0-9]+]], [x0, #4]!
396 ; CHECK: str     w[[REG]], [x1]
397 ; CHECK: ret
398   %ptr = getelementptr inbounds i32, i32* %src, i64 1
399   %tmp = load i32, i32* %ptr, align 4
400   store i32 %tmp, i32* %out, align 4
401   ret i32* %ptr
404 define i16* @preidx16zext32(i16* %src, i32* %out) {
405 ; CHECK: ldrh    w[[REG:[0-9]+]], [x0, #2]!
406 ; CHECK: str     w[[REG]], [x1]
407 ; CHECK: ret
408   %ptr = getelementptr inbounds i16, i16* %src, i64 1
409   %tmp = load i16, i16* %ptr, align 4
410   %ext = zext i16 %tmp to i32
411   store i32 %ext, i32* %out, align 4
412   ret i16* %ptr
415 define i16* @preidx16zext64(i16* %src, i64* %out) {
416 ; CHECK: ldrh    w[[REG:[0-9]+]], [x0, #2]!
417 ; CHECK: str     x[[REG]], [x1]
418 ; CHECK: ret
419   %ptr = getelementptr inbounds i16, i16* %src, i64 1
420   %tmp = load i16, i16* %ptr, align 4
421   %ext = zext i16 %tmp to i64
422   store i64 %ext, i64* %out, align 4
423   ret i16* %ptr
426 define i8* @preidx8zext32(i8* %src, i32* %out) {
427 ; CHECK: ldrb    w[[REG:[0-9]+]], [x0, #1]!
428 ; CHECK: str     w[[REG]], [x1]
429 ; CHECK: ret
430   %ptr = getelementptr inbounds i8, i8* %src, i64 1
431   %tmp = load i8, i8* %ptr, align 4
432   %ext = zext i8 %tmp to i32
433   store i32 %ext, i32* %out, align 4
434   ret i8* %ptr
437 define i8* @preidx8zext64(i8* %src, i64* %out) {
438 ; CHECK: ldrb    w[[REG:[0-9]+]], [x0, #1]!
439 ; CHECK: str     x[[REG]], [x1]
440 ; CHECK: ret
441   %ptr = getelementptr inbounds i8, i8* %src, i64 1
442   %tmp = load i8, i8* %ptr, align 4
443   %ext = zext i8 %tmp to i64
444   store i64 %ext, i64* %out, align 4
445   ret i8* %ptr
448 define i32* @preidx32sext64(i32* %src, i64* %out) {
449 ; CHECK: ldrsw   x[[REG:[0-9]+]], [x0, #4]!
450 ; CHECK: str     x[[REG]], [x1]
451 ; CHECK: ret
452   %ptr = getelementptr inbounds i32, i32* %src, i64 1
453   %tmp = load i32, i32* %ptr, align 4
454   %ext = sext i32 %tmp to i64
455   store i64 %ext, i64* %out, align 8
456   ret i32* %ptr
459 define i16* @preidx16sext32(i16* %src, i32* %out) {
460 ; CHECK: ldrsh   w[[REG:[0-9]+]], [x0, #2]!
461 ; CHECK: str     w[[REG]], [x1]
462 ; CHECK: ret
463   %ptr = getelementptr inbounds i16, i16* %src, i64 1
464   %tmp = load i16, i16* %ptr, align 4
465   %ext = sext i16 %tmp to i32
466   store i32 %ext, i32* %out, align 4
467   ret i16* %ptr
470 define i16* @preidx16sext64(i16* %src, i64* %out) {
471 ; CHECK: ldrsh   x[[REG:[0-9]+]], [x0, #2]!
472 ; CHECK: str     x[[REG]], [x1]
473 ; CHECK: ret
474   %ptr = getelementptr inbounds i16, i16* %src, i64 1
475   %tmp = load i16, i16* %ptr, align 4
476   %ext = sext i16 %tmp to i64
477   store i64 %ext, i64* %out, align 4
478   ret i16* %ptr
481 define i8* @preidx8sext32(i8* %src, i32* %out) {
482 ; CHECK: ldrsb   w[[REG:[0-9]+]], [x0, #1]!
483 ; CHECK: str     w[[REG]], [x1]
484 ; CHECK: ret
485   %ptr = getelementptr inbounds i8, i8* %src, i64 1
486   %tmp = load i8, i8* %ptr, align 4
487   %ext = sext i8 %tmp to i32
488   store i32 %ext, i32* %out, align 4
489   ret i8* %ptr
492 define i8* @preidx8sext64(i8* %src, i64* %out) {
493 ; CHECK: ldrsb   x[[REG:[0-9]+]], [x0, #1]!
494 ; CHECK: str     x[[REG]], [x1]
495 ; CHECK: ret
496   %ptr = getelementptr inbounds i8, i8* %src, i64 1
497   %tmp = load i8, i8* %ptr, align 4
498   %ext = sext i8 %tmp to i64
499   store i64 %ext, i64* %out, align 4
500   ret i8* %ptr
503 ; This test checks if illegal post-index is generated
505 define i64* @postidx_clobber(i64* %addr) nounwind noinline ssp {
506 ; CHECK-LABEL: postidx_clobber:
507 ; CHECK-NOT: str     x0, [x0], #8
508 ; ret
509  %paddr = bitcast i64* %addr to i64**
510  store i64* %addr, i64** %paddr
511  %newaddr = getelementptr i64, i64* %addr, i32 1
512  ret i64* %newaddr