Revert "[AArch64] Add DAG combine for extract extend pattern"
[oota-llvm.git] / test / CodeGen / AArch64 / aarch64-dynamic-stack-layout.ll
1 ; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s
2
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
6 ; of:
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
12 ; frame (bp,sp,fp).
13 ;
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
18 ;   correctly
19 ;
20 ; The LLVM-IR below was produced by clang on the following C++ code:
21 ;extern "C" int g();
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)
24 ;{
25 ;  // use an argument passed on the stack.
26 ;  volatile int l1;
27 ;  return i10 + (int)d10 + l1 + g();
28 ;}
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)
31 ;{
32 ;  // use an argument passed on the stack.
33 ;  volatile int l1;
34 ;  return i10 + (int)d10 + l1;
35 ;}
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)
38 ;{
39 ;  // use an argument passed on the stack.
40 ;  alignas(128) volatile int l1;
41 ;  return i10 + (int)d10 + l1 + g();
42 ;}
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)
45 ;{
46 ;  // use an argument passed on the stack.
47 ;  alignas(128) volatile int l1;
48 ;  return i10 + (int)d10 + l1;
49 ;}
50 ;
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)
53 ;{
54 ;  // use an argument passed on the stack.
55 ;  volatile int l1;
56 ;  volatile int vla[i1];
57 ;  return i10 + (int)d10 + l1 + g() + vla[0];
58 ;}
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)
61 ;{
62 ;  // use an argument passed on the stack.
63 ;  volatile int l1;
64 ;  volatile int vla[i1];
65 ;  return i10 + (int)d10 + l1 + vla[0];
66 ;}
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)
69 ;{
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];
74 ;}
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)
77 ;{
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];
82 ;}
83
84
85
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 {
87 entry:
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
95   ret i32 %add2
96 }
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]
115 ;   Check epilogue:
116 ; CHECK: ldp    x29, x30, [sp, #16]
117 ; CHECK: ldp    x20, x19, [sp], #32
118 ; CHECK: ret
119 ; CHECK: .cfi_endproc
120
121
122 declare i32 @g() #0
123
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 {
126 entry:
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.
132   ret i32 %add1
133 }
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]
142 ;   Check epilogue:
143 ; CHECK: add    sp, sp, #16             // =16
144 ; CHECK: ret
145
146
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 {
148 entry:
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
156   ret i32 %add2
157 }
158
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]
180 ;   Check epilogue:
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
185 ; CHECK: ret
186 ; CHECK: .cfi_endproc
187
188
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 {
191 entry:
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.
197   ret i32 %add1
198 }
199
200 ; CHECK-LABEL: novla_dynamicrealign_nocall
201 ;   Check that the frame pointer is created:
202 ; CHECK: stp    x29, x30, [sp, #-16]!
203 ; CHECK: mov    x29, sp
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]
212 ;   Check epilogue:
213 ;     Check that stack pointer get restored from frame pointer.
214 ; CHECK: mov    sp, x29
215 ; CHECK: ldp    x29, x30, [sp], #16
216 ; CHECK: ret
217
218
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 {
220 entry:
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
232   ret i32 %add3
233 }
234
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
255 ; CHECK: mov    w9, w0
256 ; CHECK: mov     x10, sp
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]]]
266 ;   Check epilogue:
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
271 ; CHECK: ret
272 ; CHECK: .cfi_endproc
273
274
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 {
277 entry:
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
287   ret i32 %add2
288 }
289
290 ; CHECK-LABEL: vla_nodynamicrealign_nocall
291 ;   Check that the frame pointer is created:
292 ; CHECK: stp    x29, x30, [sp, #-16]!
293 ; CHECK: mov    x29, sp
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
302 ; CHECK: mov    w9, w0
303 ; CHECK: mov     x10, sp
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]]]
313 ;   Check epilogue:
314 ;     Check that stack pointer get restored from frame pointer.
315 ; CHECK: mov    sp, x29
316 ; CHECK: ldp    x29, x30, [sp], #16
317 ; CHECK: ret
318
319
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 {
321 entry:
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
333   ret i32 %add3
334 }
335
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 &
347 ;   spill slots
348 ; CHECK: sub    x9, sp, #80            // =80
349 ; CHECK: and    sp, x9, #0xffffffffffffff80
350 ; CHECK: mov    x19, sp
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).
364 ; CHECK: mov    w9, w0
365 ; CHECK: mov     x10, sp
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]]]
374 ;   Check epilogue:
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
380 ; CHECK: ret
381 ; CHECK: .cfi_endproc
382
383
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 {
386 entry:
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
396   ret i32 %add2
397 }
398
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 &
408 ;   spill slots
409 ; CHECK: sub    x9, sp, #96
410 ; CHECK: and    sp, x9, #0xffffffffffffff80
411 ; CHECK: mov    x19, sp
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).
417 ; CHECK: mov    w9, w0
418 ; CHECK: mov     x10, sp
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]]]
427 ;   Check epilogue:
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
432 ; CHECK: ret
433
434
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 {
437 entry:
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
447   ret i32 %add2
448 }
449
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 &
459 ;   spill slots
460 ; CHECK: sub    x9, sp, #7, lsl #12
461 ; CHECK: and    sp, x9, #0xffffffffffff8000
462 ; CHECK: mov    x19, sp
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).
468 ; CHECK: mov    w9, w0
469 ; CHECK: mov     x10, sp
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]]]
478 ;   Check epilogue:
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
483 ; CHECK: ret
484
485
486 define void @realign_conditional(i1 %b) {
487 entry:
488   br i1 %b, label %bb0, label %bb1
489
490 bb0:
491   %MyAlloca = alloca i8, i64 64, align 32
492   br label %bb1
493
494 bb1:
495   ret void
496 }
497
498 ; CHECK-LABEL: realign_conditional
499 ; No realignment in the prologue.
500 ; CHECK-NOT:  and
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
506 ; CHECK:  .[[LABEL]]:
507 ; CHECK:  ret
508
509
510 define void @realign_conditional2(i1 %b) {
511 entry:
512   %tmp = alloca i8, i32 4
513   br i1 %b, label %bb0, label %bb1
514
515 bb0:
516   %MyAlloca = alloca i8, i64 64, align 32
517   br label %bb1
518
519 bb1:
520   ret void
521 }
522
523 ; CHECK-LABEL: realign_conditional2
524 ; Extra realignment in the prologue (performance issue).
525 ; CHECK:  tbz  {{.*}} .[[LABEL:.*]]
526 ; CHECK:  sub  x9, sp, #32            // =32
527 ; CHECK:  and  sp, x9, #0xffffffffffffffe0
528 ; CHECK:  mov   x19, sp
529 ; Stack is realigned in a non-entry BB.
530 ; CHECK:  sub  [[REG:x[01-9]+]], sp, #64
531 ; CHECK:  and  sp, [[REG]], #0xffffffffffffffe0
532 ; CHECK:  .[[LABEL]]:
533 ; CHECK:  ret
534
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" }
537
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"}