blob: 739570236da92634d22e4f127db769a9ddfc505b [file] [log] [blame]
Kristof Beyls17cb8982015-04-09 08:49:47 +00001; 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
86define 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 {
87entry:
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
122declare i32 @g() #0
123
124; Function Attrs: nounwind
125define 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 {
126entry:
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
147define 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 {
148entry:
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
190define 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 {
191entry:
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
219define 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 {
220entry:
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: ubfx x9, x0, #0, #32
256; CHECK: lsl x9, x9, #2
257; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000258; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000259; CHECK: mov x10, sp
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
276define 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 {
277entry:
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: ubfx x9, x0, #0, #32
303; CHECK: lsl x9, x9, #2
304; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000305; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000306; CHECK: mov x10, sp
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
320define 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 {
321entry:
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: ubfx x9, x0, #0, #32
365; CHECK: lsl x9, x9, #2
366; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000367; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000368; CHECK: mov x10, sp
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
385define 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 {
386entry:
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: ubfx x9, x0, #0, #32
418; CHECK: lsl x9, x9, #2
419; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000420; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000421; CHECK: mov x10, sp
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
436define 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 {
437entry:
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: ubfx x9, x0, #0, #32
469; CHECK: lsl x9, x9, #2
470; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000471; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000472; CHECK: mov x10, sp
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
Evgeniy Stepanov00b30202015-07-10 21:24:07 +0000485
486define void @realign_conditional(i1 %b) {
487entry:
488 br i1 %b, label %bb0, label %bb1
489
490bb0:
491 %MyAlloca = alloca i8, i64 64, align 32
492 br label %bb1
493
494bb1:
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
510define void @realign_conditional2(i1 %b) {
511entry:
512 %tmp = alloca i8, i32 4
513 br i1 %b, label %bb0, label %bb1
514
515bb0:
516 %MyAlloca = alloca i8, i64 64, align 32
517 br label %bb1
518
519bb1:
520 ret void
521}
522
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
527; CHECK: mov x19, sp
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
532; CHECK: .[[LABEL]]:
533; CHECK: ret
534
Kristof Beyls17cb8982015-04-09 08:49:47 +0000535attributes #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" }
536attributes #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"}