1 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-redzone | FileCheck %s
2 ; RUN: llc < %s -mtriple=arm64_32-apple-ios -aarch64-redzone | FileCheck %s
4 define i64* @store64(i64* %ptr, i64 %index, i64 %spacing) {
5 ; CHECK-LABEL: store64:
6 ; CHECK: str x{{[0-9+]}}, [x{{[0-9+]}}], #8
8 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 1
9 store i64 %spacing, i64* %ptr, align 4
13 define i64* @store64idxpos256(i64* %ptr, i64 %index, i64 %spacing) {
14 ; CHECK-LABEL: store64idxpos256:
15 ; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256
16 ; CHECK: str x{{[0-9+]}}, [x{{[0-9+]}}]
18 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 32
19 store i64 %spacing, i64* %ptr, align 4
23 define i64* @store64idxneg256(i64* %ptr, i64 %index, i64 %spacing) {
24 ; CHECK-LABEL: store64idxneg256:
25 ; CHECK: str x{{[0-9+]}}, [x{{[0-9+]}}], #-256
27 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 -32
28 store i64 %spacing, i64* %ptr, align 4
32 define i32* @store32(i32* %ptr, i32 %index, i32 %spacing) {
33 ; CHECK-LABEL: store32:
34 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #4
36 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 1
37 store i32 %spacing, i32* %ptr, align 4
41 define i32* @store32idxpos256(i32* %ptr, i32 %index, i32 %spacing) {
42 ; CHECK-LABEL: store32idxpos256:
43 ; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256
44 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}]
46 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 64
47 store i32 %spacing, i32* %ptr, align 4
51 define i32* @store32idxneg256(i32* %ptr, i32 %index, i32 %spacing) {
52 ; CHECK-LABEL: store32idxneg256:
53 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #-256
55 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 -64
56 store i32 %spacing, i32* %ptr, align 4
60 define i16* @store16(i16* %ptr, i16 %index, i16 %spacing) {
61 ; CHECK-LABEL: store16:
62 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #2
64 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 1
65 store i16 %spacing, i16* %ptr, align 4
69 define i16* @store16idxpos256(i16* %ptr, i16 %index, i16 %spacing) {
70 ; CHECK-LABEL: store16idxpos256:
71 ; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256
72 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}]
74 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 128
75 store i16 %spacing, i16* %ptr, align 4
79 define i16* @store16idxneg256(i16* %ptr, i16 %index, i16 %spacing) {
80 ; CHECK-LABEL: store16idxneg256:
81 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #-256
83 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 -128
84 store i16 %spacing, i16* %ptr, align 4
88 define i8* @store8(i8* %ptr, i8 %index, i8 %spacing) {
89 ; CHECK-LABEL: store8:
90 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #1
92 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 1
93 store i8 %spacing, i8* %ptr, align 4
97 define i8* @store8idxpos256(i8* %ptr, i8 %index, i8 %spacing) {
98 ; CHECK-LABEL: store8idxpos256:
99 ; CHECK: add x{{[0-9+]}}, x{{[0-9+]}}, #256
100 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}]
102 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 256
103 store i8 %spacing, i8* %ptr, align 4
107 define i8* @store8idxneg256(i8* %ptr, i8 %index, i8 %spacing) {
108 ; CHECK-LABEL: store8idxneg256:
109 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #-256
111 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 -256
112 store i8 %spacing, i8* %ptr, align 4
116 define i32* @truncst64to32(i32* %ptr, i32 %index, i64 %spacing) {
117 ; CHECK-LABEL: truncst64to32:
118 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #4
120 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 1
121 %trunc = trunc i64 %spacing to i32
122 store i32 %trunc, i32* %ptr, align 4
126 define i16* @truncst64to16(i16* %ptr, i16 %index, i64 %spacing) {
127 ; CHECK-LABEL: truncst64to16:
128 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #2
130 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 1
131 %trunc = trunc i64 %spacing to i16
132 store i16 %trunc, i16* %ptr, align 4
136 define i8* @truncst64to8(i8* %ptr, i8 %index, i64 %spacing) {
137 ; CHECK-LABEL: truncst64to8:
138 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #1
140 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 1
141 %trunc = trunc i64 %spacing to i8
142 store i8 %trunc, i8* %ptr, align 4
147 define half* @storef16(half* %ptr, half %index, half %spacing) nounwind {
148 ; CHECK-LABEL: storef16:
149 ; CHECK: str h{{[0-9+]}}, [x{{[0-9+]}}], #2
151 %incdec.ptr = getelementptr inbounds half, half* %ptr, i64 1
152 store half %spacing, half* %ptr, align 2
153 ret half* %incdec.ptr
156 define float* @storef32(float* %ptr, float %index, float %spacing) {
157 ; CHECK-LABEL: storef32:
158 ; CHECK: str s{{[0-9+]}}, [x{{[0-9+]}}], #4
160 %incdec.ptr = getelementptr inbounds float, float* %ptr, i64 1
161 store float %spacing, float* %ptr, align 4
162 ret float* %incdec.ptr
165 define double* @storef64(double* %ptr, double %index, double %spacing) {
166 ; CHECK-LABEL: storef64:
167 ; CHECK: str d{{[0-9+]}}, [x{{[0-9+]}}], #8
169 %incdec.ptr = getelementptr inbounds double, double* %ptr, i64 1
170 store double %spacing, double* %ptr, align 4
171 ret double* %incdec.ptr
175 define double* @pref64(double* %ptr, double %spacing) {
176 ; CHECK-LABEL: pref64:
177 ; CHECK: str d0, [x0, #32]!
179 %incdec.ptr = getelementptr inbounds double, double* %ptr, i64 4
180 store double %spacing, double* %incdec.ptr, align 4
181 ret double *%incdec.ptr
184 define float* @pref32(float* %ptr, float %spacing) {
185 ; CHECK-LABEL: pref32:
186 ; CHECK: str s0, [x0, #12]!
188 %incdec.ptr = getelementptr inbounds float, float* %ptr, i64 3
189 store float %spacing, float* %incdec.ptr, align 4
190 ret float *%incdec.ptr
193 define half* @pref16(half* %ptr, half %spacing) nounwind {
194 ; CHECK-LABEL: pref16:
195 ; CHECK: str h0, [x0, #6]!
197 %incdec.ptr = getelementptr inbounds half, half* %ptr, i64 3
198 store half %spacing, half* %incdec.ptr, align 2
199 ret half *%incdec.ptr
202 define i64* @pre64(i64* %ptr, i64 %spacing) {
203 ; CHECK-LABEL: pre64:
204 ; CHECK: str x1, [x0, #16]!
206 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 2
207 store i64 %spacing, i64* %incdec.ptr, align 4
211 define i64* @pre64idxpos256(i64* %ptr, i64 %spacing) {
212 ; CHECK-LABEL: pre64idxpos256:
213 ; CHECK: add x8, x0, #256
214 ; CHECK-NEXT: str x1, [x0, #256]
215 ; CHECK-NEXT: mov x0, x8
217 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 32
218 store i64 %spacing, i64* %incdec.ptr, align 4
222 define i64* @pre64idxneg256(i64* %ptr, i64 %spacing) {
223 ; CHECK-LABEL: pre64idxneg256:
224 ; CHECK: str x1, [x0, #-256]!
226 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 -32
227 store i64 %spacing, i64* %incdec.ptr, align 4
231 define i32* @pre32(i32* %ptr, i32 %spacing) {
232 ; CHECK-LABEL: pre32:
233 ; CHECK: str w1, [x0, #8]!
235 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 2
236 store i32 %spacing, i32* %incdec.ptr, align 4
240 define i32* @pre32idxpos256(i32* %ptr, i32 %spacing) {
241 ; CHECK-LABEL: pre32idxpos256:
242 ; CHECK: add x8, x0, #256
243 ; CHECK-NEXT: str w1, [x0, #256]
244 ; CHECK-NEXT: mov x0, x8
246 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 64
247 store i32 %spacing, i32* %incdec.ptr, align 4
251 define i32* @pre32idxneg256(i32* %ptr, i32 %spacing) {
252 ; CHECK-LABEL: pre32idxneg256:
253 ; CHECK: str w1, [x0, #-256]!
255 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 -64
256 store i32 %spacing, i32* %incdec.ptr, align 4
260 define i16* @pre16(i16* %ptr, i16 %spacing) {
261 ; CHECK-LABEL: pre16:
262 ; CHECK: strh w1, [x0, #4]!
264 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 2
265 store i16 %spacing, i16* %incdec.ptr, align 4
269 define i16* @pre16idxpos256(i16* %ptr, i16 %spacing) {
270 ; CHECK-LABEL: pre16idxpos256:
271 ; CHECK: add x8, x0, #256
272 ; CHECK-NEXT: strh w1, [x0, #256]
273 ; CHECK-NEXT: mov x0, x8
275 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 128
276 store i16 %spacing, i16* %incdec.ptr, align 4
280 define i16* @pre16idxneg256(i16* %ptr, i16 %spacing) {
281 ; CHECK-LABEL: pre16idxneg256:
282 ; CHECK: strh w1, [x0, #-256]!
284 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 -128
285 store i16 %spacing, i16* %incdec.ptr, align 4
289 define i8* @pre8(i8* %ptr, i8 %spacing) {
291 ; CHECK: strb w1, [x0, #2]!
293 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 2
294 store i8 %spacing, i8* %incdec.ptr, align 4
298 define i8* @pre8idxpos256(i8* %ptr, i8 %spacing) {
299 ; CHECK-LABEL: pre8idxpos256:
300 ; CHECK: add x8, x0, #256
301 ; CHECK-NEXT: strb w1, [x0, #256]
302 ; CHECK-NEXT: mov x0, x8
304 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 256
305 store i8 %spacing, i8* %incdec.ptr, align 4
309 define i8* @pre8idxneg256(i8* %ptr, i8 %spacing) {
310 ; CHECK-LABEL: pre8idxneg256:
311 ; CHECK: strb w1, [x0, #-256]!
313 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 -256
314 store i8 %spacing, i8* %incdec.ptr, align 4
318 define i32* @pretrunc64to32(i32* %ptr, i64 %spacing) {
319 ; CHECK-LABEL: pretrunc64to32:
320 ; CHECK: str w1, [x0, #8]!
322 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 2
323 %trunc = trunc i64 %spacing to i32
324 store i32 %trunc, i32* %incdec.ptr, align 4
328 define i16* @pretrunc64to16(i16* %ptr, i64 %spacing) {
329 ; CHECK-LABEL: pretrunc64to16:
330 ; CHECK: strh w1, [x0, #4]!
332 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 2
333 %trunc = trunc i64 %spacing to i16
334 store i16 %trunc, i16* %incdec.ptr, align 4
338 define i8* @pretrunc64to8(i8* %ptr, i64 %spacing) {
339 ; CHECK-LABEL: pretrunc64to8:
340 ; CHECK: strb w1, [x0, #2]!
342 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 2
343 %trunc = trunc i64 %spacing to i8
344 store i8 %trunc, i8* %incdec.ptr, align 4
351 define double* @preidxf64(double* %src, double* %out) {
352 ; CHECK-LABEL: preidxf64:
353 ; CHECK: ldr d0, [x0, #8]!
354 ; CHECK: str d0, [x1]
356 %ptr = getelementptr inbounds double, double* %src, i64 1
357 %tmp = load double, double* %ptr, align 4
358 store double %tmp, double* %out, align 4
362 define float* @preidxf32(float* %src, float* %out) {
363 ; CHECK-LABEL: preidxf32:
364 ; CHECK: ldr s0, [x0, #4]!
365 ; CHECK: str s0, [x1]
367 %ptr = getelementptr inbounds float, float* %src, i64 1
368 %tmp = load float, float* %ptr, align 4
369 store float %tmp, float* %out, align 4
373 define half* @preidxf16(half* %src, half* %out) {
374 ; CHECK-LABEL: preidxf16:
375 ; CHECK: ldr h0, [x0, #2]!
376 ; CHECK: str h0, [x1]
378 %ptr = getelementptr inbounds half, half* %src, i64 1
379 %tmp = load half, half* %ptr, align 2
380 store half %tmp, half* %out, align 2
384 define i64* @preidx64(i64* %src, i64* %out) {
385 ; CHECK-LABEL: preidx64:
386 ; CHECK: ldr x[[REG:[0-9]+]], [x0, #8]!
387 ; CHECK: str x[[REG]], [x1]
389 %ptr = getelementptr inbounds i64, i64* %src, i64 1
390 %tmp = load i64, i64* %ptr, align 4
391 store i64 %tmp, i64* %out, align 4
395 define i32* @preidx32(i32* %src, i32* %out) {
396 ; CHECK: ldr w[[REG:[0-9]+]], [x0, #4]!
397 ; CHECK: str w[[REG]], [x1]
399 %ptr = getelementptr inbounds i32, i32* %src, i64 1
400 %tmp = load i32, i32* %ptr, align 4
401 store i32 %tmp, i32* %out, align 4
405 define i16* @preidx16zext32(i16* %src, i32* %out) {
406 ; CHECK: ldrh w[[REG:[0-9]+]], [x0, #2]!
407 ; CHECK: str w[[REG]], [x1]
409 %ptr = getelementptr inbounds i16, i16* %src, i64 1
410 %tmp = load i16, i16* %ptr, align 4
411 %ext = zext i16 %tmp to i32
412 store i32 %ext, i32* %out, align 4
416 define i16* @preidx16zext64(i16* %src, i64* %out) {
417 ; CHECK: ldrh w[[REG:[0-9]+]], [x0, #2]!
418 ; CHECK: str x[[REG]], [x1]
420 %ptr = getelementptr inbounds i16, i16* %src, i64 1
421 %tmp = load i16, i16* %ptr, align 4
422 %ext = zext i16 %tmp to i64
423 store i64 %ext, i64* %out, align 4
427 define i8* @preidx8zext32(i8* %src, i32* %out) {
428 ; CHECK: ldrb w[[REG:[0-9]+]], [x0, #1]!
429 ; CHECK: str w[[REG]], [x1]
431 %ptr = getelementptr inbounds i8, i8* %src, i64 1
432 %tmp = load i8, i8* %ptr, align 4
433 %ext = zext i8 %tmp to i32
434 store i32 %ext, i32* %out, align 4
438 define i8* @preidx8zext64(i8* %src, i64* %out) {
439 ; CHECK: ldrb w[[REG:[0-9]+]], [x0, #1]!
440 ; CHECK: str x[[REG]], [x1]
442 %ptr = getelementptr inbounds i8, i8* %src, i64 1
443 %tmp = load i8, i8* %ptr, align 4
444 %ext = zext i8 %tmp to i64
445 store i64 %ext, i64* %out, align 4
449 define i32* @preidx32sext64(i32* %src, i64* %out) {
450 ; CHECK: ldrsw x[[REG:[0-9]+]], [x0, #4]!
451 ; CHECK: str x[[REG]], [x1]
453 %ptr = getelementptr inbounds i32, i32* %src, i64 1
454 %tmp = load i32, i32* %ptr, align 4
455 %ext = sext i32 %tmp to i64
456 store i64 %ext, i64* %out, align 8
460 define i16* @preidx16sext32(i16* %src, i32* %out) {
461 ; CHECK: ldrsh w[[REG:[0-9]+]], [x0, #2]!
462 ; CHECK: str w[[REG]], [x1]
464 %ptr = getelementptr inbounds i16, i16* %src, i64 1
465 %tmp = load i16, i16* %ptr, align 4
466 %ext = sext i16 %tmp to i32
467 store i32 %ext, i32* %out, align 4
471 define i16* @preidx16sext64(i16* %src, i64* %out) {
472 ; CHECK: ldrsh x[[REG:[0-9]+]], [x0, #2]!
473 ; CHECK: str x[[REG]], [x1]
475 %ptr = getelementptr inbounds i16, i16* %src, i64 1
476 %tmp = load i16, i16* %ptr, align 4
477 %ext = sext i16 %tmp to i64
478 store i64 %ext, i64* %out, align 4
482 define i8* @preidx8sext32(i8* %src, i32* %out) {
483 ; CHECK: ldrsb w[[REG:[0-9]+]], [x0, #1]!
484 ; CHECK: str w[[REG]], [x1]
486 %ptr = getelementptr inbounds i8, i8* %src, i64 1
487 %tmp = load i8, i8* %ptr, align 4
488 %ext = sext i8 %tmp to i32
489 store i32 %ext, i32* %out, align 4
493 define i8* @preidx8sext64(i8* %src, i64* %out) {
494 ; CHECK: ldrsb x[[REG:[0-9]+]], [x0, #1]!
495 ; CHECK: str x[[REG]], [x1]
497 %ptr = getelementptr inbounds i8, i8* %src, i64 1
498 %tmp = load i8, i8* %ptr, align 4
499 %ext = sext i8 %tmp to i64
500 store i64 %ext, i64* %out, align 4
504 ; This test checks if illegal post-index is generated
506 define i64* @postidx_clobber(i64* %addr) nounwind noinline ssp {
507 ; CHECK-LABEL: postidx_clobber:
508 ; CHECK-NOT: str x0, [x0], #8
510 %paddr = bitcast i64* %addr to i64**
511 store i64* %addr, i64** %paddr
512 %newaddr = getelementptr i64, i64* %addr, i32 1