1 ; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s --check-prefix=CHECK --check-prefix=PUSHF
2 ; RUN: llc < %s -mtriple=x86_64-pc-win32 -mattr=+sahf | FileCheck %s --check-prefix=SAHF
4 define i32 @f1(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) "no-frame-pointer-elim"="true" {
6 ; CHECK: movl 48(%rbp), %eax
10 define void @f2(i32 %p, ...) "no-frame-pointer-elim"="true" {
12 ; CHECK: .seh_stackalloc 8
13 ; CHECK: movq %rsp, %rbp
14 ; CHECK: .seh_setframe 5, 0
15 ; CHECK: movq %rdx, 32(%rbp)
16 ; CHECK: leaq 32(%rbp), %rax
17 %ap = alloca i8, align 8
18 call void @llvm.va_start(i8* %ap)
22 define i8* @f3() "no-frame-pointer-elim"="true" {
24 ; CHECK: movq %rsp, %rbp
25 ; CHECK: .seh_setframe 5, 0
26 ; CHECK: movq 8(%rbp), %rax
27 %ra = call i8* @llvm.returnaddress(i32 0)
31 define i8* @f4() "no-frame-pointer-elim"="true" {
34 ; CHECK: .seh_pushreg 5
35 ; CHECK: subq $304, %rsp
36 ; CHECK: .seh_stackalloc 304
37 ; CHECK: leaq 128(%rsp), %rbp
38 ; CHECK: .seh_setframe 5, 128
39 ; CHECK: .seh_endprologue
40 ; CHECK: movq 184(%rbp), %rax
42 %ra = call i8* @llvm.returnaddress(i32 0)
46 declare void @external(i8*)
48 define void @f5() "no-frame-pointer-elim"="true" {
50 ; CHECK: subq $336, %rsp
51 ; CHECK: .seh_stackalloc 336
52 ; CHECK: leaq 128(%rsp), %rbp
53 ; CHECK: .seh_setframe 5, 128
54 ; CHECK: leaq -92(%rbp), %rcx
55 ; CHECK: callq external
56 %a = alloca [300 x i8]
57 %gep = getelementptr [300 x i8], [300 x i8]* %a, i32 0, i32 0
58 call void @external(i8* %gep)
62 define void @f6(i32 %p, ...) "no-frame-pointer-elim"="true" {
64 ; CHECK: subq $336, %rsp
65 ; CHECK: .seh_stackalloc 336
66 ; CHECK: leaq 128(%rsp), %rbp
67 ; CHECK: .seh_setframe 5, 128
68 ; CHECK: leaq -92(%rbp), %rcx
69 ; CHECK: callq external
70 %a = alloca [300 x i8]
71 %gep = getelementptr [300 x i8], [300 x i8]* %a, i32 0, i32 0
72 call void @external(i8* %gep)
76 define i32 @f7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "no-frame-pointer-elim"="true" {
79 ; CHECK: .seh_pushreg 5
80 ; CHECK: subq $304, %rsp
81 ; CHECK: .seh_stackalloc 304
82 ; CHECK: leaq 128(%rsp), %rbp
83 ; CHECK: .seh_setframe 5, 128
84 ; CHECK: andq $-64, %rsp
85 ; CHECK: movl 224(%rbp), %eax
86 ; CHECK: leaq 176(%rbp), %rsp
87 alloca [300 x i8], align 64
91 define i32 @f8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "no-frame-pointer-elim"="true" {
93 ; CHECK: subq $352, %rsp
94 ; CHECK: .seh_stackalloc 352
95 ; CHECK: leaq 128(%rsp), %rbp
96 ; CHECK: .seh_setframe 5, 128
98 %alloca = alloca [300 x i8], align 64
99 ; CHECK: andq $-64, %rsp
100 ; CHECK: movq %rsp, %rbx
103 ; CHECK: movl %ecx, %eax
104 ; CHECK: leaq 15(,%rax,4), %rcx
105 ; CHECK: movabsq $34359738352, %rax
106 ; CHECK: andq %rcx, %rax
107 ; CHECK: callq __chkstk
108 ; CHECK: subq %rax, %rsp
110 %gep = getelementptr [300 x i8], [300 x i8]* %alloca, i32 0, i32 0
111 call void @external(i8* %gep)
112 ; CHECK: subq $32, %rsp
113 ; CHECK: leaq (%rbx), %rcx
114 ; CHECK: callq external
115 ; CHECK: addq $32, %rsp
118 ; CHECK: movl %esi, %eax
119 ; CHECK: leaq 224(%rbp), %rsp
126 ; CHECK: .seh_pushreg 5
127 ; CHECK-NEXT: movq %rsp, %rbp
128 ; CHECK: .seh_setframe 5, 0
129 ; CHECK: .seh_endprologue
131 %call = call i64 @llvm.x86.flags.read.u64()
133 ; CHECK-NEXT: popq %rax
136 ; CHECK-NEXT: popq %rbp
142 define i64 @f10(i64* %foo, i64 %bar, i64 %baz) {
145 ; CHECK: .seh_pushreg 5
147 ; CHECK: .seh_pushreg 6
149 ; CHECK: .seh_pushreg 7
150 ; CHECK: subq $32, %rsp
151 ; CHECK: .seh_stackalloc 32
152 ; CHECK: leaq 32(%rsp), %rbp
153 ; CHECK: .seh_setframe 5, 32
154 ; CHECK: .seh_endprologue
156 %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst
157 ; PUSHF: lock cmpxchgq
159 ; PUSHF-NEXT: popq %[[REG:.*]]
160 ; SAHF: lock cmpxchgq
161 ; SAHF-NEXT: seto %al
164 %v = extractvalue { i64, i1 } %cx, 0
165 %p = extractvalue { i64, i1 } %cx, 1
167 %call = call i64 @dummy()
169 ; PUSHF-NEXT: pushq %[[REG]]
173 ; SAHF: addb $127, %al
177 %sel = select i1 %p, i64 %call, i64 %bar
178 ; CHECK-NEXT: cmovneq
181 ; CHECK-NEXT: addq $32, %rsp
182 ; CHECK-NEXT: popq %rdi
183 ; CHECK-NEXT: popq %rsi
184 ; CHECK-NEXT: popq %rbp
187 declare i8* @llvm.returnaddress(i32) nounwind readnone
188 declare i64 @llvm.x86.flags.read.u64()
190 declare void @llvm.va_start(i8*) nounwind