xref: /llvm-project/llvm/test/CodeGen/X86/win64_frame.ll (revision 2f448bf509432c1a19ec46ab8cbc7353c03c6280)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-pc-win32              | FileCheck %s
3; RUN: llc < %s -mtriple=x86_64-pc-win32 -mattr=+sahf | FileCheck %s
4
5define i32 @f1(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) "frame-pointer"="all" {
6; CHECK-LABEL: f1:
7; CHECK:       # %bb.0:
8; CHECK-NEXT:    pushq %rbp
9; CHECK-NEXT:    .seh_pushreg %rbp
10; CHECK-NEXT:    movq %rsp, %rbp
11; CHECK-NEXT:    .seh_setframe %rbp, 0
12; CHECK-NEXT:    .seh_endprologue
13; CHECK-NEXT:    movl 48(%rbp), %eax
14; CHECK-NEXT:    popq %rbp
15; CHECK-NEXT:    retq
16; CHECK-NEXT:    .seh_endproc
17  ret i32 %p5
18}
19
20define void @f2(i32 %p, ...) "frame-pointer"="all" {
21; CHECK-LABEL: f2:
22; CHECK:       # %bb.0:
23; CHECK-NEXT:    pushq %rbp
24; CHECK-NEXT:    .seh_pushreg %rbp
25; CHECK-NEXT:    pushq %rax
26; CHECK-NEXT:    .seh_stackalloc 8
27; CHECK-NEXT:    movq %rsp, %rbp
28; CHECK-NEXT:    .seh_setframe %rbp, 0
29; CHECK-NEXT:    .seh_endprologue
30; CHECK-NEXT:    movq %rdx, 32(%rbp)
31; CHECK-NEXT:    movq %r8, 40(%rbp)
32; CHECK-NEXT:    movq %r9, 48(%rbp)
33; CHECK-NEXT:    leaq 32(%rbp), %rax
34; CHECK-NEXT:    movq %rax, (%rbp)
35; CHECK-NEXT:    addq $8, %rsp
36; CHECK-NEXT:    popq %rbp
37; CHECK-NEXT:    retq
38; CHECK-NEXT:    .seh_endproc
39  %ap = alloca i8, align 8
40  call void @llvm.va_start(ptr %ap)
41  ret void
42}
43
44define ptr @f3() "frame-pointer"="all" {
45; CHECK-LABEL: f3:
46; CHECK:       # %bb.0:
47; CHECK-NEXT:    pushq %rbp
48; CHECK-NEXT:    .seh_pushreg %rbp
49; CHECK-NEXT:    movq %rsp, %rbp
50; CHECK-NEXT:    .seh_setframe %rbp, 0
51; CHECK-NEXT:    .seh_endprologue
52; CHECK-NEXT:    movq 8(%rbp), %rax
53; CHECK-NEXT:    popq %rbp
54; CHECK-NEXT:    retq
55; CHECK-NEXT:    .seh_endproc
56  %ra = call ptr @llvm.returnaddress(i32 0)
57  ret ptr %ra
58}
59
60define ptr @f4() "frame-pointer"="all" {
61; CHECK-LABEL: f4:
62; CHECK:       # %bb.0:
63; CHECK-NEXT:    pushq %rbp
64; CHECK-NEXT:    .seh_pushreg %rbp
65; CHECK-NEXT:    subq $304, %rsp # imm = 0x130
66; CHECK-NEXT:    .seh_stackalloc 304
67; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rbp
68; CHECK-NEXT:    .seh_setframe %rbp, 128
69; CHECK-NEXT:    .seh_endprologue
70; CHECK-NEXT:    movq 184(%rbp), %rax
71; CHECK-NEXT:    addq $304, %rsp # imm = 0x130
72; CHECK-NEXT:    popq %rbp
73; CHECK-NEXT:    retq
74; CHECK-NEXT:    .seh_endproc
75  alloca [300 x i8]
76  %ra = call ptr @llvm.returnaddress(i32 0)
77  ret ptr %ra
78}
79
80declare void @external(ptr)
81
82define void @f5() "frame-pointer"="all" {
83; CHECK-LABEL: f5:
84; CHECK:       # %bb.0:
85; CHECK-NEXT:    pushq %rbp
86; CHECK-NEXT:    .seh_pushreg %rbp
87; CHECK-NEXT:    subq $336, %rsp # imm = 0x150
88; CHECK-NEXT:    .seh_stackalloc 336
89; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rbp
90; CHECK-NEXT:    .seh_setframe %rbp, 128
91; CHECK-NEXT:    .seh_endprologue
92; CHECK-NEXT:    leaq -92(%rbp), %rcx
93; CHECK-NEXT:    callq external
94; CHECK-NEXT:    nop
95; CHECK-NEXT:    addq $336, %rsp # imm = 0x150
96; CHECK-NEXT:    popq %rbp
97; CHECK-NEXT:    retq
98; CHECK-NEXT:    .seh_endproc
99  %a = alloca [300 x i8]
100  call void @external(ptr %a)
101  ret void
102}
103
104define void @f6(i32 %p, ...) "frame-pointer"="all" {
105; CHECK-LABEL: f6:
106; CHECK:       # %bb.0:
107; CHECK-NEXT:    pushq %rbp
108; CHECK-NEXT:    .seh_pushreg %rbp
109; CHECK-NEXT:    subq $336, %rsp # imm = 0x150
110; CHECK-NEXT:    .seh_stackalloc 336
111; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rbp
112; CHECK-NEXT:    .seh_setframe %rbp, 128
113; CHECK-NEXT:    .seh_endprologue
114; CHECK-NEXT:    leaq -92(%rbp), %rcx
115; CHECK-NEXT:    callq external
116; CHECK-NEXT:    nop
117; CHECK-NEXT:    addq $336, %rsp # imm = 0x150
118; CHECK-NEXT:    popq %rbp
119; CHECK-NEXT:    retq
120; CHECK-NEXT:    .seh_endproc
121  %a = alloca [300 x i8]
122  call void @external(ptr %a)
123  ret void
124}
125
126define i32 @f7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "frame-pointer"="all" {
127; CHECK-LABEL: f7:
128; CHECK:       # %bb.0:
129; CHECK-NEXT:    pushq %rbp
130; CHECK-NEXT:    .seh_pushreg %rbp
131; CHECK-NEXT:    subq $304, %rsp # imm = 0x130
132; CHECK-NEXT:    .seh_stackalloc 304
133; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rbp
134; CHECK-NEXT:    .seh_setframe %rbp, 128
135; CHECK-NEXT:    .seh_endprologue
136; CHECK-NEXT:    andq $-64, %rsp
137; CHECK-NEXT:    movl 224(%rbp), %eax
138; CHECK-NEXT:    leaq 176(%rbp), %rsp
139; CHECK-NEXT:    popq %rbp
140; CHECK-NEXT:    retq
141; CHECK-NEXT:    .seh_endproc
142  alloca [300 x i8], align 64
143  ret i32 %e
144}
145
146define i32 @f8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "frame-pointer"="all" {
147; CHECK-LABEL: f8:
148; CHECK:       # %bb.0:
149; CHECK-NEXT:    pushq %rbp
150; CHECK-NEXT:    .seh_pushreg %rbp
151; CHECK-NEXT:    pushq %rsi
152; CHECK-NEXT:    .seh_pushreg %rsi
153; CHECK-NEXT:    pushq %rbx
154; CHECK-NEXT:    .seh_pushreg %rbx
155; CHECK-NEXT:    subq $352, %rsp # imm = 0x160
156; CHECK-NEXT:    .seh_stackalloc 352
157; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rbp
158; CHECK-NEXT:    .seh_setframe %rbp, 128
159; CHECK-NEXT:    .seh_endprologue
160; CHECK-NEXT:    andq $-64, %rsp
161; CHECK-NEXT:    movq %rsp, %rbx
162; CHECK-NEXT:    movl 288(%rbp), %esi
163; CHECK-NEXT:    movl %ecx, %eax
164; CHECK-NEXT:    leaq 15(,%rax,4), %rax
165; CHECK-NEXT:    andq $-16, %rax
166; CHECK-NEXT:    callq __chkstk
167; CHECK-NEXT:    subq %rax, %rsp
168; CHECK-NEXT:    subq $32, %rsp
169; CHECK-NEXT:    movq %rbx, %rcx
170; CHECK-NEXT:    callq external
171; CHECK-NEXT:    addq $32, %rsp
172; CHECK-NEXT:    movl %esi, %eax
173; CHECK-NEXT:    leaq 224(%rbp), %rsp
174; CHECK-NEXT:    popq %rbx
175; CHECK-NEXT:    popq %rsi
176; CHECK-NEXT:    popq %rbp
177; CHECK-NEXT:    retq
178; CHECK-NEXT:    .seh_endproc
179  %alloca = alloca [300 x i8], align 64
180  alloca i32, i32 %a
181  call void @external(ptr %alloca)
182  ret i32 %e
183}
184
185define i64 @f9() {
186; CHECK-LABEL: f9:
187; CHECK:       # %bb.0: # %entry
188; CHECK-NEXT:    pushq %rbp
189; CHECK-NEXT:    .seh_pushreg %rbp
190; CHECK-NEXT:    movq %rsp, %rbp
191; CHECK-NEXT:    .seh_setframe %rbp, 0
192; CHECK-NEXT:    .seh_endprologue
193; CHECK-NEXT:    pushfq
194; CHECK-NEXT:    popq %rax
195; CHECK-NEXT:    popq %rbp
196; CHECK-NEXT:    retq
197; CHECK-NEXT:    .seh_endproc
198entry:
199  %call = call i64 @llvm.x86.flags.read.u64()
200  ret i64 %call
201}
202
203declare i64 @dummy()
204
205define i64 @f10(ptr %foo, i64 %bar, i64 %baz) {
206; CHECK-LABEL: f10:
207; CHECK:       # %bb.0:
208; CHECK-NEXT:    pushq %rsi
209; CHECK-NEXT:    .seh_pushreg %rsi
210; CHECK-NEXT:    pushq %rbx
211; CHECK-NEXT:    .seh_pushreg %rbx
212; CHECK-NEXT:    subq $40, %rsp
213; CHECK-NEXT:    .seh_stackalloc 40
214; CHECK-NEXT:    .seh_endprologue
215; CHECK-NEXT:    movq %rdx, %rsi
216; CHECK-NEXT:    movq %rdx, %rax
217; CHECK-NEXT:    lock cmpxchgq %r8, (%rcx)
218; CHECK-NEXT:    sete %bl
219; CHECK-NEXT:    callq dummy
220; CHECK-NEXT:    testb %bl, %bl
221; CHECK-NEXT:    cmoveq %rsi, %rax
222; CHECK-NEXT:    addq $40, %rsp
223; CHECK-NEXT:    popq %rbx
224; CHECK-NEXT:    popq %rsi
225; CHECK-NEXT:    retq
226; CHECK-NEXT:    .seh_endproc
227  %cx = cmpxchg ptr %foo, i64 %bar, i64 %baz seq_cst seq_cst
228  %v = extractvalue { i64, i1 } %cx, 0
229  %p = extractvalue { i64, i1 } %cx, 1
230  %call = call i64 @dummy()
231  %sel = select i1 %p, i64 %call, i64 %bar
232  ret i64 %sel
233}
234
235define ptr @f11() "frame-pointer"="all" {
236; CHECK-LABEL: f11:
237; CHECK:       # %bb.0:
238; CHECK-NEXT:    pushq %rbp
239; CHECK-NEXT:    .seh_pushreg %rbp
240; CHECK-NEXT:    movq %rsp, %rbp
241; CHECK-NEXT:    .seh_setframe %rbp, 0
242; CHECK-NEXT:    .seh_endprologue
243; CHECK-NEXT:    leaq 8(%rbp), %rax
244; CHECK-NEXT:    popq %rbp
245; CHECK-NEXT:    retq
246; CHECK-NEXT:    .seh_endproc
247  %aora = call ptr @llvm.addressofreturnaddress()
248  ret ptr %aora
249}
250
251define ptr @f12() {
252; CHECK-LABEL: f12:
253; CHECK:       # %bb.0:
254; CHECK-NEXT:    movq %rsp, %rax
255; CHECK-NEXT:    retq
256  %aora = call ptr @llvm.addressofreturnaddress()
257  ret ptr %aora
258}
259
260declare ptr @llvm.returnaddress(i32) nounwind readnone
261declare ptr @llvm.addressofreturnaddress() nounwind readnone
262declare i64 @llvm.x86.flags.read.u64()
263declare void @llvm.va_start(ptr) nounwind
264