blob: 73b6801d0d90ccd5df7db876e4212b10e1e228f6 [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 Berry62c1a1e2016-03-02 17:58:31 +0000101; CHECK: stp x19, x30, [sp, #-16]!
102; CHECK: sub sp, 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 Berry62c1a1e2016-03-02 17:58:31 +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
120; CHECK-MACHO: stp x20, x19, [sp, #-32]!
121; Check that the frame pointer is created:
122; CHECK-MACHO: stp x29, x30, [sp, #16]
123; CHECK-MACHO: add x29, sp, #16
124; Check correctness of cfi pseudo-instructions
125; CHECK-MACHO: .cfi_def_cfa w29, 16
126; CHECK-MACHO: .cfi_offset w30, -8
127; CHECK-MACHO: .cfi_offset w29, -16
128; CHECK-MACHO: .cfi_offset w19, -24
129; CHECK-MACHO: .cfi_offset w20, -32
130; Check correct access to arguments passed on the stack, through frame pointer
131; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32]
132; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20]
133; Check correct access to local variable on the stack, through stack pointer
134; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [sp, #12]
135; Check epilogue:
136; CHECK-MACHO: ldp x29, x30, [sp, #16]
137; CHECK-MACHO: ldp x20, x19, [sp], #32
138; CHECK-MACHO: ret
139; CHECK-MACHO: .cfi_endproc
140
Kristof Beyls17cb8982015-04-09 08:49:47 +0000141
142declare i32 @g() #0
143
144; Function Attrs: nounwind
145define 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 {
146entry:
147 %l1 = alloca i32, align 4
148 %conv = fptosi double %d10 to i32
149 %add = add nsw i32 %conv, %i10
150 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
151 %add1 = add nsw i32 %add, %l1.0.l1.0.
152 ret i32 %add1
153}
154; CHECK-LABEL: novla_nodynamicrealign_nocall
155; Check that space is reserved for one local variable on the stack.
156; CHECK: sub sp, sp, #16 // =16
157; Check correct access to arguments passed on the stack, through stack pointer
158; CHECK: ldr d[[DARG:[0-9]+]], [sp, #40]
159; CHECK: ldr w[[IARG:[0-9]+]], [sp, #24]
160; Check correct access to local variable on the stack, through stack pointer
161; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12]
162; Check epilogue:
163; CHECK: add sp, sp, #16 // =16
164; CHECK: ret
165
166
167define 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 {
168entry:
169 %l1 = alloca i32, align 128
170 %conv = fptosi double %d10 to i32
171 %add = add nsw i32 %conv, %i10
172 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
173 %add1 = add nsw i32 %add, %l1.0.l1.0.
174 %call = tail call i32 @g()
175 %add2 = add nsw i32 %add1, %call
176 ret i32 %add2
177}
178
179; CHECK-LABEL: novla_dynamicrealign_call
180; CHECK: .cfi_startproc
181; Check that used callee-saved registers are saved
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000182; CHECK: str x19, [sp, #-32]!
Kristof Beyls17cb8982015-04-09 08:49:47 +0000183; Check that the frame pointer is created:
184; CHECK: stp x29, x30, [sp, #16]
185; CHECK: add x29, sp, #16
186; Check the dynamic realignment of the stack pointer to a 128-byte boundary
187; CHECK: sub x9, sp, #96
188; CHECK: and sp, x9, #0xffffffffffffff80
189; Check correctness of cfi pseudo-instructions
190; CHECK: .cfi_def_cfa w29, 16
191; CHECK: .cfi_offset w30, -8
192; CHECK: .cfi_offset w29, -16
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000193; CHECK: .cfi_offset w19, -32
Kristof Beyls17cb8982015-04-09 08:49:47 +0000194; Check correct access to arguments passed on the stack, through frame pointer
195; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
196; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
197; Check correct access to local variable on the stack, through re-aligned stack pointer
198; CHECK: ldr w[[ILOC:[0-9]+]], [sp]
199; Check epilogue:
200; Check that stack pointer get restored from frame pointer.
201; CHECK: sub sp, x29, #16 // =16
202; CHECK: ldp x29, x30, [sp, #16]
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000203; CHECK: ldr x19, [sp], #32
Kristof Beyls17cb8982015-04-09 08:49:47 +0000204; CHECK: ret
205; CHECK: .cfi_endproc
206
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000207; CHECK-MACHO-LABEL: _novla_dynamicrealign_call:
208; CHECK-MACHO: .cfi_startproc
209; Check that used callee-saved registers are saved
210; CHECK-MACHO: stp x20, x19, [sp, #-32]!
211; Check that the frame pointer is created:
212; CHECK-MACHO: stp x29, x30, [sp, #16]
213; CHECK-MACHO: add x29, sp, #16
214; Check the dynamic realignment of the stack pointer to a 128-byte boundary
215; CHECK-MACHO: sub x9, sp, #96
216; CHECK-MACHO: and sp, x9, #0xffffffffffffff80
217; Check correctness of cfi pseudo-instructions
218; CHECK-MACHO: .cfi_def_cfa w29, 16
219; CHECK-MACHO: .cfi_offset w30, -8
220; CHECK-MACHO: .cfi_offset w29, -16
221; CHECK-MACHO: .cfi_offset w19, -24
222; CHECK-MACHO: .cfi_offset w20, -32
223; Check correct access to arguments passed on the stack, through frame pointer
224; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32]
225; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20]
226; Check correct access to local variable on the stack, through re-aligned stack pointer
227; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [sp]
228; Check epilogue:
229; Check that stack pointer get restored from frame pointer.
230; CHECK-MACHO: sub sp, x29, #16
231; CHECK-MACHO: ldp x29, x30, [sp, #16]
232; CHECK-MACHO: ldp x20, x19, [sp], #32
233; CHECK-MACHO: ret
234; CHECK-MACHO: .cfi_endproc
235
Kristof Beyls17cb8982015-04-09 08:49:47 +0000236
237; Function Attrs: nounwind
238define 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 {
239entry:
240 %l1 = alloca i32, align 128
241 %conv = fptosi double %d10 to i32
242 %add = add nsw i32 %conv, %i10
243 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
244 %add1 = add nsw i32 %add, %l1.0.l1.0.
245 ret i32 %add1
246}
247
248; CHECK-LABEL: novla_dynamicrealign_nocall
249; Check that the frame pointer is created:
250; CHECK: stp x29, x30, [sp, #-16]!
251; CHECK: mov x29, sp
252; Check the dynamic realignment of the stack pointer to a 128-byte boundary
253; CHECK: sub x9, sp, #112
254; CHECK: and sp, x9, #0xffffffffffffff80
255; Check correct access to arguments passed on the stack, through frame pointer
256; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
257; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
258; Check correct access to local variable on the stack, through re-aligned stack pointer
259; CHECK: ldr w[[ILOC:[0-9]+]], [sp]
260; Check epilogue:
261; Check that stack pointer get restored from frame pointer.
262; CHECK: mov sp, x29
263; CHECK: ldp x29, x30, [sp], #16
264; CHECK: ret
265
266
267define 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 {
268entry:
269 %l1 = alloca i32, align 4
270 %0 = zext i32 %i1 to i64
271 %vla = alloca i32, i64 %0, align 4
272 %conv = fptosi double %d10 to i32
273 %add = add nsw i32 %conv, %i10
274 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
275 %add1 = add nsw i32 %add, %l1.0.l1.0.
276 %call = tail call i32 @g()
277 %add2 = add nsw i32 %add1, %call
278 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
279 %add3 = add nsw i32 %add2, %1
280 ret i32 %add3
281}
282
283; CHECK-LABEL: vla_nodynamicrealign_call
284; CHECK: .cfi_startproc
285; Check that used callee-saved registers are saved
286; CHECK: stp x20, x19, [sp, #-32]!
287; Check that the frame pointer is created:
288; CHECK: stp x29, x30, [sp, #16]
289; CHECK: add x29, sp, #16
290; Check that space is reserved on the stack for the local variable,
291; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned.
292; CHECK: sub sp, sp, #16
293; Check correctness of cfi pseudo-instructions
294; CHECK: .cfi_def_cfa w29, 16
295; CHECK: .cfi_offset w30, -8
296; CHECK: .cfi_offset w29, -16
297; CHECK: .cfi_offset w19, -24
298; CHECK: .cfi_offset w20, -32
299; Check correct access to arguments passed on the stack, through frame pointer
300; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
301; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
302; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
Tim Northover2a9d8012015-07-29 21:34:32 +0000303; CHECK: mov w9, w0
304; CHECK: mov x10, sp
Kristof Beyls17cb8982015-04-09 08:49:47 +0000305; CHECK: lsl x9, x9, #2
306; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000307; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000308; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
309; CHECK: mov sp, x[[VLASPTMP]]
310; Check correct access to local variable, through frame pointer
311; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-20]
312; Check correct accessing of the VLA variable through the base pointer
313; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
314; Check epilogue:
315; Check that stack pointer get restored from frame pointer.
316; CHECK: sub sp, x29, #16 // =16
317; CHECK: ldp x29, x30, [sp, #16]
318; CHECK: ldp x20, x19, [sp], #32
319; CHECK: ret
320; CHECK: .cfi_endproc
321
322
323; Function Attrs: nounwind
324define 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 {
325entry:
326 %l1 = alloca i32, align 4
327 %0 = zext i32 %i1 to i64
328 %vla = alloca i32, i64 %0, align 4
329 %conv = fptosi double %d10 to i32
330 %add = add nsw i32 %conv, %i10
331 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4
332 %add1 = add nsw i32 %add, %l1.0.l1.0.
333 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
334 %add2 = add nsw i32 %add1, %1
335 ret i32 %add2
336}
337
338; CHECK-LABEL: vla_nodynamicrealign_nocall
339; Check that the frame pointer is created:
340; CHECK: stp x29, x30, [sp, #-16]!
341; CHECK: mov x29, sp
342; Check that space is reserved on the stack for the local variable,
343; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned.
344; CHECK: sub sp, sp, #16
345; Check correctness of cfi pseudo-instructions
346; Check correct access to arguments passed on the stack, through frame pointer
347; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
348; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
349; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
Tim Northover2a9d8012015-07-29 21:34:32 +0000350; CHECK: mov w9, w0
351; CHECK: mov x10, sp
Kristof Beyls17cb8982015-04-09 08:49:47 +0000352; CHECK: lsl x9, x9, #2
353; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000354; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000355; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
356; CHECK: mov sp, x[[VLASPTMP]]
357; Check correct access to local variable, through frame pointer
358; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-4]
359; Check correct accessing of the VLA variable through the base pointer
360; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
361; Check epilogue:
362; Check that stack pointer get restored from frame pointer.
363; CHECK: mov sp, x29
364; CHECK: ldp x29, x30, [sp], #16
365; CHECK: ret
366
367
368define 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 {
369entry:
370 %l1 = alloca i32, align 128
371 %0 = zext i32 %i1 to i64
372 %vla = alloca i32, i64 %0, align 4
373 %conv = fptosi double %d10 to i32
374 %add = add nsw i32 %conv, %i10
375 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
376 %add1 = add nsw i32 %add, %l1.0.l1.0.
377 %call = tail call i32 @g()
378 %add2 = add nsw i32 %add1, %call
379 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
380 %add3 = add nsw i32 %add2, %1
381 ret i32 %add3
382}
383
384; CHECK-LABEL: vla_dynamicrealign_call
385; CHECK: .cfi_startproc
386; Check that used callee-saved registers are saved
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000387; CHECK: str x21, [sp, #-48]!
Kristof Beyls17cb8982015-04-09 08:49:47 +0000388; CHECK: stp x20, x19, [sp, #16]
389; Check that the frame pointer is created:
390; CHECK: stp x29, x30, [sp, #32]
391; CHECK: add x29, sp, #32
392; Check that the stack pointer gets re-aligned to 128
393; bytes & the base pointer (x19) gets initialized to
394; this 128-byte aligned area for local variables &
395; spill slots
396; CHECK: sub x9, sp, #80 // =80
397; CHECK: and sp, x9, #0xffffffffffffff80
398; CHECK: mov x19, sp
399; Check correctness of cfi pseudo-instructions
400; CHECK: .cfi_def_cfa w29, 16
401; CHECK: .cfi_offset w30, -8
402; CHECK: .cfi_offset w29, -16
403; CHECK: .cfi_offset w19, -24
404; CHECK: .cfi_offset w20, -32
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000405; CHECK: .cfi_offset w21, -48
Kristof Beyls17cb8982015-04-09 08:49:47 +0000406; Check correct access to arguments passed on the stack, through frame pointer
407; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
408; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
409; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
410; and set-up of base pointer (x19).
Tim Northover2a9d8012015-07-29 21:34:32 +0000411; CHECK: mov w9, w0
412; CHECK: mov x10, sp
Kristof Beyls17cb8982015-04-09 08:49:47 +0000413; CHECK: lsl x9, x9, #2
414; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000415; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000416; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
417; CHECK: mov sp, x[[VLASPTMP]]
418; Check correct access to local variable, through base pointer
419; CHECK: ldr w[[ILOC:[0-9]+]], [x19]
420; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
421; Check epilogue:
422; Check that stack pointer get restored from frame pointer.
423; CHECK: sub sp, x29, #32
424; CHECK: ldp x29, x30, [sp, #32]
425; CHECK: ldp x20, x19, [sp, #16]
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000426; CHECK: ldr x21, [sp], #48
Kristof Beyls17cb8982015-04-09 08:49:47 +0000427; CHECK: ret
428; CHECK: .cfi_endproc
429
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000430; CHECK-MACHO-LABEL: _vla_dynamicrealign_call:
431; CHECK-MACHO: .cfi_startproc
432; Check that used callee-saved registers are saved
433; CHECK-MACHO: stp x22, x21, [sp, #-48]!
434; CHECK-MACHO: stp x20, x19, [sp, #16]
435; Check that the frame pointer is created:
436; CHECK-MACHO: stp x29, x30, [sp, #32]
437; CHECK-MACHO: add x29, sp, #32
438; Check that the stack pointer gets re-aligned to 128
439; bytes & the base pointer (x19) gets initialized to
440; this 128-byte aligned area for local variables &
441; spill slots
442; CHECK-MACHO: sub x9, sp, #80
443; CHECK-MACHO: and sp, x9, #0xffffffffffffff80
444; CHECK-MACHO: mov x19, sp
445; Check correctness of cfi pseudo-instructions
446; CHECK-MACHO: .cfi_def_cfa w29, 16
447; CHECK-MACHO: .cfi_offset w30, -8
448; CHECK-MACHO: .cfi_offset w29, -16
449; CHECK-MACHO: .cfi_offset w19, -24
450; CHECK-MACHO: .cfi_offset w20, -32
451; CHECK-MACHO: .cfi_offset w21, -40
452; CHECK-MACHO: .cfi_offset w22, -48
453; Check correct access to arguments passed on the stack, through frame pointer
454; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20]
455; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32]
456; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
457; and set-up of base pointer (x19).
458; CHECK-MACHO: mov w9, w0
459; CHECK-MACHO: mov x10, sp
460; CHECK-MACHO: lsl x9, x9, #2
461; CHECK-MACHO: add x9, x9, #15
462; CHECK-MACHO: and x9, x9, #0x7fffffff0
463; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9
464; CHECK-MACHO: mov sp, x[[VLASPTMP]]
465; Check correct access to local variable, through base pointer
466; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19]
467; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
468; Check epilogue:
469; Check that stack pointer get restored from frame pointer.
470; CHECK-MACHO: sub sp, x29, #32
471; CHECK-MACHO: ldp x29, x30, [sp, #32]
472; CHECK-MACHO: ldp x20, x19, [sp, #16]
473; CHECK-MACHO: ldp x22, x21, [sp], #48
474; CHECK-MACHO: ret
475; CHECK-MACHO: .cfi_endproc
476
Kristof Beyls17cb8982015-04-09 08:49:47 +0000477
478; Function Attrs: nounwind
479define 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 {
480entry:
481 %l1 = alloca i32, align 128
482 %0 = zext i32 %i1 to i64
483 %vla = alloca i32, i64 %0, align 4
484 %conv = fptosi double %d10 to i32
485 %add = add nsw i32 %conv, %i10
486 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128
487 %add1 = add nsw i32 %add, %l1.0.l1.0.
488 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
489 %add2 = add nsw i32 %add1, %1
490 ret i32 %add2
491}
492
493; CHECK-LABEL: vla_dynamicrealign_nocall
494; Check that used callee-saved registers are saved
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000495; CHECK: str x19, [sp, #-32]!
Kristof Beyls17cb8982015-04-09 08:49:47 +0000496; Check that the frame pointer is created:
497; CHECK: stp x29, x30, [sp, #16]
498; CHECK: add x29, sp, #16
499; Check that the stack pointer gets re-aligned to 128
500; bytes & the base pointer (x19) gets initialized to
501; this 128-byte aligned area for local variables &
502; spill slots
503; CHECK: sub x9, sp, #96
504; CHECK: and sp, x9, #0xffffffffffffff80
505; CHECK: mov x19, sp
506; Check correct access to arguments passed on the stack, through frame pointer
507; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
508; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
509; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
510; and set-up of base pointer (x19).
Tim Northover2a9d8012015-07-29 21:34:32 +0000511; CHECK: mov w9, w0
512; CHECK: mov x10, sp
Kristof Beyls17cb8982015-04-09 08:49:47 +0000513; CHECK: lsl x9, x9, #2
514; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000515; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000516; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
517; CHECK: mov sp, x[[VLASPTMP]]
518; Check correct access to local variable, through base pointer
519; CHECK: ldr w[[ILOC:[0-9]+]], [x19]
520; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
521; Check epilogue:
522; Check that stack pointer get restored from frame pointer.
523; CHECK: sub sp, x29, #16
524; CHECK: ldp x29, x30, [sp, #16]
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000525; CHECK: ldr x19, [sp], #32
Kristof Beyls17cb8982015-04-09 08:49:47 +0000526; CHECK: ret
527
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000528; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall:
529; Check that used callee-saved registers are saved
530; CHECK-MACHO: stp x20, x19, [sp, #-32]!
531; Check that the frame pointer is created:
532; CHECK-MACHO: stp x29, x30, [sp, #16]
533; CHECK-MACHO: add x29, sp, #16
534; Check that the stack pointer gets re-aligned to 128
535; bytes & the base pointer (x19) gets initialized to
536; this 128-byte aligned area for local variables &
537; spill slots
538; CHECK-MACHO: sub x9, sp, #96
539; CHECK-MACHO: and sp, x9, #0xffffffffffffff80
540; CHECK-MACHO: mov x19, sp
541; Check correct access to arguments passed on the stack, through frame pointer
542; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20]
543; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32]
544; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
545; and set-up of base pointer (x19).
546; CHECK-MACHO: mov w9, w0
547; CHECK-MACHO: mov x10, sp
548; CHECK-MACHO: lsl x9, x9, #2
549; CHECK-MACHO: add x9, x9, #15
550; CHECK-MACHO: and x9, x9, #0x7fffffff0
551; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9
552; CHECK-MACHO: mov sp, x[[VLASPTMP]]
553; Check correct access to local variable, through base pointer
554; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19]
555; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
556; Check epilogue:
557; Check that stack pointer get restored from frame pointer.
558; CHECK-MACHO: sub sp, x29, #16
559; CHECK-MACHO: ldp x29, x30, [sp, #16]
560; CHECK-MACHO: ldp x20, x19, [sp], #32
561; CHECK-MACHO: ret
562
Kristof Beyls17cb8982015-04-09 08:49:47 +0000563
564; Function Attrs: nounwind
565define 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 {
566entry:
567 %l1 = alloca i32, align 32768
568 %0 = zext i32 %i1 to i64
569 %vla = alloca i32, i64 %0, align 4
570 %conv = fptosi double %d10 to i32
571 %add = add nsw i32 %conv, %i10
572 %l1.0.l1.0. = load volatile i32, i32* %l1, align 32768
573 %add1 = add nsw i32 %add, %l1.0.l1.0.
574 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1
575 %add2 = add nsw i32 %add1, %1
576 ret i32 %add2
577}
578
579; CHECK-LABEL: vla_dynamicrealign_nocall_large_align
580; Check that used callee-saved registers are saved
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000581; CHECK: stp x28, x19, [sp, #-32]!
Kristof Beyls17cb8982015-04-09 08:49:47 +0000582; Check that the frame pointer is created:
583; CHECK: stp x29, x30, [sp, #16]
584; CHECK: add x29, sp, #16
585; Check that the stack pointer gets re-aligned to 128
586; bytes & the base pointer (x19) gets initialized to
587; this 128-byte aligned area for local variables &
588; spill slots
589; CHECK: sub x9, sp, #7, lsl #12
590; CHECK: and sp, x9, #0xffffffffffff8000
591; CHECK: mov x19, sp
592; Check correct access to arguments passed on the stack, through frame pointer
593; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]
594; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]
595; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
596; and set-up of base pointer (x19).
Tim Northover2a9d8012015-07-29 21:34:32 +0000597; CHECK: mov w9, w0
598; CHECK: mov x10, sp
Kristof Beyls17cb8982015-04-09 08:49:47 +0000599; CHECK: lsl x9, x9, #2
600; CHECK: add x9, x9, #15
Fiona Glaserb08ae7a2015-07-10 18:29:02 +0000601; CHECK: and x9, x9, #0x7fffffff0
Kristof Beyls17cb8982015-04-09 08:49:47 +0000602; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
603; CHECK: mov sp, x[[VLASPTMP]]
604; Check correct access to local variable, through base pointer
605; CHECK: ldr w[[ILOC:[0-9]+]], [x19]
606; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
607; Check epilogue:
608; Check that stack pointer get restored from frame pointer.
609; CHECK: sub sp, x29, #16
610; CHECK: ldp x29, x30, [sp, #16]
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000611; CHECK: ldp x28, x19, [sp], #32
Kristof Beyls17cb8982015-04-09 08:49:47 +0000612; CHECK: ret
613
Geoff Berryc25d3bd2016-02-12 16:31:41 +0000614; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall_large_align:
615; Check that used callee-saved registers are saved
616; CHECK-MACHO: stp x20, x19, [sp, #-32]!
617; Check that the frame pointer is created:
618; CHECK-MACHO: stp x29, x30, [sp, #16]
619; CHECK-MACHO: add x29, sp, #16
620; Check that the stack pointer gets re-aligned to 128
621; bytes & the base pointer (x19) gets initialized to
622; this 128-byte aligned area for local variables &
623; spill slots
624; CHECK-MACHO: sub x9, sp, #7, lsl #12
625; CHECK-MACHO: and sp, x9, #0xffffffffffff8000
626; CHECK-MACHO: mov x19, sp
627; Check correct access to arguments passed on the stack, through frame pointer
628; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20]
629; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32]
630; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
631; and set-up of base pointer (x19).
632; CHECK-MACHO: mov w9, w0
633; CHECK-MACHO: mov x10, sp
634; CHECK-MACHO: lsl x9, x9, #2
635; CHECK-MACHO: add x9, x9, #15
636; CHECK-MACHO: and x9, x9, #0x7fffffff0
637; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9
638; CHECK-MACHO: mov sp, x[[VLASPTMP]]
639; Check correct access to local variable, through base pointer
640; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19]
641; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
642; Check epilogue:
643; Check that stack pointer get restored from frame pointer.
644; CHECK-MACHO: sub sp, x29, #16
645; CHECK-MACHO: ldp x29, x30, [sp, #16]
646; CHECK-MACHO: ldp x20, x19, [sp], #32
647; CHECK-MACHO: ret
648
Evgeniy Stepanov00b30202015-07-10 21:24:07 +0000649
650define void @realign_conditional(i1 %b) {
651entry:
652 br i1 %b, label %bb0, label %bb1
653
654bb0:
655 %MyAlloca = alloca i8, i64 64, align 32
656 br label %bb1
657
658bb1:
659 ret void
660}
661
662; CHECK-LABEL: realign_conditional
663; No realignment in the prologue.
664; CHECK-NOT: and
665; CHECK-NOT: 0xffffffffffffffe0
666; CHECK: tbz {{.*}} .[[LABEL:.*]]
667; Stack is realigned in a non-entry BB.
668; CHECK: sub [[REG:x[01-9]+]], sp, #64
669; CHECK: and sp, [[REG]], #0xffffffffffffffe0
670; CHECK: .[[LABEL]]:
671; CHECK: ret
672
673
674define void @realign_conditional2(i1 %b) {
675entry:
676 %tmp = alloca i8, i32 4
677 br i1 %b, label %bb0, label %bb1
678
679bb0:
680 %MyAlloca = alloca i8, i64 64, align 32
681 br label %bb1
682
683bb1:
684 ret void
685}
686
687; CHECK-LABEL: realign_conditional2
688; Extra realignment in the prologue (performance issue).
Quentin Colombetf6645cc2015-11-18 23:12:20 +0000689; CHECK: tbz {{.*}} .[[LABEL:.*]]
Evgeniy Stepanov00b30202015-07-10 21:24:07 +0000690; CHECK: sub x9, sp, #32 // =32
691; CHECK: and sp, x9, #0xffffffffffffffe0
692; CHECK: mov x19, sp
Evgeniy Stepanov00b30202015-07-10 21:24:07 +0000693; Stack is realigned in a non-entry BB.
694; CHECK: sub [[REG:x[01-9]+]], sp, #64
695; CHECK: and sp, [[REG]], #0xffffffffffffffe0
696; CHECK: .[[LABEL]]:
697; CHECK: ret
698
Geoff Berry62c1a1e2016-03-02 17:58:31 +0000699attributes #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" }
700attributes #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 +0000701
702!1 = !{!2, !2, i64 0}
703!2 = !{!"int", !3, i64 0}
704!3 = !{!"omnipotent char", !4, i64 0}
705!4 = !{!"Simple C/C++ TBAA"}