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
7 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 1
8 store i64 %spacing, i64* %ptr, align 4
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+]}}]
17 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 32
18 store i64 %spacing, i64* %ptr, align 4
22 define i64* @store64idxneg256(i64* %ptr, i64 %index, i64 %spacing) {
23 ; CHECK-LABEL: store64idxneg256:
24 ; CHECK: str x{{[0-9+]}}, [x{{[0-9+]}}], #-256
26 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 -32
27 store i64 %spacing, i64* %ptr, align 4
31 define i32* @store32(i32* %ptr, i32 %index, i32 %spacing) {
32 ; CHECK-LABEL: store32:
33 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #4
35 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 1
36 store i32 %spacing, i32* %ptr, align 4
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+]}}]
45 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 64
46 store i32 %spacing, i32* %ptr, align 4
50 define i32* @store32idxneg256(i32* %ptr, i32 %index, i32 %spacing) {
51 ; CHECK-LABEL: store32idxneg256:
52 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #-256
54 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 -64
55 store i32 %spacing, i32* %ptr, align 4
59 define i16* @store16(i16* %ptr, i16 %index, i16 %spacing) {
60 ; CHECK-LABEL: store16:
61 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #2
63 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 1
64 store i16 %spacing, i16* %ptr, align 4
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+]}}]
73 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 128
74 store i16 %spacing, i16* %ptr, align 4
78 define i16* @store16idxneg256(i16* %ptr, i16 %index, i16 %spacing) {
79 ; CHECK-LABEL: store16idxneg256:
80 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #-256
82 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 -128
83 store i16 %spacing, i16* %ptr, align 4
87 define i8* @store8(i8* %ptr, i8 %index, i8 %spacing) {
88 ; CHECK-LABEL: store8:
89 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #1
91 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 1
92 store i8 %spacing, i8* %ptr, align 4
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+]}}]
101 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 256
102 store i8 %spacing, i8* %ptr, align 4
106 define i8* @store8idxneg256(i8* %ptr, i8 %index, i8 %spacing) {
107 ; CHECK-LABEL: store8idxneg256:
108 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #-256
110 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 -256
111 store i8 %spacing, i8* %ptr, align 4
115 define i32* @truncst64to32(i32* %ptr, i32 %index, i64 %spacing) {
116 ; CHECK-LABEL: truncst64to32:
117 ; CHECK: str w{{[0-9+]}}, [x{{[0-9+]}}], #4
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
125 define i16* @truncst64to16(i16* %ptr, i16 %index, i64 %spacing) {
126 ; CHECK-LABEL: truncst64to16:
127 ; CHECK: strh w{{[0-9+]}}, [x{{[0-9+]}}], #2
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
135 define i8* @truncst64to8(i8* %ptr, i8 %index, i64 %spacing) {
136 ; CHECK-LABEL: truncst64to8:
137 ; CHECK: strb w{{[0-9+]}}, [x{{[0-9+]}}], #1
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
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
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
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
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]!
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]!
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]!
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]!
205 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 2
206 store i64 %spacing, i64* %incdec.ptr, align 4
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
216 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 32
217 store i64 %spacing, i64* %incdec.ptr, align 4
221 define i64* @pre64idxneg256(i64* %ptr, i64 %spacing) {
222 ; CHECK-LABEL: pre64idxneg256:
223 ; CHECK: str x1, [x0, #-256]!
225 %incdec.ptr = getelementptr inbounds i64, i64* %ptr, i64 -32
226 store i64 %spacing, i64* %incdec.ptr, align 4
230 define i32* @pre32(i32* %ptr, i32 %spacing) {
231 ; CHECK-LABEL: pre32:
232 ; CHECK: str w1, [x0, #8]!
234 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 2
235 store i32 %spacing, i32* %incdec.ptr, align 4
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
245 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 64
246 store i32 %spacing, i32* %incdec.ptr, align 4
250 define i32* @pre32idxneg256(i32* %ptr, i32 %spacing) {
251 ; CHECK-LABEL: pre32idxneg256:
252 ; CHECK: str w1, [x0, #-256]!
254 %incdec.ptr = getelementptr inbounds i32, i32* %ptr, i64 -64
255 store i32 %spacing, i32* %incdec.ptr, align 4
259 define i16* @pre16(i16* %ptr, i16 %spacing) {
260 ; CHECK-LABEL: pre16:
261 ; CHECK: strh w1, [x0, #4]!
263 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 2
264 store i16 %spacing, i16* %incdec.ptr, align 4
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
274 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 128
275 store i16 %spacing, i16* %incdec.ptr, align 4
279 define i16* @pre16idxneg256(i16* %ptr, i16 %spacing) {
280 ; CHECK-LABEL: pre16idxneg256:
281 ; CHECK: strh w1, [x0, #-256]!
283 %incdec.ptr = getelementptr inbounds i16, i16* %ptr, i64 -128
284 store i16 %spacing, i16* %incdec.ptr, align 4
288 define i8* @pre8(i8* %ptr, i8 %spacing) {
290 ; CHECK: strb w1, [x0, #2]!
292 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 2
293 store i8 %spacing, i8* %incdec.ptr, align 4
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
303 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 256
304 store i8 %spacing, i8* %incdec.ptr, align 4
308 define i8* @pre8idxneg256(i8* %ptr, i8 %spacing) {
309 ; CHECK-LABEL: pre8idxneg256:
310 ; CHECK: strb w1, [x0, #-256]!
312 %incdec.ptr = getelementptr inbounds i8, i8* %ptr, i64 -256
313 store i8 %spacing, i8* %incdec.ptr, align 4
317 define i32* @pretrunc64to32(i32* %ptr, i64 %spacing) {
318 ; CHECK-LABEL: pretrunc64to32:
319 ; CHECK: str w1, [x0, #8]!
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
327 define i16* @pretrunc64to16(i16* %ptr, i64 %spacing) {
328 ; CHECK-LABEL: pretrunc64to16:
329 ; CHECK: strh w1, [x0, #4]!
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
337 define i8* @pretrunc64to8(i8* %ptr, i64 %spacing) {
338 ; CHECK-LABEL: pretrunc64to8:
339 ; CHECK: strb w1, [x0, #2]!
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
350 define double* @preidxf64(double* %src, double* %out) {
351 ; CHECK-LABEL: preidxf64:
352 ; CHECK: ldr d0, [x0, #8]!
353 ; CHECK: str d0, [x1]
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
361 define float* @preidxf32(float* %src, float* %out) {
362 ; CHECK-LABEL: preidxf32:
363 ; CHECK: ldr s0, [x0, #4]!
364 ; CHECK: str s0, [x1]
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
372 define half* @preidxf16(half* %src, half* %out) {
373 ; CHECK-LABEL: preidxf16:
374 ; CHECK: ldr h0, [x0, #2]!
375 ; CHECK: str h0, [x1]
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
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]
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
394 define i32* @preidx32(i32* %src, i32* %out) {
395 ; CHECK: ldr w[[REG:[0-9]+]], [x0, #4]!
396 ; CHECK: str w[[REG]], [x1]
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
404 define i16* @preidx16zext32(i16* %src, i32* %out) {
405 ; CHECK: ldrh w[[REG:[0-9]+]], [x0, #2]!
406 ; CHECK: str w[[REG]], [x1]
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
415 define i16* @preidx16zext64(i16* %src, i64* %out) {
416 ; CHECK: ldrh w[[REG:[0-9]+]], [x0, #2]!
417 ; CHECK: str x[[REG]], [x1]
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
426 define i8* @preidx8zext32(i8* %src, i32* %out) {
427 ; CHECK: ldrb w[[REG:[0-9]+]], [x0, #1]!
428 ; CHECK: str w[[REG]], [x1]
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
437 define i8* @preidx8zext64(i8* %src, i64* %out) {
438 ; CHECK: ldrb w[[REG:[0-9]+]], [x0, #1]!
439 ; CHECK: str x[[REG]], [x1]
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
448 define i32* @preidx32sext64(i32* %src, i64* %out) {
449 ; CHECK: ldrsw x[[REG:[0-9]+]], [x0, #4]!
450 ; CHECK: str x[[REG]], [x1]
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
459 define i16* @preidx16sext32(i16* %src, i32* %out) {
460 ; CHECK: ldrsh w[[REG:[0-9]+]], [x0, #2]!
461 ; CHECK: str w[[REG]], [x1]
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
470 define i16* @preidx16sext64(i16* %src, i64* %out) {
471 ; CHECK: ldrsh x[[REG:[0-9]+]], [x0, #2]!
472 ; CHECK: str x[[REG]], [x1]
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
481 define i8* @preidx8sext32(i8* %src, i32* %out) {
482 ; CHECK: ldrsb w[[REG:[0-9]+]], [x0, #1]!
483 ; CHECK: str w[[REG]], [x1]
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
492 define i8* @preidx8sext64(i8* %src, i64* %out) {
493 ; CHECK: ldrsb x[[REG:[0-9]+]], [x0, #1]!
494 ; CHECK: str x[[REG]], [x1]
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
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
509 %paddr = bitcast i64* %addr to i64**
510 store i64* %addr, i64** %paddr
511 %newaddr = getelementptr i64, i64* %addr, i32 1