blob: 708ae083eb865be6caf4a2baa6c45d11f08ae022 [file] [log] [blame]
Chad Rosierd0165742015-12-21 14:43:45 +00001; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -disable-post-ra < %s | FileCheck %s
Geoff Berry62c1a1e2016-03-02 17:58:31 +00002; RUN: llc -verify-machineinstrs -mtriple=arm64-apple-ios -disable-fp-elim -disable-post-ra < %s | FileCheck %s --check-prefix=CHECK-MACHO
Kristof Beyls17cb8982015-04-09 08:49:47 +00003
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).
14;
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
20;
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)
25;{
26; // use an argument passed on the stack.
27; volatile int l1;
28; return i10 + (int)d10 + l1 + g();
29;}
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)
32;{
33; // use an argument passed on the stack.
34; volatile int l1;
35; return i10 + (int)d10 + l1;
36;}
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)
39;{
40; // use an argument passed on the stack.
41; alignas(128) volatile int l1;
42; return i10 + (int)d10 + l1 + g();
43;}
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)
46;{
47; // use an argument passed on the stack.
48; alignas(128) volatile int l1;
49; return i10 + (int)d10 + l1;
50;}
51;
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)
54;{
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];
59;}
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)
62;{
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];
67;}
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)
70;{
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];
75;}
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)
78;{
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];
83;}
84
85
86
87define 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 {
88entry:
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
97}
98; CHECK-LABEL: novla_nodynamicrealign_call
99; CHECK: .cfi_startproc
100; Check that used callee-saved registers are saved
Geoff Berrya5335642016-05-06 16:34:59 +0000101; CHECK: sub sp, sp, #32
102; CHECK: stp x19, x30, [sp, #16]
Kristof Beyls17cb8982015-04-09 08:49:47 +0000103; Check correctness of cfi pseudo-instructions
Geoff Berry62c1a1e2016-03-02 17:58:31 +0000104; CHECK: .cfi_def_cfa_offset 32
Kristof Beyls17cb8982015-04-09 08:49:47 +0000105; CHECK: .cfi_offset w30, -8
Geoff Berry62c1a1e2016-03-02 17:58:31 +0000106; 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]
Kristof Beyls17cb8982015-04-09 08:49:47 +0000110; Check correct access to local variable on the stack, through stack pointer
111; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12]
112; Check epilogue:
Geoff Berrya5335642016-05-06 16:34:59 +0000113; CHECK: ldp x19, x30, [sp, #16]
Kristof Beyls17cb8982015-04-09 08:49:47 +0000114; CHECK: ret
115; CHECK: .cfi_endproc
116
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000117; CHECK-MACHO-LABEL: _novla_nodynamicrealign_call:
118; CHECK-MACHO: .cfi_startproc
119; Check that used callee-saved registers are saved
Geoff Berrya5335642016-05-06 16:34:59 +0000120; CHECK-MACHO: sub sp, sp, #48
121; CHECK-MACHO: stp x20, x19, [sp, #16]
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000122; Check that the frame pointer is created:
Geoff Berrya5335642016-05-06 16:34:59 +0000123; CHECK-MACHO: stp x29, x30, [sp, #32]
124; CHECK-MACHO: add x29, sp, #32
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000125; 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:
Geoff Berrya5335642016-05-06 16:34:59 +0000137; CHECK-MACHO: ldp x29, x30, [sp, #32]
138; CHECK-MACHO: ldp x20, x19, [sp, #16]
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000139; CHECK-MACHO: ret
140; CHECK-MACHO: .cfi_endproc
141
Kristof Beyls17cb8982015-04-09 08:49:47 +0000142
143declare i32 @g() #0
144
145; Function Attrs: nounwind
146define 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 {
147entry:
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
154}
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
166
167
168define 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 {
169entry:
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
178}
179
180; CHECK-LABEL: novla_dynamicrealign_call
181; CHECK: .cfi_startproc
182; Check that used callee-saved registers are saved
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000183; CHECK: str x19, [sp, #-32]!
Kristof Beyls17cb8982015-04-09 08:49:47 +0000184; 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
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000194; CHECK: .cfi_offset w19, -32
Kristof Beyls17cb8982015-04-09 08:49:47 +0000195; 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]
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000204; CHECK: ldr x19, [sp], #32
Kristof Beyls17cb8982015-04-09 08:49:47 +0000205; CHECK: ret
206; CHECK: .cfi_endproc
207
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000208; 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
236
Kristof Beyls17cb8982015-04-09 08:49:47 +0000237
238; Function Attrs: nounwind
239define 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 {
240entry:
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
247}
248
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
266
267
268define 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 {
269entry:
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
282}
283
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
Tim Northover2a9d8012015-07-29 21:34:32 +0000304; CHECK: mov w9, w0
305; CHECK: mov x10, sp
Kristof Beyls17cb8982015-04-09 08:49:47 +0000306; CHECK: lsl x9, x9, #2
307; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000308; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000309; 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
322
323
324; Function Attrs: nounwind
325define 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 {
326entry:
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
337}
338
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
Tim Northover2a9d8012015-07-29 21:34:32 +0000351; CHECK: mov w9, w0
352; CHECK: mov x10, sp
Kristof Beyls17cb8982015-04-09 08:49:47 +0000353; CHECK: lsl x9, x9, #2
354; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000355; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000356; 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
367
368
369define 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 {
370entry:
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
383}
384
385; CHECK-LABEL: vla_dynamicrealign_call
386; CHECK: .cfi_startproc
387; Check that used callee-saved registers are saved
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000388; CHECK: str x21, [sp, #-48]!
Kristof Beyls17cb8982015-04-09 08:49:47 +0000389; 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
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000406; CHECK: .cfi_offset w21, -48
Kristof Beyls17cb8982015-04-09 08:49:47 +0000407; 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).
Tim Northover2a9d8012015-07-29 21:34:32 +0000412; CHECK: mov w9, w0
413; CHECK: mov x10, sp
Kristof Beyls17cb8982015-04-09 08:49:47 +0000414; CHECK: lsl x9, x9, #2
415; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000416; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000417; 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]
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000427; CHECK: ldr x21, [sp], #48
Kristof Beyls17cb8982015-04-09 08:49:47 +0000428; CHECK: ret
429; CHECK: .cfi_endproc
430
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000431; 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
477
Kristof Beyls17cb8982015-04-09 08:49:47 +0000478
479; Function Attrs: nounwind
480define 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 {
481entry:
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
492}
493
494; CHECK-LABEL: vla_dynamicrealign_nocall
495; Check that used callee-saved registers are saved
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000496; CHECK: str x19, [sp, #-32]!
Kristof Beyls17cb8982015-04-09 08:49:47 +0000497; 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).
Tim Northover2a9d8012015-07-29 21:34:32 +0000512; CHECK: mov w9, w0
513; CHECK: mov x10, sp
Kristof Beyls17cb8982015-04-09 08:49:47 +0000514; CHECK: lsl x9, x9, #2
515; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000516; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000517; 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]
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000526; CHECK: ldr x19, [sp], #32
Kristof Beyls17cb8982015-04-09 08:49:47 +0000527; CHECK: ret
528
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000529; 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
563
Kristof Beyls17cb8982015-04-09 08:49:47 +0000564
565; Function Attrs: nounwind
566define 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 {
567entry:
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
578}
579
580; CHECK-LABEL: vla_dynamicrealign_nocall_large_align
581; Check that used callee-saved registers are saved
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000582; CHECK: stp x28, x19, [sp, #-32]!
Kristof Beyls17cb8982015-04-09 08:49:47 +0000583; 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).
Tim Northover2a9d8012015-07-29 21:34:32 +0000598; CHECK: mov w9, w0
599; CHECK: mov x10, sp
Kristof Beyls17cb8982015-04-09 08:49:47 +0000600; CHECK: lsl x9, x9, #2
601; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000602; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000603; 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]
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000612; CHECK: ldp x28, x19, [sp], #32
Kristof Beyls17cb8982015-04-09 08:49:47 +0000613; CHECK: ret
614
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000615; 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
649
Evgeniy Stepanov00b30202015-07-10 21:24:07 +0000650
651define void @realign_conditional(i1 %b) {
652entry:
653 br i1 %b, label %bb0, label %bb1
654
655bb0:
656 %MyAlloca = alloca i8, i64 64, align 32
657 br label %bb1
658
659bb1:
660 ret void
661}
662
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
673
674
675define void @realign_conditional2(i1 %b) {
676entry:
Geoff Berry66f6b652016-06-02 16:22:07 +0000677 %tmp = alloca i8, i32 16
Evgeniy Stepanov00b30202015-07-10 21:24:07 +0000678 br i1 %b, label %bb0, label %bb1
679
680bb0:
681 %MyAlloca = alloca i8, i64 64, align 32
682 br label %bb1
683
684bb1:
685 ret void
686}
687
688; CHECK-LABEL: realign_conditional2
689; Extra realignment in the prologue (performance issue).
Quentin Colombetf6645cc2015-11-18 23:12:20 +0000690; CHECK: tbz {{.*}} .[[LABEL:.*]]
Evgeniy Stepanov00b30202015-07-10 21:24:07 +0000691; CHECK: sub x9, sp, #32 // =32
692; CHECK: and sp, x9, #0xffffffffffffffe0
693; CHECK: mov x19, sp
Evgeniy Stepanov00b30202015-07-10 21:24:07 +0000694; 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
699
Geoff Berry62c1a1e2016-03-02 17:58:31 +0000700attributes #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" }
701attributes #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" }
Kristof Beyls17cb8982015-04-09 08:49:47 +0000702
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"}