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
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
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
21 ; The LLVM-IR below was produced by clang on the following C++ code:
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.
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.
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.
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.
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 {
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, i32* %l1, align 4
93 %add1 = add nsw i32 %add, %l1.0.l1.0.
94 %call = tail call i32 @g()
95 %add2 = add nsw i32 %add1, %call
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 x19, x30, [sp, #16]
103 ; Check correctness of cfi pseudo-instructions
104 ; CHECK: .cfi_def_cfa_offset 32
105 ; CHECK: .cfi_offset w30, -8
106 ; CHECK: .cfi_offset w19, -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]
113 ; CHECK: ldp x19, x30, [sp, #16]
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]
137 ; CHECK-MACHO: ldp x29, x30, [sp, #32]
138 ; CHECK-MACHO: ldp x20, x19, [sp, #16]
140 ; CHECK-MACHO: .cfi_endproc
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 {
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, i32* %l1, align 4
152 %add1 = add nsw i32 %add, %l1.0.l1.0.
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 // =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]
164 ; CHECK: add sp, sp, #16 // =16
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 {
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, i32* %l1, align 128
174 %add1 = add nsw i32 %add, %l1.0.l1.0.
175 %call = tail call i32 @g()
176 %add2 = add nsw i32 %add1, %call
180 ; CHECK-LABEL: novla_dynamicrealign_call
181 ; CHECK: .cfi_startproc
182 ; Check that used callee-saved registers are saved
183 ; CHECK: str x19, [sp, #-32]!
184 ; Check that the frame pointer is created:
185 ; CHECK: stp x29, x30, [sp, #16]
186 ; CHECK: add x29, sp, #16
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, 16
192 ; CHECK: .cfi_offset w30, -8
193 ; CHECK: .cfi_offset w29, -16
194 ; CHECK: .cfi_offset w19, -32
195 ; Check correct access to arguments passed on the stack, through frame pointer
196 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
197 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
198 ; Check correct access to local variable on the stack, through re-aligned stack pointer
199 ; CHECK: ldr w[[ILOC:[0-9]+]], [sp]
201 ; Check that stack pointer get restored from frame pointer.
202 ; CHECK: sub sp, x29, #16 // =16
203 ; CHECK: ldp x29, x30, [sp, #16]
204 ; CHECK: ldr x19, [sp], #32
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]
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
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 {
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, i32* %l1, align 128
245 %add1 = add nsw i32 %add, %l1.0.l1.0.
249 ; CHECK-LABEL: novla_dynamicrealign_nocall
250 ; Check that the frame pointer is created:
251 ; CHECK: stp x29, x30, [sp, #-16]!
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]
262 ; Check that stack pointer get restored from frame pointer.
264 ; CHECK: ldp x29, x30, [sp], #16
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 {
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, i32* %l1, align 4
276 %add1 = add nsw i32 %add, %l1.0.l1.0.
277 %call = tail call i32 @g()
278 %add2 = add nsw i32 %add1, %call
279 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
280 %add3 = add nsw i32 %add2, %1
284 ; CHECK-LABEL: vla_nodynamicrealign_call
285 ; CHECK: .cfi_startproc
286 ; Check that used callee-saved registers are saved
287 ; CHECK: stp x20, x19, [sp, #-32]!
288 ; Check that the frame pointer is created:
289 ; CHECK: stp x29, x30, [sp, #16]
290 ; CHECK: add x29, sp, #16
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, 16
296 ; CHECK: .cfi_offset w30, -8
297 ; CHECK: .cfi_offset w29, -16
298 ; CHECK: .cfi_offset w19, -24
299 ; CHECK: .cfi_offset w20, -32
300 ; Check correct access to arguments passed on the stack, through frame pointer
301 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
302 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
303 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
306 ; CHECK: lsl x9, x9, #2
307 ; CHECK: add x9, x9, #15
308 ; CHECK: and x9, x9, #0x7fffffff0
309 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
310 ; CHECK: mov sp, x[[VLASPTMP]]
311 ; Check correct access to local variable, through frame pointer
312 ; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-20]
313 ; Check correct accessing of the VLA variable through the base pointer
314 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
316 ; Check that stack pointer get restored from frame pointer.
317 ; CHECK: sub sp, x29, #16 // =16
318 ; CHECK: ldp x29, x30, [sp, #16]
319 ; CHECK: ldp x20, x19, [sp], #32
321 ; CHECK: .cfi_endproc
324 ; Function Attrs: nounwind
325 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 {
327 %l1 = alloca i32, align 4
328 %0 = zext i32 %i1 to i64
329 %vla = alloca i32, i64 %0, align 4
330 %conv = fptosi double %d10 to i32
331 %add = add nsw i32 %conv, %i10
332 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
333 %add1 = add nsw i32 %add, %l1.0.l1.0.
334 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
335 %add2 = add nsw i32 %add1, %1
339 ; CHECK-LABEL: vla_nodynamicrealign_nocall
340 ; Check that the frame pointer is created:
341 ; CHECK: stp x29, x30, [sp, #-16]!
343 ; Check that space is reserved on the stack for the local variable,
344 ; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned.
345 ; CHECK: sub sp, sp, #16
346 ; Check correctness of cfi pseudo-instructions
347 ; Check correct access to arguments passed on the stack, through frame pointer
348 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
349 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
350 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
353 ; CHECK: lsl x9, x9, #2
354 ; CHECK: add x9, x9, #15
355 ; CHECK: and x9, x9, #0x7fffffff0
356 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
357 ; CHECK: mov sp, x[[VLASPTMP]]
358 ; Check correct access to local variable, through frame pointer
359 ; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-4]
360 ; Check correct accessing of the VLA variable through the base pointer
361 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
363 ; Check that stack pointer get restored from frame pointer.
365 ; CHECK: ldp x29, x30, [sp], #16
369 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 {
371 %l1 = alloca i32, align 128
372 %0 = zext i32 %i1 to i64
373 %vla = alloca i32, i64 %0, align 4
374 %conv = fptosi double %d10 to i32
375 %add = add nsw i32 %conv, %i10
376 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
377 %add1 = add nsw i32 %add, %l1.0.l1.0.
378 %call = tail call i32 @g()
379 %add2 = add nsw i32 %add1, %call
380 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
381 %add3 = add nsw i32 %add2, %1
385 ; CHECK-LABEL: vla_dynamicrealign_call
386 ; CHECK: .cfi_startproc
387 ; Check that used callee-saved registers are saved
388 ; CHECK: str x21, [sp, #-48]!
389 ; CHECK: stp x20, x19, [sp, #16]
390 ; Check that the frame pointer is created:
391 ; CHECK: stp x29, x30, [sp, #32]
392 ; CHECK: add x29, sp, #32
393 ; Check that the stack pointer gets re-aligned to 128
394 ; bytes & the base pointer (x19) gets initialized to
395 ; this 128-byte aligned area for local variables &
397 ; CHECK: sub x9, sp, #80 // =80
398 ; CHECK: and sp, x9, #0xffffffffffffff80
400 ; Check correctness of cfi pseudo-instructions
401 ; CHECK: .cfi_def_cfa w29, 16
402 ; CHECK: .cfi_offset w30, -8
403 ; CHECK: .cfi_offset w29, -16
404 ; CHECK: .cfi_offset w19, -24
405 ; CHECK: .cfi_offset w20, -32
406 ; CHECK: .cfi_offset w21, -48
407 ; Check correct access to arguments passed on the stack, through frame pointer
408 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
409 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
410 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
411 ; and set-up of base pointer (x19).
414 ; CHECK: lsl x9, x9, #2
415 ; CHECK: add x9, x9, #15
416 ; CHECK: and x9, x9, #0x7fffffff0
417 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
418 ; CHECK: mov sp, x[[VLASPTMP]]
419 ; Check correct access to local variable, through base pointer
420 ; CHECK: ldr w[[ILOC:[0-9]+]], [x19]
421 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
423 ; Check that stack pointer get restored from frame pointer.
424 ; CHECK: sub sp, x29, #32
425 ; CHECK: ldp x29, x30, [sp, #32]
426 ; CHECK: ldp x20, x19, [sp, #16]
427 ; CHECK: ldr x21, [sp], #48
429 ; CHECK: .cfi_endproc
431 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_call:
432 ; CHECK-MACHO: .cfi_startproc
433 ; Check that used callee-saved registers are saved
434 ; CHECK-MACHO: stp x22, x21, [sp, #-48]!
435 ; CHECK-MACHO: stp x20, x19, [sp, #16]
436 ; Check that the frame pointer is created:
437 ; CHECK-MACHO: stp x29, x30, [sp, #32]
438 ; CHECK-MACHO: add x29, sp, #32
439 ; Check that the stack pointer gets re-aligned to 128
440 ; bytes & the base pointer (x19) gets initialized to
441 ; this 128-byte aligned area for local variables &
443 ; CHECK-MACHO: sub x9, sp, #80
444 ; CHECK-MACHO: and sp, x9, #0xffffffffffffff80
445 ; CHECK-MACHO: mov x19, sp
446 ; Check correctness of cfi pseudo-instructions
447 ; CHECK-MACHO: .cfi_def_cfa w29, 16
448 ; CHECK-MACHO: .cfi_offset w30, -8
449 ; CHECK-MACHO: .cfi_offset w29, -16
450 ; CHECK-MACHO: .cfi_offset w19, -24
451 ; CHECK-MACHO: .cfi_offset w20, -32
452 ; CHECK-MACHO: .cfi_offset w21, -40
453 ; CHECK-MACHO: .cfi_offset w22, -48
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 correct reservation of 16-byte aligned VLA (size in w0) on stack
458 ; and set-up of base pointer (x19).
459 ; CHECK-MACHO: mov w9, w0
460 ; CHECK-MACHO: mov x10, sp
461 ; CHECK-MACHO: lsl x9, x9, #2
462 ; CHECK-MACHO: add x9, x9, #15
463 ; CHECK-MACHO: and x9, x9, #0x7fffffff0
464 ; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9
465 ; CHECK-MACHO: mov sp, x[[VLASPTMP]]
466 ; Check correct access to local variable, through base pointer
467 ; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19]
468 ; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
470 ; Check that stack pointer get restored from frame pointer.
471 ; CHECK-MACHO: sub sp, x29, #32
472 ; CHECK-MACHO: ldp x29, x30, [sp, #32]
473 ; CHECK-MACHO: ldp x20, x19, [sp, #16]
474 ; CHECK-MACHO: ldp x22, x21, [sp], #48
476 ; CHECK-MACHO: .cfi_endproc
479 ; Function Attrs: nounwind
480 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 {
482 %l1 = alloca i32, align 128
483 %0 = zext i32 %i1 to i64
484 %vla = alloca i32, i64 %0, align 4
485 %conv = fptosi double %d10 to i32
486 %add = add nsw i32 %conv, %i10
487 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
488 %add1 = add nsw i32 %add, %l1.0.l1.0.
489 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
490 %add2 = add nsw i32 %add1, %1
494 ; CHECK-LABEL: vla_dynamicrealign_nocall
495 ; Check that used callee-saved registers are saved
496 ; CHECK: str x19, [sp, #-32]!
497 ; Check that the frame pointer is created:
498 ; CHECK: stp x29, x30, [sp, #16]
499 ; CHECK: add x29, sp, #16
500 ; Check that the stack pointer gets re-aligned to 128
501 ; bytes & the base pointer (x19) gets initialized to
502 ; this 128-byte aligned area for local variables &
504 ; CHECK: sub x9, sp, #96
505 ; CHECK: and sp, x9, #0xffffffffffffff80
507 ; Check correct access to arguments passed on the stack, through frame pointer
508 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
509 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
510 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
511 ; and set-up of base pointer (x19).
514 ; CHECK: lsl x9, x9, #2
515 ; CHECK: add x9, x9, #15
516 ; CHECK: and x9, x9, #0x7fffffff0
517 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
518 ; CHECK: mov sp, x[[VLASPTMP]]
519 ; Check correct access to local variable, through base pointer
520 ; CHECK: ldr w[[ILOC:[0-9]+]], [x19]
521 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
523 ; Check that stack pointer get restored from frame pointer.
524 ; CHECK: sub sp, x29, #16
525 ; CHECK: ldp x29, x30, [sp, #16]
526 ; CHECK: ldr x19, [sp], #32
529 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall:
530 ; Check that used callee-saved registers are saved
531 ; CHECK-MACHO: stp x20, x19, [sp, #-32]!
532 ; Check that the frame pointer is created:
533 ; CHECK-MACHO: stp x29, x30, [sp, #16]
534 ; CHECK-MACHO: add x29, sp, #16
535 ; Check that the stack pointer gets re-aligned to 128
536 ; bytes & the base pointer (x19) gets initialized to
537 ; this 128-byte aligned area for local variables &
539 ; CHECK-MACHO: sub x9, sp, #96
540 ; CHECK-MACHO: and sp, x9, #0xffffffffffffff80
541 ; CHECK-MACHO: mov x19, sp
542 ; Check correct access to arguments passed on the stack, through frame pointer
543 ; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20]
544 ; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32]
545 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
546 ; and set-up of base pointer (x19).
547 ; CHECK-MACHO: mov w9, w0
548 ; CHECK-MACHO: mov x10, sp
549 ; CHECK-MACHO: lsl x9, x9, #2
550 ; CHECK-MACHO: add x9, x9, #15
551 ; CHECK-MACHO: and x9, x9, #0x7fffffff0
552 ; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9
553 ; CHECK-MACHO: mov sp, x[[VLASPTMP]]
554 ; Check correct access to local variable, through base pointer
555 ; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19]
556 ; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
558 ; Check that stack pointer get restored from frame pointer.
559 ; CHECK-MACHO: sub sp, x29, #16
560 ; CHECK-MACHO: ldp x29, x30, [sp, #16]
561 ; CHECK-MACHO: ldp x20, x19, [sp], #32
565 ; Function Attrs: nounwind
566 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 {
568 %l1 = alloca i32, align 32768
569 %0 = zext i32 %i1 to i64
570 %vla = alloca i32, i64 %0, align 4
571 %conv = fptosi double %d10 to i32
572 %add = add nsw i32 %conv, %i10
573 %l1.0.l1.0. = load volatile i32, i32* %l1, align 32768
574 %add1 = add nsw i32 %add, %l1.0.l1.0.
575 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
576 %add2 = add nsw i32 %add1, %1
580 ; CHECK-LABEL: vla_dynamicrealign_nocall_large_align
581 ; Check that used callee-saved registers are saved
582 ; CHECK: stp x28, x19, [sp, #-32]!
583 ; Check that the frame pointer is created:
584 ; CHECK: stp x29, x30, [sp, #16]
585 ; CHECK: add x29, sp, #16
586 ; Check that the stack pointer gets re-aligned to 128
587 ; bytes & the base pointer (x19) gets initialized to
588 ; this 128-byte aligned area for local variables &
590 ; CHECK: sub x9, sp, #7, lsl #12
591 ; CHECK: and sp, x9, #0xffffffffffff8000
593 ; Check correct access to arguments passed on the stack, through frame pointer
594 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
595 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
596 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
597 ; and set-up of base pointer (x19).
600 ; CHECK: lsl x9, x9, #2
601 ; CHECK: add x9, x9, #15
602 ; CHECK: and x9, x9, #0x7fffffff0
603 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
604 ; CHECK: mov sp, x[[VLASPTMP]]
605 ; Check correct access to local variable, through base pointer
606 ; CHECK: ldr w[[ILOC:[0-9]+]], [x19]
607 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
609 ; Check that stack pointer get restored from frame pointer.
610 ; CHECK: sub sp, x29, #16
611 ; CHECK: ldp x29, x30, [sp, #16]
612 ; CHECK: ldp x28, x19, [sp], #32
615 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall_large_align:
616 ; Check that used callee-saved registers are saved
617 ; CHECK-MACHO: stp x20, x19, [sp, #-32]!
618 ; Check that the frame pointer is created:
619 ; CHECK-MACHO: stp x29, x30, [sp, #16]
620 ; CHECK-MACHO: add x29, sp, #16
621 ; Check that the stack pointer gets re-aligned to 128
622 ; bytes & the base pointer (x19) gets initialized to
623 ; this 128-byte aligned area for local variables &
625 ; CHECK-MACHO: sub x9, sp, #7, lsl #12
626 ; CHECK-MACHO: and sp, x9, #0xffffffffffff8000
627 ; CHECK-MACHO: mov x19, sp
628 ; Check correct access to arguments passed on the stack, through frame pointer
629 ; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20]
630 ; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32]
631 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
632 ; and set-up of base pointer (x19).
633 ; CHECK-MACHO: mov w9, w0
634 ; CHECK-MACHO: mov x10, sp
635 ; CHECK-MACHO: lsl x9, x9, #2
636 ; CHECK-MACHO: add x9, x9, #15
637 ; CHECK-MACHO: and x9, x9, #0x7fffffff0
638 ; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9
639 ; CHECK-MACHO: mov sp, x[[VLASPTMP]]
640 ; Check correct access to local variable, through base pointer
641 ; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19]
642 ; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
644 ; Check that stack pointer get restored from frame pointer.
645 ; CHECK-MACHO: sub sp, x29, #16
646 ; CHECK-MACHO: ldp x29, x30, [sp, #16]
647 ; CHECK-MACHO: ldp x20, x19, [sp], #32
651 define void @realign_conditional(i1 %b) {
653 br i1 %b, label %bb0, label %bb1
656 %MyAlloca = alloca i8, i64 64, align 32
663 ; CHECK-LABEL: realign_conditional
664 ; No realignment in the prologue.
666 ; CHECK-NOT: 0xffffffffffffffe0
667 ; CHECK: tbz {{.*}} .[[LABEL:.*]]
668 ; Stack is realigned in a non-entry BB.
669 ; CHECK: sub [[REG:x[01-9]+]], sp, #64
670 ; CHECK: and sp, [[REG]], #0xffffffffffffffe0
675 define void @realign_conditional2(i1 %b) {
677 %tmp = alloca i8, i32 16
678 br i1 %b, label %bb0, label %bb1
681 %MyAlloca = alloca i8, i64 64, align 32
688 ; CHECK-LABEL: realign_conditional2
689 ; Extra realignment in the prologue (performance issue).
690 ; CHECK: tbz {{.*}} .[[LABEL:.*]]
691 ; CHECK: sub x9, sp, #32 // =32
692 ; CHECK: and sp, x9, #0xffffffffffffffe0
694 ; Stack is realigned in a non-entry BB.
695 ; CHECK: sub [[REG:x[01-9]+]], sp, #64
696 ; CHECK: and sp, [[REG]], #0xffffffffffffffe0
700 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" }
701 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" }
703 !1 = !{!2, !2, i64 0}
704 !2 = !{!"int", !3, i64 0}
705 !3 = !{!"omnipotent char", !4, i64 0}
706 !4 = !{!"Simple C/C++ TBAA"}