[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / aarch64-dynamic-stack-layout.ll
blob7e97116d9d0227338dd067f400e1b367888ad49f
1 ; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -disable-post-ra < %s | FileCheck %s
2 ; RUN: llc -verify-machineinstrs -mtriple=arm64-apple-ios -frame-pointer=all -disable-post-ra < %s | FileCheck %s --check-prefix=CHECK-MACHO
4 ; This test aims to check basic correctness of frame layout &
5 ; frame access code. There are 8 functions in this test file,
6 ; each function implements one element in the cartesian product
7 ; of:
8 ; . a function having a VLA/noVLA
9 ; . a function with dynamic stack realignment/no dynamic stack realignment.
10 ; . a function needing a frame pionter/no frame pointer,
11 ; since the presence/absence of these has influence on the frame
12 ; layout and which pointer to use to access various part of the
13 ; frame (bp,sp,fp).
15 ; Furthermore: in every test function:
16 ; . there is always one integer and 1 floating point argument to be able
17 ;   to check those are accessed correctly.
18 ; . there is always one local variable to check that is accessed
19 ;   correctly
21 ; The LLVM-IR below was produced by clang on the following C++ code:
22 ;extern "C" int g();
23 ;extern "C" int novla_nodynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
24 ;                                             double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
26 ;  // use an argument passed on the stack.
27 ;  volatile int l1;
28 ;  return i10 + (int)d10 + l1 + g();
30 ;extern "C" int novla_nodynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
31 ;                                             double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
33 ;  // use an argument passed on the stack.
34 ;  volatile int l1;
35 ;  return i10 + (int)d10 + l1;
37 ;extern "C" int novla_dynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
38 ;                                         double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
40 ;  // use an argument passed on the stack.
41 ;  alignas(128) volatile int l1;
42 ;  return i10 + (int)d10 + l1 + g();
44 ;extern "C" int novla_dynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
45 ;                                           double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
47 ;  // use an argument passed on the stack.
48 ;  alignas(128) volatile int l1;
49 ;  return i10 + (int)d10 + l1;
52 ;extern "C" int vla_nodynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
53 ;                                         double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
55 ;  // use an argument passed on the stack.
56 ;  volatile int l1;
57 ;  volatile int vla[i1];
58 ;  return i10 + (int)d10 + l1 + g() + vla[0];
60 ;extern "C" int vla_nodynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
61 ;                                           double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
63 ;  // use an argument passed on the stack.
64 ;  volatile int l1;
65 ;  volatile int vla[i1];
66 ;  return i10 + (int)d10 + l1 + vla[0];
68 ;extern "C" int vla_dynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
69 ;                                       double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
71 ;  // use an argument passed on the stack.
72 ;  alignas(128) volatile int l1;
73 ;  volatile int vla[i1];
74 ;  return i10 + (int)d10 + l1 + g() + vla[0];
76 ;extern "C" int vla_dynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10,
77 ;                                         double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
79 ;  // use an argument passed on the stack.
80 ;  alignas(128) volatile int l1;
81 ;  volatile int vla[i1];
82 ;  return i10 + (int)d10 + l1 + vla[0];
87 define i32 @novla_nodynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 {
88 entry:
89   %l1 = alloca i32, align 4
90   %conv = fptosi double %d10 to i32
91   %add = add nsw i32 %conv, %i10
92   %l1.0.l1.0. = load volatile i32, ptr %l1, align 4
93   %add1 = or i32 %add, %l1.0.l1.0.
94   %call = tail call i32 @g()
95   %add2 = add nsw i32 %add1, %call
96   ret i32 %add2
98 ; CHECK-LABEL: novla_nodynamicrealign_call
99 ; CHECK: .cfi_startproc
100 ;   Check that used callee-saved registers are saved
101 ; CHECK: sub    sp, sp, #32
102 ; CHECK: stp    x30, x19, [sp, #16]
103 ;   Check correctness of cfi pseudo-instructions
104 ; CHECK: .cfi_def_cfa_offset 32
105 ; CHECK: .cfi_offset w19, -8
106 ; CHECK: .cfi_offset w30, -16
107 ;   Check correct access to arguments passed on the stack, through stack pointer
108 ; CHECK: ldr    d[[DARG:[0-9]+]], [sp, #56]
109 ; CHECK: ldr    w[[IARG:[0-9]+]], [sp, #40]
110 ;   Check correct access to local variable on the stack, through stack pointer
111 ; CHECK: ldr    w[[ILOC:[0-9]+]], [sp, #12]
112 ;   Check epilogue:
113 ; CHECK: ldp    x30, x19, [sp, #16]
114 ; CHECK: ret
115 ; CHECK: .cfi_endproc
117 ; CHECK-MACHO-LABEL: _novla_nodynamicrealign_call:
118 ; CHECK-MACHO: .cfi_startproc
119 ;   Check that used callee-saved registers are saved
120 ; CHECK-MACHO: sub      sp, sp, #48
121 ; CHECK-MACHO: stp      x20, x19, [sp, #16]
122 ;   Check that the frame pointer is created:
123 ; CHECK-MACHO: stp      x29, x30, [sp, #32]
124 ; CHECK-MACHO: add      x29, sp, #32
125 ;   Check correctness of cfi pseudo-instructions
126 ; CHECK-MACHO: .cfi_def_cfa w29, 16
127 ; CHECK-MACHO: .cfi_offset w30, -8
128 ; CHECK-MACHO: .cfi_offset w29, -16
129 ; CHECK-MACHO: .cfi_offset w19, -24
130 ; CHECK-MACHO: .cfi_offset w20, -32
131 ;   Check correct access to arguments passed on the stack, through frame pointer
132 ; CHECK-MACHO: ldr      d[[DARG:[0-9]+]], [x29, #32]
133 ; CHECK-MACHO: ldr      w[[IARG:[0-9]+]], [x29, #20]
134 ;   Check correct access to local variable on the stack, through stack pointer
135 ; CHECK-MACHO: ldr      w[[ILOC:[0-9]+]], [sp, #12]
136 ;   Check epilogue:
137 ; CHECK-MACHO: ldp      x29, x30, [sp, #32]
138 ; CHECK-MACHO: ldp      x20, x19, [sp, #16]
139 ; CHECK-MACHO: ret
140 ; CHECK-MACHO: .cfi_endproc
143 declare i32 @g() #0
145 ; Function Attrs: nounwind
146 define i32 @novla_nodynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 {
147 entry:
148   %l1 = alloca i32, align 4
149   %conv = fptosi double %d10 to i32
150   %add = add nsw i32 %conv, %i10
151   %l1.0.l1.0. = load volatile i32, ptr %l1, align 4
152   %add1 = add nsw i32 %add, %l1.0.l1.0.
153   ret i32 %add1
155 ; CHECK-LABEL: novla_nodynamicrealign_nocall
156 ;   Check that space is reserved for one local variable on the stack.
157 ; CHECK:        sub     sp, sp, #16
158 ;   Check correct access to arguments passed on the stack, through stack pointer
159 ; CHECK: ldr    d[[DARG:[0-9]+]], [sp, #40]
160 ; CHECK: ldr    w[[IARG:[0-9]+]], [sp, #24]
161 ;   Check correct access to local variable on the stack, through stack pointer
162 ; CHECK: ldr    w[[ILOC:[0-9]+]], [sp, #12]
163 ;   Check epilogue:
164 ; CHECK: add    sp, sp, #16
165 ; CHECK: ret
168 define i32 @novla_dynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 {
169 entry:
170   %l1 = alloca i32, align 128
171   %conv = fptosi double %d10 to i32
172   %add = add nsw i32 %conv, %i10
173   %l1.0.l1.0. = load volatile i32, ptr %l1, align 128
174   %add1 = or i32 %add, %l1.0.l1.0.
175   %call = tail call i32 @g()
176   %add2 = add nsw i32 %add1, %call
177   ret i32 %add2
180 ; CHECK-LABEL: novla_dynamicrealign_call
181 ; CHECK: .cfi_startproc
182 ;   Check that used callee-saved registers are saved
183 ; CHECK: stp    x29, x30, [sp, #-32]!
184 ;   Check that the frame pointer is created:
185 ; CHECK: str    x19, [sp, #16]
186 ; CHECK: mov    x29, sp
187 ;   Check the dynamic realignment of the stack pointer to a 128-byte boundary
188 ; CHECK: sub    x9, sp, #96
189 ; CHECK: and    sp, x9, #0xffffffffffffff80
190 ;   Check correctness of cfi pseudo-instructions
191 ; CHECK: .cfi_def_cfa w29, 32
192 ; CHECK: .cfi_offset w19, -16
193 ; CHECK: .cfi_offset w30, -24
194 ; CHECK: .cfi_offset w29, -32
195 ;   Check correct access to arguments passed on the stack, through frame pointer
196 ; CHECK: ldr    d[[DARG:[0-9]+]], [x29, #56]
197 ; CHECK: ldr    w[[IARG:[0-9]+]], [x29, #40]
198 ;   Check correct access to local variable on the stack, through re-aligned stack pointer
199 ; CHECK: ldr    w[[ILOC:[0-9]+]], [sp]
200 ;   Check epilogue:
201 ;     Check that stack pointer get restored from frame pointer.
202 ; CHECK: mov    sp, x29
203 ; CHECK: ldr    x19, [sp, #16]
204 ; CHECK: ldp    x29, x30, [sp], #32
205 ; CHECK: ret
206 ; CHECK: .cfi_endproc
208 ; CHECK-MACHO-LABEL: _novla_dynamicrealign_call:
209 ; CHECK-MACHO: .cfi_startproc
210 ;   Check that used callee-saved registers are saved
211 ; CHECK-MACHO: stp      x20, x19, [sp, #-32]!
212 ;   Check that the frame pointer is created:
213 ; CHECK-MACHO: stp      x29, x30, [sp, #16]
214 ; CHECK-MACHO: add      x29, sp, #16
215 ;   Check the dynamic realignment of the stack pointer to a 128-byte boundary
216 ; CHECK-MACHO: sub      x9, sp, #96
217 ; CHECK-MACHO: and      sp, x9, #0xffffffffffffff80
218 ;   Check correctness of cfi pseudo-instructions
219 ; CHECK-MACHO: .cfi_def_cfa w29, 16
220 ; CHECK-MACHO: .cfi_offset w30, -8
221 ; CHECK-MACHO: .cfi_offset w29, -16
222 ; CHECK-MACHO: .cfi_offset w19, -24
223 ; CHECK-MACHO: .cfi_offset w20, -32
224 ;   Check correct access to arguments passed on the stack, through frame pointer
225 ; CHECK-MACHO: ldr      d[[DARG:[0-9]+]], [x29, #32]
226 ; CHECK-MACHO: ldr      w[[IARG:[0-9]+]], [x29, #20]
227 ;   Check correct access to local variable on the stack, through re-aligned stack pointer
228 ; CHECK-MACHO: ldr      w[[ILOC:[0-9]+]], [sp]
229 ;   Check epilogue:
230 ;     Check that stack pointer get restored from frame pointer.
231 ; CHECK-MACHO: sub      sp, x29, #16
232 ; CHECK-MACHO: ldp      x29, x30, [sp, #16]
233 ; CHECK-MACHO: ldp      x20, x19, [sp], #32
234 ; CHECK-MACHO: ret
235 ; CHECK-MACHO: .cfi_endproc
238 ; Function Attrs: nounwind
239 define i32 @novla_dynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 {
240 entry:
241   %l1 = alloca i32, align 128
242   %conv = fptosi double %d10 to i32
243   %add = add nsw i32 %conv, %i10
244   %l1.0.l1.0. = load volatile i32, ptr %l1, align 128
245   %add1 = add nsw i32 %add, %l1.0.l1.0.
246   ret i32 %add1
249 ; CHECK-LABEL: novla_dynamicrealign_nocall
250 ;   Check that the frame pointer is created:
251 ; CHECK: stp    x29, x30, [sp, #-16]!
252 ; CHECK: mov    x29, sp
253 ;   Check the dynamic realignment of the stack pointer to a 128-byte boundary
254 ; CHECK: sub    x9, sp, #112
255 ; CHECK: and    sp, x9, #0xffffffffffffff80
256 ;   Check correct access to arguments passed on the stack, through frame pointer
257 ; CHECK: ldr    d[[DARG:[0-9]+]], [x29, #40]
258 ; CHECK: ldr    w[[IARG:[0-9]+]], [x29, #24]
259 ;   Check correct access to local variable on the stack, through re-aligned stack pointer
260 ; CHECK: ldr    w[[ILOC:[0-9]+]], [sp]
261 ;   Check epilogue:
262 ;     Check that stack pointer get restored from frame pointer.
263 ; CHECK: mov    sp, x29
264 ; CHECK: ldp    x29, x30, [sp], #16
265 ; CHECK: ret
268 define i32 @vla_nodynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 {
269 entry:
270   %l1 = alloca i32, align 4
271   %0 = zext i32 %i1 to i64
272   %vla = alloca i32, i64 %0, align 4
273   %conv = fptosi double %d10 to i32
274   %add = add nsw i32 %conv, %i10
275   %l1.0.l1.0. = load volatile i32, ptr %l1, align 4
276   %add1 = or i32 %add, %l1.0.l1.0.
277   %call = tail call i32 @g()
278   %add2 = add nsw i32 %add1, %call
279   %1 = load volatile i32, ptr %vla, align 4, !tbaa !1
280   %add3 = add nsw i32 %add2, %1
281   ret i32 %add3
284 ; CHECK-LABEL: vla_nodynamicrealign_call
285 ; CHECK: .cfi_startproc
286 ;   Check that used callee-saved registers are saved
287 ; CHECK: stp    x29, x30, [sp, #-32]!
288 ;   Check that the frame pointer is created:
289 ; CHECK: stp    x20, x19, [sp, #16]
290 ; CHECK: mov    x29, sp
291 ;   Check that space is reserved on the stack for the local variable,
292 ;   rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned.
293 ; CHECK: sub    sp, sp, #16
294 ;   Check correctness of cfi pseudo-instructions
295 ; CHECK: .cfi_def_cfa w29, 32
296 ; CHECK: .cfi_offset w19, -8
297 ; CHECK: .cfi_offset w20, -16
298 ; CHECK: .cfi_offset w30, -24
299 ; CHECK: .cfi_offset w29, -32
300 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
301 ; CHECK: ubfiz   x8, x0, #2, #32
302 ;   Check correct access to arguments passed on the stack, through frame pointer
303 ; CHECK: ldr    w[[IARG:[0-9]+]], [x29, #40]
304 ; CHECK: ldr    d[[DARG:[0-9]+]], [x29, #56]
305 ; CHECK: add     x8, x8, #15
306 ; CHECK: and     x8, x8, #0x7fffffff0
307 ; CHECK: mov     x10, sp
308 ; CHECK: sub     x[[VLASPTMP:[0-9]+]], x10, x8
309 ; CHECK: mov     sp, x[[VLASPTMP]]
310 ;   Check correct access to local variable, through frame pointer
311 ; CHECK: ldur   w[[ILOC:[0-9]+]], [x29, #-4]
312 ;   Check correct accessing of the VLA variable through the base pointer
313 ; CHECK: ldr    w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
314 ;   Check epilogue:
315 ;     Check that stack pointer get restored from frame pointer.
316 ; CHECK: mov    sp, x29
317 ; CHECK: ldp    x20, x19, [sp, #16]
318 ; CHECK: ldp    x29, x30, [sp], #32
319 ; CHECK: ret
320 ; CHECK: .cfi_endproc
323 ; Function Attrs: nounwind
324 define i32 @vla_nodynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 {
325 entry:
326   %l1 = alloca i32, align 4
327   %0 = zext i32 %i1 to i64
328   %vla = alloca i32, i64 %0, align 4
329   %conv = fptosi double %d10 to i32
330   %add = add nsw i32 %conv, %i10
331   %l1.0.l1.0. = load volatile i32, ptr %l1, align 4
332   %add1 = add nsw i32 %add, %l1.0.l1.0.
333   %1 = load volatile i32, ptr %vla, align 4, !tbaa !1
334   %add2 = add nsw i32 %add1, %1
335   ret i32 %add2
338 ; CHECK-LABEL: vla_nodynamicrealign_nocall
339 ;   Check that the frame pointer is created:
340 ; CHECK: stp    x29, x30, [sp, #-16]!
341 ; CHECK: mov    x29, sp
342 ;   Check that space is reserved on the stack for the local variable,
343 ;   rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned.
344 ; CHECK: sub    sp, sp, #16
345 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
346 ; CHECK: ubfiz  x8, x0, #2, #32
347 ;   Check correctness of cfi pseudo-instructions
348 ;   Check correct access to arguments passed on the stack, through frame pointer
349 ; CHECK: ldr    w[[IARG:[0-9]+]], [x29, #24]
350 ; CHECK: ldr    d[[DARG:[0-9]+]], [x29, #40]
351 ; CHECK: add    x8, x8, #15
352 ; CHECK: and    x8, x8, #0x7fffffff0
353 ; CHECK: mov    x10, sp
354 ; CHECK: sub    x[[VLASPTMP:[0-9]+]], x10, x8
355 ; CHECK: mov    sp, x[[VLASPTMP]]
356 ;   Check correct access to local variable, through frame pointer
357 ; CHECK: ldur   w[[ILOC:[0-9]+]], [x29, #-4]
358 ;   Check correct accessing of the VLA variable through the base pointer
359 ; CHECK: ldr    w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
360 ;   Check epilogue:
361 ;     Check that stack pointer get restored from frame pointer.
362 ; CHECK: mov    sp, x29
363 ; CHECK: ldp    x29, x30, [sp], #16
364 ; CHECK: ret
367 define i32 @vla_dynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 {
368 entry:
369   %l1 = alloca i32, align 128
370   %0 = zext i32 %i1 to i64
371   %vla = alloca i32, i64 %0, align 4
372   %conv = fptosi double %d10 to i32
373   %add = add nsw i32 %conv, %i10
374   %l1.0.l1.0. = load volatile i32, ptr %l1, align 128
375   %add1 = or i32 %add, %l1.0.l1.0.
376   %call = tail call i32 @g()
377   %add2 = add nsw i32 %add1, %call
378   %1 = load volatile i32, ptr %vla, align 4, !tbaa !1
379   %add3 = add nsw i32 %add2, %1
380   ret i32 %add3
383 ; CHECK-LABEL: vla_dynamicrealign_call
384 ; CHECK: .cfi_startproc
385 ;   Check that used callee-saved registers are saved
386 ; CHECK: stp    x29, x30, [sp, #-48]!
387 ; CHECK: str    x21, [sp, #16]
388 ; CHECK: stp    x20, x19, [sp, #32]
389 ;   Check that the frame pointer is created:
390 ; CHECK: mov    x29, sp
391 ;   Check that the stack pointer gets re-aligned to 128
392 ;   bytes & the base pointer (x19) gets initialized to
393 ;   this 128-byte aligned area for local variables &
394 ;   spill slots
395 ; CHECK: sub    x9, sp, #80
396 ; CHECK: and    sp, x9, #0xffffffffffffff80
397 ; CHECK: mov    x19, sp
398 ;   Check correctness of cfi pseudo-instructions
399 ; CHECK: .cfi_def_cfa w29, 48
400 ; CHECK: .cfi_offset w19, -8
401 ; CHECK: .cfi_offset w20, -16
402 ; CHECK: .cfi_offset w21, -32
403 ; CHECK: .cfi_offset w30, -40
404 ; CHECK: .cfi_offset w29, -48
405 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
406 ;   and set-up of base pointer (x19).
407 ; CHECK: ubfiz   x8, x0, #2, #32
408 ;   Check correct access to arguments passed on the stack, through frame pointer
409 ; CHECK: ldr    w[[IARG:[0-9]+]], [x29, #56]
410 ; CHECK: ldr     d[[DARG:[0-9]+]], [x29, #72]
411 ; CHECK: add     x8, x8, #15
412 ; CHECK: and     x8, x8, #0x7fffffff0
413 ; CHECK: mov     x10, sp
414 ; CHECK: sub     x[[VLASPTMP:[0-9]+]], x10, x8
415 ; CHECK: mov     sp, x[[VLASPTMP]]
416 ;   Check correct access to local variable, through base pointer
417 ; CHECK: ldr    w[[ILOC:[0-9]+]], [x19]
418 ; CHECK: ldr     w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
419 ;   Check epilogue:
420 ;     Check that stack pointer get restored from frame pointer.
421 ; CHECK: mov    sp, x29
422 ; CHECK: ldp    x20, x19, [sp, #32]
423 ; CHECK: ldr    x21, [sp, #16]
424 ; CHECK: ldp    x29, x30, [sp], #48
425 ; CHECK: ret
426 ; CHECK: .cfi_endproc
428 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_call:
429 ; CHECK-MACHO: .cfi_startproc
430 ;   Check that used callee-saved registers are saved
431 ; CHECK-MACHO: stp      x22, x21, [sp, #-48]!
432 ; CHECK-MACHO: stp      x20, x19, [sp, #16]
433 ;   Check that the frame pointer is created:
434 ; CHECK-MACHO: stp      x29, x30, [sp, #32]
435 ; CHECK-MACHO: add      x29, sp, #32
436 ;   Check that the stack pointer gets re-aligned to 128
437 ;   bytes & the base pointer (x19) gets initialized to
438 ;   this 128-byte aligned area for local variables &
439 ;   spill slots
440 ; CHECK-MACHO: sub      x9, sp, #80
441 ; CHECK-MACHO: and      sp, x9, #0xffffffffffffff80
442 ; CHECK-MACHO: mov    x19, sp
443 ;   Check correctness of cfi pseudo-instructions
444 ; CHECK-MACHO: .cfi_def_cfa w29, 16
445 ; CHECK-MACHO: .cfi_offset w30, -8
446 ; CHECK-MACHO: .cfi_offset w29, -16
447 ; CHECK-MACHO: .cfi_offset w19, -24
448 ; CHECK-MACHO: .cfi_offset w20, -32
449 ; CHECK-MACHO: .cfi_offset w21, -40
450 ; CHECK-MACHO: .cfi_offset w22, -48
451 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
452 ;   and set-up of base pointer (x19).
453 ; CHECK-MACHO: ubfiz     x8, x0, #2, #32
454 ;   Check correct access to arguments passed on the stack, through frame pointer
455 ; CHECK-MACHO: ldr      w[[IARG:[0-9]+]], [x29, #20]
456 ; CHECK-MACHO: ldr      d[[DARG:[0-9]+]], [x29, #32]
457 ; CHECK-MACHO: add       x8, x8, #15
458 ; CHECK-MACHO: and       x8, x8, #0x7fffffff0
459 ; CHECK-MACHO: mov       x10, sp
460 ; CHECK-MACHO: sub       x[[VLASPTMP:[0-9]+]], x10, x8
461 ; CHECK-MACHO: mov       sp, x[[VLASPTMP]]
462 ;   Check correct access to local variable, through base pointer
463 ; CHECK-MACHO: ldr      w[[ILOC:[0-9]+]], [x19]
464 ; CHECK-MACHO: ldr       w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
465 ;   Check epilogue:
466 ;     Check that stack pointer get restored from frame pointer.
467 ; CHECK-MACHO: sub      sp, x29, #32
468 ; CHECK-MACHO: ldp      x29, x30, [sp, #32]
469 ; CHECK-MACHO: ldp      x20, x19, [sp, #16]
470 ; CHECK-MACHO: ldp      x22, x21, [sp], #48
471 ; CHECK-MACHO: ret
472 ; CHECK-MACHO: .cfi_endproc
475 ; Function Attrs: nounwind
476 define i32 @vla_dynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 {
477 entry:
478   %l1 = alloca i32, align 128
479   %0 = zext i32 %i1 to i64
480   %vla = alloca i32, i64 %0, align 4
481   %conv = fptosi double %d10 to i32
482   %add = add nsw i32 %conv, %i10
483   %l1.0.l1.0. = load volatile i32, ptr %l1, align 128
484   %add1 = add nsw i32 %add, %l1.0.l1.0.
485   %1 = load volatile i32, ptr %vla, align 4, !tbaa !1
486   %add2 = add nsw i32 %add1, %1
487   ret i32 %add2
490 ; CHECK-LABEL: vla_dynamicrealign_nocall
491 ;   Check that used callee-saved registers are saved
492 ; CHECK: stp    x29, x30, [sp, #-32]!
493 ; CHECK: str    x19, [sp, #16]
494 ;   Check that the frame pointer is created:
495 ; CHECK: mov    x29, sp
496 ;   Check that the stack pointer gets re-aligned to 128
497 ;   bytes & the base pointer (x19) gets initialized to
498 ;   this 128-byte aligned area for local variables &
499 ;   spill slots
500 ; CHECK: sub    x9, sp, #96
501 ; CHECK: and    sp, x9, #0xffffffffffffff80
502 ; CHECK: mov    x19, sp
503 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
504 ;   and set-up of base pointer (x19).
505 ; CHECK: ubfiz   x8, x0, #2, #32
506 ;   Check correct access to arguments passed on the stack, through frame pointer
507 ; CHECK: ldr    w[[IARG:[0-9]+]], [x29, #40]
508 ; CHECK: ldr    d[[DARG:[0-9]+]], [x29, #56]
509 ; CHECK: add     x8, x8, #15
510 ; CHECK: and     x8, x8, #0x7fffffff0
511 ; CHECK: mov     x10, sp
512 ; CHECK: sub     x[[VLASPTMP:[0-9]+]], x10, x8
513 ; CHECK: mov     sp, x[[VLASPTMP]]
514 ;   Check correct access to local variable, through base pointer
515 ; CHECK: ldr    w[[ILOC:[0-9]+]], [x19]
516 ; CHECK: ldr     w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
517 ;   Check epilogue:
518 ;     Check that stack pointer get restored from frame pointer.
519 ; CHECK: mov    sp, x29
520 ; CHECK: ldr    x19, [sp, #16]
521 ; CHECK: ldp    x29, x30, [sp], #32
522 ; CHECK: ret
524 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall:
525 ;   Check that used callee-saved registers are saved
526 ; CHECK-MACHO: stp      x20, x19, [sp, #-32]!
527 ;   Check that the frame pointer is created:
528 ; CHECK-MACHO: stp      x29, x30, [sp, #16]
529 ; CHECK-MACHO: add      x29, sp, #16
530 ;   Check that the stack pointer gets re-aligned to 128
531 ;   bytes & the base pointer (x19) gets initialized to
532 ;   this 128-byte aligned area for local variables &
533 ;   spill slots
534 ; CHECK-MACHO: sub      x9, sp, #96
535 ; CHECK-MACHO: and      sp, x9, #0xffffffffffffff80
536 ; CHECK-MACHO: mov    x19, sp
537 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
538 ;   and set-up of base pointer (x19).
539 ; CHECK-MACHO: ubfiz     x8, x0, #2, #32
540 ;   Check correct access to arguments passed on the stack, through frame pointer
541 ; CHECK-MACHO: ldr      w[[IARG:[0-9]+]], [x29, #20]
542 ; CHECK-MACHO: ldr      d[[DARG:[0-9]+]], [x29, #32]
543 ; CHECK-MACHO: add       x8, x8, #15
544 ; CHECK-MACHO: and       x8, x8, #0x7fffffff0
545 ; CHECK-MACHO: mov       x10, sp
546 ; CHECK-MACHO: sub       x[[VLASPTMP:[0-9]+]], x10, x8
547 ; CHECK-MACHO: mov       sp, x[[VLASPTMP]]
548 ;   Check correct access to local variable, through base pointer
549 ; CHECK-MACHO: ldr      w[[ILOC:[0-9]+]], [x19]
550 ; CHECK-MACHO: ldr       w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
551 ;   Check epilogue:
552 ;     Check that stack pointer get restored from frame pointer.
553 ; CHECK-MACHO: sub      sp, x29, #16
554 ; CHECK-MACHO: ldp      x29, x30, [sp, #16]
555 ; CHECK-MACHO: ldp      x20, x19, [sp], #32
556 ; CHECK-MACHO: ret
559 ; Function Attrs: nounwind
560 define i32 @vla_dynamicrealign_nocall_large_align(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 {
561 entry:
562   %l1 = alloca i32, align 32768
563   %0 = zext i32 %i1 to i64
564   %vla = alloca i32, i64 %0, align 4
565   %conv = fptosi double %d10 to i32
566   %add = add nsw i32 %conv, %i10
567   %l1.0.l1.0. = load volatile i32, ptr %l1, align 32768
568   %add1 = add nsw i32 %add, %l1.0.l1.0.
569   %1 = load volatile i32, ptr %vla, align 4, !tbaa !1
570   %add2 = add nsw i32 %add1, %1
571   ret i32 %add2
574 ; CHECK-LABEL: vla_dynamicrealign_nocall_large_align
575 ;   Check that used callee-saved registers are saved
576 ; CHECK: stp    x29, x30, [sp, #-32]!
577 ; CHECK: str  x19, [sp, #16]
578 ;   Check that the frame pointer is created:
579 ; CHECK: mov    x29, sp
580 ;   Check that the stack pointer gets re-aligned to 128
581 ;   bytes & the base pointer (x19) gets initialized to
582 ;   this 128-byte aligned area for local variables &
583 ;   spill slots
584 ; CHECK: sub    x9, sp, #7, lsl #12
585 ; CHECK: and    sp, x9, #0xffffffffffff8000
586 ; CHECK: mov    x19, sp
587 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
588 ;   and set-up of base pointer (x19).
589 ; CHECK: ubfiz   x8, x0, #2, #32
590 ;   Check correct access to arguments passed on the stack, through frame pointer
591 ; CHECK: ldr    w[[IARG:[0-9]+]], [x29, #40]
592 ; CHECK: ldr    d[[DARG:[0-9]+]], [x29, #56]
593 ; CHECK: add     x8, x8, #15
594 ; CHECK: and     x8, x8, #0x7fffffff0
595 ; CHECK: mov     x10, sp
596 ; CHECK: sub     x[[VLASPTMP:[0-9]+]], x10, x8
597 ; CHECK: mov     sp, x[[VLASPTMP]]
598 ;   Check correct access to local variable, through base pointer
599 ; CHECK: ldr    w[[ILOC:[0-9]+]], [x19]
600 ; CHECK: ldr     w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
601 ;   Check epilogue:
602 ;     Check that stack pointer get restored from frame pointer.
603 ; CHECK: mov    sp, x29
604 ; CHECK: ldr  x19, [sp, #16]
605 ; CHECK: ldp    x29, x30, [sp], #32
606 ; CHECK: ret
608 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall_large_align:
609 ;   Check that used callee-saved registers are saved
610 ; CHECK-MACHO: stp      x20, x19, [sp, #-32]!
611 ;   Check that the frame pointer is created:
612 ; CHECK-MACHO: stp      x29, x30, [sp, #16]
613 ; CHECK-MACHO: add      x29, sp, #16
614 ;   Check that the stack pointer gets re-aligned to 128
615 ;   bytes & the base pointer (x19) gets initialized to
616 ;   this 128-byte aligned area for local variables &
617 ;   spill slots
618 ; CHECK-MACHO: sub      x9, sp, #7, lsl #12
619 ; CHECK-MACHO: and      sp, x9, #0xffffffffffff8000
620 ; CHECK-MACHO: mov    x19, sp
621 ;   Check correct reservation of 16-byte aligned VLA (size in w0) on stack
622 ;   and set-up of base pointer (x19).
623 ; CHECK-MACHO: ubfiz     x8, x0, #2, #32
624 ;   Check correct access to arguments passed on the stack, through frame pointer
625 ; CHECK-MACHO: ldr      w[[IARG:[0-9]+]], [x29, #20]
626 ; CHECK-MACHO: ldr      d[[DARG:[0-9]+]], [x29, #32]
627 ; CHECK-MACHO: add       x8, x8, #15
628 ; CHECK-MACHO: and       x8, x8, #0x7fffffff0
629 ; CHECK-MACHO: mov       x10, sp
630 ; CHECK-MACHO: sub       x[[VLASPTMP:[0-9]+]], x10, x8
631 ; CHECK-MACHO: mov       sp, x[[VLASPTMP]]
632 ;   Check correct access to local variable, through base pointer
633 ; CHECK-MACHO: ldr      w[[ILOC:[0-9]+]], [x19]
634 ; CHECK-MACHO: ldr       w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
635 ;   Check epilogue:
636 ;     Check that stack pointer get restored from frame pointer.
637 ; CHECK-MACHO: sub      sp, x29, #16
638 ; CHECK-MACHO: ldp      x29, x30, [sp, #16]
639 ; CHECK-MACHO: ldp      x20, x19, [sp], #32
640 ; CHECK-MACHO: ret
642 declare void @use(ptr)
644 define void @realign_conditional(i1 %b, ptr %p) {
645 entry:
646   br i1 %b, label %bb0, label %bb1
648 bb0:
649   %MyAlloca = alloca i8, i64 64, align 32
650   store ptr %MyAlloca, ptr %p
651   br label %bb1
653 bb1:
654   ret void
657 ; CHECK-LABEL: realign_conditional
658 ; No realignment in the prologue.
659 ; CHECK-NOT:  and
660 ; CHECK-NOT:  0xffffffffffffffe0
661 ; CHECK:  tbz  {{.*}} .[[LABEL:.*]]
662 ; Stack is realigned in a non-entry BB.
663 ; CHECK:  sub  [[REG:x[01-9]+]], sp, #64
664 ; CHECK:  and  [[REG]], [[REG]], #0xffffffffffffffe0
665 ; CHECK:  mov  sp, [[REG]]
666 ; CHECK:  .[[LABEL]]:
667 ; CHECK:  ret
670 define void @realign_conditional2(i1 %b, ptr %p) {
671 entry:
672   %tmp = alloca i8, i32 16
673   br i1 %b, label %bb0, label %bb1
675 bb0:
676   %MyAlloca = alloca i8, i64 64, align 32
677   store ptr %MyAlloca, ptr %p
678   br label %bb1
680 bb1:
681   ret void
684 ; CHECK-LABEL: realign_conditional2
685 ; Extra realignment in the prologue (performance issue).
686 ; CHECK:  tbz  {{.*}} .[[LABEL:.*]]
687 ; CHECK:  sub  x9, sp, #32
688 ; CHECK:  and  sp, x9, #0xffffffffffffffe0
689 ; CHECK:  mov   x19, sp
690 ; Stack is realigned in a non-entry BB.
691 ; CHECK:  sub  [[REG:x[01-9]+]], sp, #64
692 ; CHECK:  and  [[REG]], [[REG]], #0xffffffffffffffe0
693 ; CHECK:  mov  sp, [[REG]]
694 ; CHECK:  .[[LABEL]]:
695 ; CHECK:  ret
697 attributes #0 = { "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
698 attributes #1 = { nounwind "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
700 !1 = !{!2, !2, i64 0}
701 !2 = !{!"int", !3, i64 0}
702 !3 = !{!"omnipotent char", !4, i64 0}
703 !4 = !{!"Simple C/C++ TBAA"}