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 4 5 define i32 @f1(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) "no-frame-pointer-elim"="true" { 6 ; ALL-LABEL: f1: 7 ; ALL: # %bb.0: 8 ; ALL-NEXT: pushq %rbp 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 14 ; ALL-NEXT: popq %rbp 15 ; ALL-NEXT: retq 16 ; ALL-NEXT: .seh_handlerdata 17 ; ALL-NEXT: .text 18 ; ALL-NEXT: .seh_endproc 19 ret i32 %p5 20 } 21 22 define void @f2(i32 %p, ...) "no-frame-pointer-elim"="true" { 23 ; ALL-LABEL: f2: 24 ; ALL: # %bb.0: 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 %r9, 48(%rbp) 33 ; ALL-NEXT: movq %r8, 40(%rbp) 34 ; ALL-NEXT: movq %rdx, 32(%rbp) 35 ; ALL-NEXT: leaq 32(%rbp), %rax 36 ; ALL-NEXT: movq %rax, (%rbp) 37 ; ALL-NEXT: addq $8, %rsp 38 ; ALL-NEXT: popq %rbp 39 ; ALL-NEXT: retq 40 ; ALL-NEXT: .seh_handlerdata 41 ; ALL-NEXT: .text 42 ; ALL-NEXT: .seh_endproc 43 %ap = alloca i8, align 8 44 call void @llvm.va_start(i8* %ap) 45 ret void 46 } 47 48 define i8* @f3() "no-frame-pointer-elim"="true" { 49 ; ALL-LABEL: f3: 50 ; ALL: # %bb.0: 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 57 ; ALL-NEXT: popq %rbp 58 ; ALL-NEXT: retq 59 ; ALL-NEXT: .seh_handlerdata 60 ; ALL-NEXT: .text 61 ; ALL-NEXT: .seh_endproc 62 %ra = call i8* @llvm.returnaddress(i32 0) 63 ret i8* %ra 64 } 65 66 define i8* @f4() "no-frame-pointer-elim"="true" { 67 ; ALL-LABEL: f4: 68 ; ALL: # %bb.0: 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 78 ; ALL-NEXT: popq %rbp 79 ; ALL-NEXT: retq 80 ; ALL-NEXT: .seh_handlerdata 81 ; ALL-NEXT: .text 82 ; ALL-NEXT: .seh_endproc 83 alloca [300 x i8] 84 %ra = call i8* @llvm.returnaddress(i32 0) 85 ret i8* %ra 86 } 87 88 declare void @external(i8*) 89 90 define void @f5() "no-frame-pointer-elim"="true" { 91 ; ALL-LABEL: f5: 92 ; ALL: # %bb.0: 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 102 ; ALL-NEXT: nop 103 ; ALL-NEXT: addq $336, %rsp # imm = 0x150 104 ; ALL-NEXT: popq %rbp 105 ; ALL-NEXT: retq 106 ; ALL-NEXT: .seh_handlerdata 107 ; ALL-NEXT: .text 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) 112 ret void 113 } 114 115 define void @f6(i32 %p, ...) "no-frame-pointer-elim"="true" { 116 ; ALL-LABEL: f6: 117 ; ALL: # %bb.0: 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 127 ; ALL-NEXT: nop 128 ; ALL-NEXT: addq $336, %rsp # imm = 0x150 129 ; ALL-NEXT: popq %rbp 130 ; ALL-NEXT: retq 131 ; ALL-NEXT: .seh_handlerdata 132 ; ALL-NEXT: .text 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) 137 ret void 138 } 139 140 define i32 @f7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "no-frame-pointer-elim"="true" { 141 ; ALL-LABEL: f7: 142 ; ALL: # %bb.0: 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 154 ; ALL-NEXT: retq 155 ; ALL-NEXT: .seh_handlerdata 156 ; ALL-NEXT: .text 157 ; ALL-NEXT: .seh_endproc 158 alloca [300 x i8], align 64 159 ret i32 %e 160 } 161 162 define i32 @f8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "no-frame-pointer-elim"="true" { 163 ; ALL-LABEL: f8: 164 ; ALL: # %bb.0: 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 193 ; ALL-NEXT: retq 194 ; ALL-NEXT: .seh_handlerdata 195 ; ALL-NEXT: .text 196 ; ALL-NEXT: .seh_endproc 197 %alloca = alloca [300 x i8], align 64 198 alloca i32, i32 %a 199 %gep = getelementptr [300 x i8], [300 x i8]* %alloca, i32 0, i32 0 200 call void @external(i8* %gep) 201 ret i32 %e 202 } 203 204 define i64 @f9() { 205 ; ALL-LABEL: f9: 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 212 ; ALL-NEXT: pushfq 213 ; ALL-NEXT: popq %rax 214 ; ALL-NEXT: popq %rbp 215 ; ALL-NEXT: retq 216 ; ALL-NEXT: .seh_handlerdata 217 ; ALL-NEXT: .text 218 ; ALL-NEXT: .seh_endproc 219 entry: 220 %call = call i64 @llvm.x86.flags.read.u64() 221 ret i64 %call 222 } 223 224 declare i64 @dummy() 225 226 define i64 @f10(i64* %foo, i64 %bar, i64 %baz) { 227 ; ALL-LABEL: f10: 228 ; ALL: # %bb.0: 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) 239 ; ALL-NEXT: sete %bl 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 246 ; ALL-NEXT: retq 247 ; ALL-NEXT: .seh_handlerdata 248 ; ALL-NEXT: .text 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 255 ret i64 %sel 256 } 257 258 define i8* @f11() "no-frame-pointer-elim"="true" { 259 ; ALL-LABEL: f11: 260 ; ALL: # %bb.0: 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 268 ; ALL-NEXT: retq 269 ; ALL-NEXT: .seh_handlerdata 270 ; ALL-NEXT: .text 271 ; ALL-NEXT: .seh_endproc 272 %aora = call i8* @llvm.addressofreturnaddress() 273 ret i8* %aora 274 } 275 276 define i8* @f12() { 277 ; ALL-LABEL: f12: 278 ; ALL: # %bb.0: 279 ; ALL-NEXT: movq %rsp, %rax 280 ; ALL-NEXT: retq 281 %aora = call i8* @llvm.addressofreturnaddress() 282 ret i8* %aora 283 } 284 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 289