1 ; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s
3 ; This test aims to check basic correctness of frame layout &
4 ; frame access code. There are 8 functions in this test file,
5 ; each function implements one element in the cartesian product
7 ; . a function having a VLA/noVLA
8 ; . a function with dynamic stack realignment/no dynamic stack realignment.
9 ; . a function needing a frame pionter/no frame pointer,
10 ; since the presence/absence of these has influence on the frame
11 ; layout and which pointer to use to access various part of the
14 ; Furthermore: in every test function:
15 ; . there is always one integer and 1 floating point argument to be able
16 ; to check those are accessed correctly.
17 ; . there is always one local variable to check that is accessed
20 ; The LLVM-IR below was produced by clang on the following C++ code:
22 ;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,
23 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
25 ; // use an argument passed on the stack.
27 ; return i10 + (int)d10 + l1 + g();
29 ;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,
30 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
32 ; // use an argument passed on the stack.
34 ; return i10 + (int)d10 + l1;
36 ;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,
37 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
39 ; // use an argument passed on the stack.
40 ; alignas(128) volatile int l1;
41 ; return i10 + (int)d10 + l1 + g();
43 ;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,
44 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
46 ; // use an argument passed on the stack.
47 ; alignas(128) volatile int l1;
48 ; return i10 + (int)d10 + l1;
51 ;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,
52 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
54 ; // use an argument passed on the stack.
56 ; volatile int vla[i1];
57 ; return i10 + (int)d10 + l1 + g() + vla[0];
59 ;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,
60 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
62 ; // use an argument passed on the stack.
64 ; volatile int vla[i1];
65 ; return i10 + (int)d10 + l1 + vla[0];
67 ;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,
68 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
70 ; // use an argument passed on the stack.
71 ; alignas(128) volatile int l1;
72 ; volatile int vla[i1];
73 ; return i10 + (int)d10 + l1 + g() + vla[0];
75 ;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,
76 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10)
78 ; // use an argument passed on the stack.
79 ; alignas(128) volatile int l1;
80 ; volatile int vla[i1];
81 ; return i10 + (int)d10 + l1 + vla[0];
86 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 %l1 = alloca i32, align 4
89 %conv = fptosi double %d10 to i32
90 %add = add nsw i32 %conv, %i10
91 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
92 %add1 = add nsw i32 %add, %l1.0.l1.0.
93 %call = tail call i32 @g()
94 %add2 = add nsw i32 %add1, %call
97 ; CHECK-LABEL: novla_nodynamicrealign_call
98 ; CHECK: .cfi_startproc
99 ; Check that used callee-saved registers are saved
100 ; CHECK: stp x20, x19, [sp, #-32]!
101 ; Check that the frame pointer is created:
102 ; CHECK: stp x29, x30, [sp, #16]
103 ; CHECK: add x29, sp, #16
104 ; Check correctness of cfi pseudo-instructions
105 ; CHECK: .cfi_def_cfa w29, 16
106 ; CHECK: .cfi_offset w30, -8
107 ; CHECK: .cfi_offset w29, -16
108 ; CHECK: .cfi_offset w19, -24
109 ; CHECK: .cfi_offset w20, -32
110 ; Check correct access to arguments passed on the stack, through frame pointer
111 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
112 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
113 ; Check correct access to local variable on the stack, through stack pointer
114 ; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12]
116 ; CHECK: ldp x29, x30, [sp, #16]
117 ; CHECK: ldp x20, x19, [sp], #32
119 ; CHECK: .cfi_endproc
124 ; Function Attrs: nounwind
125 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 {
127 %l1 = alloca i32, align 4
128 %conv = fptosi double %d10 to i32
129 %add = add nsw i32 %conv, %i10
130 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
131 %add1 = add nsw i32 %add, %l1.0.l1.0.
134 ; CHECK-LABEL: novla_nodynamicrealign_nocall
135 ; Check that space is reserved for one local variable on the stack.
136 ; CHECK: sub sp, sp, #16 // =16
137 ; Check correct access to arguments passed on the stack, through stack pointer
138 ; CHECK: ldr d[[DARG:[0-9]+]], [sp, #40]
139 ; CHECK: ldr w[[IARG:[0-9]+]], [sp, #24]
140 ; Check correct access to local variable on the stack, through stack pointer
141 ; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12]
143 ; CHECK: add sp, sp, #16 // =16
147 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 {
149 %l1 = alloca i32, align 128
150 %conv = fptosi double %d10 to i32
151 %add = add nsw i32 %conv, %i10
152 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
153 %add1 = add nsw i32 %add, %l1.0.l1.0.
154 %call = tail call i32 @g()
155 %add2 = add nsw i32 %add1, %call
159 ; CHECK-LABEL: novla_dynamicrealign_call
160 ; CHECK: .cfi_startproc
161 ; Check that used callee-saved registers are saved
162 ; CHECK: stp x20, x19, [sp, #-32]!
163 ; Check that the frame pointer is created:
164 ; CHECK: stp x29, x30, [sp, #16]
165 ; CHECK: add x29, sp, #16
166 ; Check the dynamic realignment of the stack pointer to a 128-byte boundary
167 ; CHECK: sub x9, sp, #96
168 ; CHECK: and sp, x9, #0xffffffffffffff80
169 ; Check correctness of cfi pseudo-instructions
170 ; CHECK: .cfi_def_cfa w29, 16
171 ; CHECK: .cfi_offset w30, -8
172 ; CHECK: .cfi_offset w29, -16
173 ; CHECK: .cfi_offset w19, -24
174 ; CHECK: .cfi_offset w20, -32
175 ; Check correct access to arguments passed on the stack, through frame pointer
176 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
177 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
178 ; Check correct access to local variable on the stack, through re-aligned stack pointer
179 ; CHECK: ldr w[[ILOC:[0-9]+]], [sp]
181 ; Check that stack pointer get restored from frame pointer.
182 ; CHECK: sub sp, x29, #16 // =16
183 ; CHECK: ldp x29, x30, [sp, #16]
184 ; CHECK: ldp x20, x19, [sp], #32
186 ; CHECK: .cfi_endproc
189 ; Function Attrs: nounwind
190 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 {
192 %l1 = alloca i32, align 128
193 %conv = fptosi double %d10 to i32
194 %add = add nsw i32 %conv, %i10
195 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
196 %add1 = add nsw i32 %add, %l1.0.l1.0.
200 ; CHECK-LABEL: novla_dynamicrealign_nocall
201 ; Check that the frame pointer is created:
202 ; CHECK: stp x29, x30, [sp, #-16]!
204 ; Check the dynamic realignment of the stack pointer to a 128-byte boundary
205 ; CHECK: sub x9, sp, #112
206 ; CHECK: and sp, x9, #0xffffffffffffff80
207 ; Check correct access to arguments passed on the stack, through frame pointer
208 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
209 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
210 ; Check correct access to local variable on the stack, through re-aligned stack pointer
211 ; CHECK: ldr w[[ILOC:[0-9]+]], [sp]
213 ; Check that stack pointer get restored from frame pointer.
215 ; CHECK: ldp x29, x30, [sp], #16
219 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 {
221 %l1 = alloca i32, align 4
222 %0 = zext i32 %i1 to i64
223 %vla = alloca i32, i64 %0, align 4
224 %conv = fptosi double %d10 to i32
225 %add = add nsw i32 %conv, %i10
226 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
227 %add1 = add nsw i32 %add, %l1.0.l1.0.
228 %call = tail call i32 @g()
229 %add2 = add nsw i32 %add1, %call
230 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
231 %add3 = add nsw i32 %add2, %1
235 ; CHECK-LABEL: vla_nodynamicrealign_call
236 ; CHECK: .cfi_startproc
237 ; Check that used callee-saved registers are saved
238 ; CHECK: stp x20, x19, [sp, #-32]!
239 ; Check that the frame pointer is created:
240 ; CHECK: stp x29, x30, [sp, #16]
241 ; CHECK: add x29, sp, #16
242 ; Check that space is reserved on the stack for the local variable,
243 ; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned.
244 ; CHECK: sub sp, sp, #16
245 ; Check correctness of cfi pseudo-instructions
246 ; CHECK: .cfi_def_cfa w29, 16
247 ; CHECK: .cfi_offset w30, -8
248 ; CHECK: .cfi_offset w29, -16
249 ; CHECK: .cfi_offset w19, -24
250 ; CHECK: .cfi_offset w20, -32
251 ; Check correct access to arguments passed on the stack, through frame pointer
252 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
253 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
254 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
257 ; CHECK: lsl x9, x9, #2
258 ; CHECK: add x9, x9, #15
259 ; CHECK: and x9, x9, #0x7fffffff0
260 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
261 ; CHECK: mov sp, x[[VLASPTMP]]
262 ; Check correct access to local variable, through frame pointer
263 ; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-20]
264 ; Check correct accessing of the VLA variable through the base pointer
265 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
267 ; Check that stack pointer get restored from frame pointer.
268 ; CHECK: sub sp, x29, #16 // =16
269 ; CHECK: ldp x29, x30, [sp, #16]
270 ; CHECK: ldp x20, x19, [sp], #32
272 ; CHECK: .cfi_endproc
275 ; Function Attrs: nounwind
276 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 {
278 %l1 = alloca i32, align 4
279 %0 = zext i32 %i1 to i64
280 %vla = alloca i32, i64 %0, align 4
281 %conv = fptosi double %d10 to i32
282 %add = add nsw i32 %conv, %i10
283 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
284 %add1 = add nsw i32 %add, %l1.0.l1.0.
285 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
286 %add2 = add nsw i32 %add1, %1
290 ; CHECK-LABEL: vla_nodynamicrealign_nocall
291 ; Check that the frame pointer is created:
292 ; CHECK: stp x29, x30, [sp, #-16]!
294 ; Check that space is reserved on the stack for the local variable,
295 ; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned.
296 ; CHECK: sub sp, sp, #16
297 ; Check correctness of cfi pseudo-instructions
298 ; Check correct access to arguments passed on the stack, through frame pointer
299 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
300 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
301 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
304 ; CHECK: lsl x9, x9, #2
305 ; CHECK: add x9, x9, #15
306 ; CHECK: and x9, x9, #0x7fffffff0
307 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
308 ; CHECK: mov sp, x[[VLASPTMP]]
309 ; Check correct access to local variable, through frame pointer
310 ; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-4]
311 ; Check correct accessing of the VLA variable through the base pointer
312 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
314 ; Check that stack pointer get restored from frame pointer.
316 ; CHECK: ldp x29, x30, [sp], #16
320 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 {
322 %l1 = alloca i32, align 128
323 %0 = zext i32 %i1 to i64
324 %vla = alloca i32, i64 %0, align 4
325 %conv = fptosi double %d10 to i32
326 %add = add nsw i32 %conv, %i10
327 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
328 %add1 = add nsw i32 %add, %l1.0.l1.0.
329 %call = tail call i32 @g()
330 %add2 = add nsw i32 %add1, %call
331 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
332 %add3 = add nsw i32 %add2, %1
336 ; CHECK-LABEL: vla_dynamicrealign_call
337 ; CHECK: .cfi_startproc
338 ; Check that used callee-saved registers are saved
339 ; CHECK: stp x22, x21, [sp, #-48]!
340 ; CHECK: stp x20, x19, [sp, #16]
341 ; Check that the frame pointer is created:
342 ; CHECK: stp x29, x30, [sp, #32]
343 ; CHECK: add x29, sp, #32
344 ; Check that the stack pointer gets re-aligned to 128
345 ; bytes & the base pointer (x19) gets initialized to
346 ; this 128-byte aligned area for local variables &
348 ; CHECK: sub x9, sp, #80 // =80
349 ; CHECK: and sp, x9, #0xffffffffffffff80
351 ; Check correctness of cfi pseudo-instructions
352 ; CHECK: .cfi_def_cfa w29, 16
353 ; CHECK: .cfi_offset w30, -8
354 ; CHECK: .cfi_offset w29, -16
355 ; CHECK: .cfi_offset w19, -24
356 ; CHECK: .cfi_offset w20, -32
357 ; CHECK: .cfi_offset w21, -40
358 ; CHECK: .cfi_offset w22, -48
359 ; Check correct access to arguments passed on the stack, through frame pointer
360 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
361 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
362 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
363 ; and set-up of base pointer (x19).
366 ; CHECK: lsl x9, x9, #2
367 ; CHECK: add x9, x9, #15
368 ; CHECK: and x9, x9, #0x7fffffff0
369 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
370 ; CHECK: mov sp, x[[VLASPTMP]]
371 ; Check correct access to local variable, through base pointer
372 ; CHECK: ldr w[[ILOC:[0-9]+]], [x19]
373 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
375 ; Check that stack pointer get restored from frame pointer.
376 ; CHECK: sub sp, x29, #32
377 ; CHECK: ldp x29, x30, [sp, #32]
378 ; CHECK: ldp x20, x19, [sp, #16]
379 ; CHECK: ldp x22, x21, [sp], #48
381 ; CHECK: .cfi_endproc
384 ; Function Attrs: nounwind
385 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 {
387 %l1 = alloca i32, align 128
388 %0 = zext i32 %i1 to i64
389 %vla = alloca i32, i64 %0, align 4
390 %conv = fptosi double %d10 to i32
391 %add = add nsw i32 %conv, %i10
392 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
393 %add1 = add nsw i32 %add, %l1.0.l1.0.
394 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
395 %add2 = add nsw i32 %add1, %1
399 ; CHECK-LABEL: vla_dynamicrealign_nocall
400 ; Check that used callee-saved registers are saved
401 ; CHECK: stp x20, x19, [sp, #-32]!
402 ; Check that the frame pointer is created:
403 ; CHECK: stp x29, x30, [sp, #16]
404 ; CHECK: add x29, sp, #16
405 ; Check that the stack pointer gets re-aligned to 128
406 ; bytes & the base pointer (x19) gets initialized to
407 ; this 128-byte aligned area for local variables &
409 ; CHECK: sub x9, sp, #96
410 ; CHECK: and sp, x9, #0xffffffffffffff80
412 ; Check correct access to arguments passed on the stack, through frame pointer
413 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
414 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
415 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
416 ; and set-up of base pointer (x19).
419 ; CHECK: lsl x9, x9, #2
420 ; CHECK: add x9, x9, #15
421 ; CHECK: and x9, x9, #0x7fffffff0
422 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
423 ; CHECK: mov sp, x[[VLASPTMP]]
424 ; Check correct access to local variable, through base pointer
425 ; CHECK: ldr w[[ILOC:[0-9]+]], [x19]
426 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
428 ; Check that stack pointer get restored from frame pointer.
429 ; CHECK: sub sp, x29, #16
430 ; CHECK: ldp x29, x30, [sp, #16]
431 ; CHECK: ldp x20, x19, [sp], #32
435 ; Function Attrs: nounwind
436 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 {
438 %l1 = alloca i32, align 32768
439 %0 = zext i32 %i1 to i64
440 %vla = alloca i32, i64 %0, align 4
441 %conv = fptosi double %d10 to i32
442 %add = add nsw i32 %conv, %i10
443 %l1.0.l1.0. = load volatile i32, i32* %l1, align 32768
444 %add1 = add nsw i32 %add, %l1.0.l1.0.
445 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
446 %add2 = add nsw i32 %add1, %1
450 ; CHECK-LABEL: vla_dynamicrealign_nocall_large_align
451 ; Check that used callee-saved registers are saved
452 ; CHECK: stp x20, x19, [sp, #-32]!
453 ; Check that the frame pointer is created:
454 ; CHECK: stp x29, x30, [sp, #16]
455 ; CHECK: add x29, sp, #16
456 ; Check that the stack pointer gets re-aligned to 128
457 ; bytes & the base pointer (x19) gets initialized to
458 ; this 128-byte aligned area for local variables &
460 ; CHECK: sub x9, sp, #7, lsl #12
461 ; CHECK: and sp, x9, #0xffffffffffff8000
463 ; Check correct access to arguments passed on the stack, through frame pointer
464 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
465 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
466 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
467 ; and set-up of base pointer (x19).
470 ; CHECK: lsl x9, x9, #2
471 ; CHECK: add x9, x9, #15
472 ; CHECK: and x9, x9, #0x7fffffff0
473 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
474 ; CHECK: mov sp, x[[VLASPTMP]]
475 ; Check correct access to local variable, through base pointer
476 ; CHECK: ldr w[[ILOC:[0-9]+]], [x19]
477 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
479 ; Check that stack pointer get restored from frame pointer.
480 ; CHECK: sub sp, x29, #16
481 ; CHECK: ldp x29, x30, [sp, #16]
482 ; CHECK: ldp x20, x19, [sp], #32
486 define void @realign_conditional(i1 %b) {
488 br i1 %b, label %bb0, label %bb1
491 %MyAlloca = alloca i8, i64 64, align 32
498 ; CHECK-LABEL: realign_conditional
499 ; No realignment in the prologue.
501 ; CHECK-NOT: 0xffffffffffffffe0
502 ; CHECK: tbz {{.*}} .[[LABEL:.*]]
503 ; Stack is realigned in a non-entry BB.
504 ; CHECK: sub [[REG:x[01-9]+]], sp, #64
505 ; CHECK: and sp, [[REG]], #0xffffffffffffffe0
510 define void @realign_conditional2(i1 %b) {
512 %tmp = alloca i8, i32 4
513 br i1 %b, label %bb0, label %bb1
516 %MyAlloca = alloca i8, i64 64, align 32
523 ; CHECK-LABEL: realign_conditional2
524 ; Extra realignment in the prologue (performance issue).
525 ; CHECK: sub x9, sp, #32 // =32
526 ; CHECK: and sp, x9, #0xffffffffffffffe0
528 ; CHECK: tbz {{.*}} .[[LABEL:.*]]
529 ; Stack is realigned in a non-entry BB.
530 ; CHECK: sub [[REG:x[01-9]+]], sp, #64
531 ; CHECK: and sp, [[REG]], #0xffffffffffffffe0
535 attributes #0 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
536 attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
538 !1 = !{!2, !2, i64 0}
539 !2 = !{!"int", !3, i64 0}
540 !3 = !{!"omnipotent char", !4, i64 0}
541 !4 = !{!"Simple C/C++ TBAA"}