1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s --check-prefix=ALL --check-prefix=PUSHF
3 ; RUN: llc < %s -mtriple=x86_64-pc-win32 -mattr=+sahf | FileCheck %s --check-prefix=ALL --check-prefix=SAHF
5 define i32 @f1(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) "no-frame-pointer-elim"="true" {
9 ; ALL-NEXT: .seh_pushreg 5
10 ; ALL-NEXT: movq %rsp, %rbp
11 ; ALL-NEXT: .seh_setframe 5, 0
12 ; ALL-NEXT: .seh_endprologue
13 ; ALL-NEXT: movl 48(%rbp), %eax
16 ; ALL-NEXT: .seh_handlerdata
18 ; ALL-NEXT: .seh_endproc
22 define void @f2(i32 %p, ...) "no-frame-pointer-elim"="true" {
25 ; ALL-NEXT: pushq %rbp
26 ; ALL-NEXT: .seh_pushreg 5
27 ; ALL-NEXT: pushq %rax
28 ; ALL-NEXT: .seh_stackalloc 8
29 ; ALL-NEXT: movq %rsp, %rbp
30 ; ALL-NEXT: .seh_setframe 5, 0
31 ; ALL-NEXT: .seh_endprologue
32 ; ALL-NEXT: movq %rdx, 32(%rbp)
33 ; ALL-NEXT: movq %r8, 40(%rbp)
34 ; ALL-NEXT: movq %r9, 48(%rbp)
35 ; ALL-NEXT: leaq 32(%rbp), %rax
36 ; ALL-NEXT: movq %rax, (%rbp)
37 ; ALL-NEXT: addq $8, %rsp
40 ; ALL-NEXT: .seh_handlerdata
42 ; ALL-NEXT: .seh_endproc
43 %ap = alloca i8, align 8
44 call void @llvm.va_start(i8* %ap)
48 define i8* @f3() "no-frame-pointer-elim"="true" {
51 ; ALL-NEXT: pushq %rbp
52 ; ALL-NEXT: .seh_pushreg 5
53 ; ALL-NEXT: movq %rsp, %rbp
54 ; ALL-NEXT: .seh_setframe 5, 0
55 ; ALL-NEXT: .seh_endprologue
56 ; ALL-NEXT: movq 8(%rbp), %rax
59 ; ALL-NEXT: .seh_handlerdata
61 ; ALL-NEXT: .seh_endproc
62 %ra = call i8* @llvm.returnaddress(i32 0)
66 define i8* @f4() "no-frame-pointer-elim"="true" {
69 ; ALL-NEXT: pushq %rbp
70 ; ALL-NEXT: .seh_pushreg 5
71 ; ALL-NEXT: subq $304, %rsp # imm = 0x130
72 ; ALL-NEXT: .seh_stackalloc 304
73 ; ALL-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
74 ; ALL-NEXT: .seh_setframe 5, 128
75 ; ALL-NEXT: .seh_endprologue
76 ; ALL-NEXT: movq 184(%rbp), %rax
77 ; ALL-NEXT: addq $304, %rsp # imm = 0x130
80 ; ALL-NEXT: .seh_handlerdata
82 ; ALL-NEXT: .seh_endproc
84 %ra = call i8* @llvm.returnaddress(i32 0)
88 declare void @external(i8*)
90 define void @f5() "no-frame-pointer-elim"="true" {
93 ; ALL-NEXT: pushq %rbp
94 ; ALL-NEXT: .seh_pushreg 5
95 ; ALL-NEXT: subq $336, %rsp # imm = 0x150
96 ; ALL-NEXT: .seh_stackalloc 336
97 ; ALL-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
98 ; ALL-NEXT: .seh_setframe 5, 128
99 ; ALL-NEXT: .seh_endprologue
100 ; ALL-NEXT: leaq -92(%rbp), %rcx
101 ; ALL-NEXT: callq external
103 ; ALL-NEXT: addq $336, %rsp # imm = 0x150
104 ; ALL-NEXT: popq %rbp
106 ; ALL-NEXT: .seh_handlerdata
108 ; ALL-NEXT: .seh_endproc
109 %a = alloca [300 x i8]
110 %gep = getelementptr [300 x i8], [300 x i8]* %a, i32 0, i32 0
111 call void @external(i8* %gep)
115 define void @f6(i32 %p, ...) "no-frame-pointer-elim"="true" {
118 ; ALL-NEXT: pushq %rbp
119 ; ALL-NEXT: .seh_pushreg 5
120 ; ALL-NEXT: subq $336, %rsp # imm = 0x150
121 ; ALL-NEXT: .seh_stackalloc 336
122 ; ALL-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
123 ; ALL-NEXT: .seh_setframe 5, 128
124 ; ALL-NEXT: .seh_endprologue
125 ; ALL-NEXT: leaq -92(%rbp), %rcx
126 ; ALL-NEXT: callq external
128 ; ALL-NEXT: addq $336, %rsp # imm = 0x150
129 ; ALL-NEXT: popq %rbp
131 ; ALL-NEXT: .seh_handlerdata
133 ; ALL-NEXT: .seh_endproc
134 %a = alloca [300 x i8]
135 %gep = getelementptr [300 x i8], [300 x i8]* %a, i32 0, i32 0
136 call void @external(i8* %gep)
140 define i32 @f7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "no-frame-pointer-elim"="true" {
143 ; ALL-NEXT: pushq %rbp
144 ; ALL-NEXT: .seh_pushreg 5
145 ; ALL-NEXT: subq $304, %rsp # imm = 0x130
146 ; ALL-NEXT: .seh_stackalloc 304
147 ; ALL-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
148 ; ALL-NEXT: .seh_setframe 5, 128
149 ; ALL-NEXT: .seh_endprologue
150 ; ALL-NEXT: andq $-64, %rsp
151 ; ALL-NEXT: movl 224(%rbp), %eax
152 ; ALL-NEXT: leaq 176(%rbp), %rsp
153 ; ALL-NEXT: popq %rbp
155 ; ALL-NEXT: .seh_handlerdata
157 ; ALL-NEXT: .seh_endproc
158 alloca [300 x i8], align 64
162 define i32 @f8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "no-frame-pointer-elim"="true" {
165 ; ALL-NEXT: pushq %rbp
166 ; ALL-NEXT: .seh_pushreg 5
167 ; ALL-NEXT: pushq %rsi
168 ; ALL-NEXT: .seh_pushreg 6
169 ; ALL-NEXT: pushq %rbx
170 ; ALL-NEXT: .seh_pushreg 3
171 ; ALL-NEXT: subq $352, %rsp # imm = 0x160
172 ; ALL-NEXT: .seh_stackalloc 352
173 ; ALL-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
174 ; ALL-NEXT: .seh_setframe 5, 128
175 ; ALL-NEXT: .seh_endprologue
176 ; ALL-NEXT: andq $-64, %rsp
177 ; ALL-NEXT: movq %rsp, %rbx
178 ; ALL-NEXT: movl 288(%rbp), %esi
179 ; ALL-NEXT: movl %ecx, %eax
180 ; ALL-NEXT: leaq 15(,%rax,4), %rax
181 ; ALL-NEXT: andq $-16, %rax
182 ; ALL-NEXT: callq __chkstk
183 ; ALL-NEXT: subq %rax, %rsp
184 ; ALL-NEXT: subq $32, %rsp
185 ; ALL-NEXT: movq %rbx, %rcx
186 ; ALL-NEXT: callq external
187 ; ALL-NEXT: addq $32, %rsp
188 ; ALL-NEXT: movl %esi, %eax
189 ; ALL-NEXT: leaq 224(%rbp), %rsp
190 ; ALL-NEXT: popq %rbx
191 ; ALL-NEXT: popq %rsi
192 ; ALL-NEXT: popq %rbp
194 ; ALL-NEXT: .seh_handlerdata
196 ; ALL-NEXT: .seh_endproc
197 %alloca = alloca [300 x i8], align 64
199 %gep = getelementptr [300 x i8], [300 x i8]* %alloca, i32 0, i32 0
200 call void @external(i8* %gep)
206 ; ALL: # %bb.0: # %entry
207 ; ALL-NEXT: pushq %rbp
208 ; ALL-NEXT: .seh_pushreg 5
209 ; ALL-NEXT: movq %rsp, %rbp
210 ; ALL-NEXT: .seh_setframe 5, 0
211 ; ALL-NEXT: .seh_endprologue
213 ; ALL-NEXT: popq %rax
214 ; ALL-NEXT: popq %rbp
216 ; ALL-NEXT: .seh_handlerdata
218 ; ALL-NEXT: .seh_endproc
220 %call = call i64 @llvm.x86.flags.read.u64()
226 define i64 @f10(i64* %foo, i64 %bar, i64 %baz) {
229 ; ALL-NEXT: pushq %rsi
230 ; ALL-NEXT: .seh_pushreg 6
231 ; ALL-NEXT: pushq %rbx
232 ; ALL-NEXT: .seh_pushreg 3
233 ; ALL-NEXT: subq $40, %rsp
234 ; ALL-NEXT: .seh_stackalloc 40
235 ; ALL-NEXT: .seh_endprologue
236 ; ALL-NEXT: movq %rdx, %rsi
237 ; ALL-NEXT: movq %rdx, %rax
238 ; ALL-NEXT: lock cmpxchgq %r8, (%rcx)
240 ; ALL-NEXT: callq dummy
241 ; ALL-NEXT: testb %bl, %bl
242 ; ALL-NEXT: cmoveq %rsi, %rax
243 ; ALL-NEXT: addq $40, %rsp
244 ; ALL-NEXT: popq %rbx
245 ; ALL-NEXT: popq %rsi
247 ; ALL-NEXT: .seh_handlerdata
249 ; ALL-NEXT: .seh_endproc
250 %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst
251 %v = extractvalue { i64, i1 } %cx, 0
252 %p = extractvalue { i64, i1 } %cx, 1
253 %call = call i64 @dummy()
254 %sel = select i1 %p, i64 %call, i64 %bar
258 define i8* @f11() "no-frame-pointer-elim"="true" {
261 ; ALL-NEXT: pushq %rbp
262 ; ALL-NEXT: .seh_pushreg 5
263 ; ALL-NEXT: movq %rsp, %rbp
264 ; ALL-NEXT: .seh_setframe 5, 0
265 ; ALL-NEXT: .seh_endprologue
266 ; ALL-NEXT: leaq 8(%rbp), %rax
267 ; ALL-NEXT: popq %rbp
269 ; ALL-NEXT: .seh_handlerdata
271 ; ALL-NEXT: .seh_endproc
272 %aora = call i8* @llvm.addressofreturnaddress()
279 ; ALL-NEXT: movq %rsp, %rax
281 %aora = call i8* @llvm.addressofreturnaddress()
285 declare i8* @llvm.returnaddress(i32) nounwind readnone
286 declare i8* @llvm.addressofreturnaddress() nounwind readnone
287 declare i64 @llvm.x86.flags.read.u64()
288 declare void @llvm.va_start(i8*) nounwind