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, 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
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]
113 ; CHECK: ldp x30, x19, [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, ptr %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
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
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, 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
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]
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]
201 ; Check that stack pointer get restored from frame pointer.
203 ; CHECK: ldr x19, [sp, #16]
204 ; CHECK: ldp x29, x30, [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, ptr %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, 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
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]
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
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]]]
315 ; Check that stack pointer get restored from frame pointer.
317 ; CHECK: ldp x20, x19, [sp, #16]
318 ; CHECK: ldp x29, x30, [sp], #32
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 {
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
338 ; CHECK-LABEL: vla_nodynamicrealign_nocall
339 ; Check that the frame pointer is created:
340 ; CHECK: stp x29, x30, [sp, #-16]!
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
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]]]
361 ; Check that stack pointer get restored from frame pointer.
363 ; CHECK: ldp x29, x30, [sp], #16
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 {
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
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:
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 &
395 ; CHECK: sub x9, sp, #80
396 ; CHECK: and sp, x9, #0xffffffffffffff80
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
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]]]
420 ; Check that stack pointer get restored from frame pointer.
422 ; CHECK: ldp x20, x19, [sp, #32]
423 ; CHECK: ldr x21, [sp, #16]
424 ; CHECK: ldp x29, x30, [sp], #48
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 &
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]]]
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
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 {
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
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:
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 &
500 ; CHECK: sub x9, sp, #96
501 ; CHECK: and sp, x9, #0xffffffffffffff80
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
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]]]
518 ; Check that stack pointer get restored from frame pointer.
520 ; CHECK: ldr x19, [sp, #16]
521 ; CHECK: ldp x29, x30, [sp], #32
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 &
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]]]
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
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 {
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
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:
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 &
584 ; CHECK: sub x9, sp, #7, lsl #12
585 ; CHECK: and sp, x9, #0xffffffffffff8000
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
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]]]
602 ; Check that stack pointer get restored from frame pointer.
604 ; CHECK: ldr x19, [sp, #16]
605 ; CHECK: ldp x29, x30, [sp], #32
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 &
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]]]
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
642 declare void @use(ptr)
644 define void @realign_conditional(i1 %b, ptr %p) {
646 br i1 %b, label %bb0, label %bb1
649 %MyAlloca = alloca i8, i64 64, align 32
650 store ptr %MyAlloca, ptr %p
657 ; CHECK-LABEL: realign_conditional
658 ; No realignment in the prologue.
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]]
670 define void @realign_conditional2(i1 %b, ptr %p) {
672 %tmp = alloca i8, i32 16
673 br i1 %b, label %bb0, label %bb1
676 %MyAlloca = alloca i8, i64 64, align 32
677 store ptr %MyAlloca, ptr %p
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
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]]
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"}