[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / AArch64 / aarch64-dynamic-stack-layout.ll
blob09eb5fe429da8f2cbdd606608ab439fec0cd088f
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, 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
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    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]
112 ;   Check epilogue:
113 ; CHECK: ldp    x19, x30, [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, i32* %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             // =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             // =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, 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
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: 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]
200 ;   Check epilogue:
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
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, i32* %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, 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
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    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
304 ; CHECK: mov    w9, w0
305 ; CHECK: mov     x10, sp
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]]]
315 ;   Check epilogue:
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
320 ; CHECK: ret
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 {
326 entry:
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
336   ret i32 %add2
339 ; CHECK-LABEL: vla_nodynamicrealign_nocall
340 ;   Check that the frame pointer is created:
341 ; CHECK: stp    x29, x30, [sp, #-16]!
342 ; CHECK: mov    x29, sp
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
351 ; CHECK: mov    w9, w0
352 ; CHECK: mov     x10, sp
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]]]
362 ;   Check epilogue:
363 ;     Check that stack pointer get restored from frame pointer.
364 ; CHECK: mov    sp, x29
365 ; CHECK: ldp    x29, x30, [sp], #16
366 ; CHECK: ret
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 {
370 entry:
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
382   ret i32 %add3
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 &
396 ;   spill slots
397 ; CHECK: sub    x9, sp, #80            // =80
398 ; CHECK: and    sp, x9, #0xffffffffffffff80
399 ; CHECK: mov    x19, sp
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).
412 ; CHECK: mov    w9, w0
413 ; CHECK: mov     x10, sp
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]]]
422 ;   Check epilogue:
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
428 ; CHECK: ret
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 &
442 ;   spill slots
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]]]
469 ;   Check epilogue:
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
475 ; CHECK-MACHO: ret
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 {
481 entry:
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
491   ret i32 %add2
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 &
503 ;   spill slots
504 ; CHECK: sub    x9, sp, #96
505 ; CHECK: and    sp, x9, #0xffffffffffffff80
506 ; CHECK: mov    x19, sp
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).
512 ; CHECK: mov    w9, w0
513 ; CHECK: mov     x10, sp
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]]]
522 ;   Check epilogue:
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
527 ; CHECK: ret
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 &
538 ;   spill slots
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]]]
557 ;   Check epilogue:
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
562 ; CHECK-MACHO: ret
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 {
567 entry:
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
577   ret i32 %add2
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 &
589 ;   spill slots
590 ; CHECK: sub    x9, sp, #7, lsl #12
591 ; CHECK: and    sp, x9, #0xffffffffffff8000
592 ; CHECK: mov    x19, sp
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).
598 ; CHECK: mov    w9, w0
599 ; CHECK: mov     x10, sp
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]]]
608 ;   Check epilogue:
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
613 ; CHECK: ret
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 &
624 ;   spill slots
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]]]
643 ;   Check epilogue:
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
648 ; CHECK-MACHO: ret
651 define void @realign_conditional(i1 %b) {
652 entry:
653   br i1 %b, label %bb0, label %bb1
655 bb0:
656   %MyAlloca = alloca i8, i64 64, align 32
657   br label %bb1
659 bb1:
660   ret void
663 ; CHECK-LABEL: realign_conditional
664 ; No realignment in the prologue.
665 ; CHECK-NOT:  and
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
671 ; CHECK:  .[[LABEL]]:
672 ; CHECK:  ret
675 define void @realign_conditional2(i1 %b) {
676 entry:
677   %tmp = alloca i8, i32 16
678   br i1 %b, label %bb0, label %bb1
680 bb0:
681   %MyAlloca = alloca i8, i64 64, align 32
682   br label %bb1
684 bb1:
685   ret void
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
693 ; CHECK:  mov   x19, sp
694 ; Stack is realigned in a non-entry BB.
695 ; CHECK:  sub  [[REG:x[01-9]+]], sp, #64
696 ; CHECK:  and  sp, [[REG]], #0xffffffffffffffe0
697 ; CHECK:  .[[LABEL]]:
698 ; CHECK:  ret
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"}