-; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s --check-prefix=CHECK --check-prefix=PUSHF
+; RUN: llc < %s -mtriple=x86_64-pc-win32 -mattr=+sahf | FileCheck %s --check-prefix=SAHF
define i32 @f1(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) "no-frame-pointer-elim"="true" {
; CHECK-LABEL: f1:
; CHECK: leaq 224(%rbp), %rsp
}
+define i64 @f9() {
+entry:
+ ; CHECK-LABEL: f9:
+ ; CHECK: pushq %rbp
+ ; CHECK: .seh_pushreg 5
+ ; CHECK-NEXT: movq %rsp, %rbp
+ ; CHECK: .seh_setframe 5, 0
+ ; CHECK: .seh_endprologue
+
+ %call = call i64 @llvm.x86.flags.read.u64()
+ ; CHECK-NEXT: pushfq
+ ; CHECK-NEXT: popq %rax
+
+ ret i64 %call
+ ; CHECK-NEXT: popq %rbp
+ ; CHECK-NEXT: retq
+}
+
+declare i64 @dummy()
+
+define i64 @f10(i64* %foo, i64 %bar, i64 %baz) {
+ ; CHECK-LABEL: f10:
+ ; CHECK: pushq %rbp
+ ; CHECK: .seh_pushreg 5
+ ; CHECK: pushq %rsi
+ ; CHECK: .seh_pushreg 6
+ ; CHECK: pushq %rdi
+ ; CHECK: .seh_pushreg 7
+ ; CHECK: subq $32, %rsp
+ ; CHECK: .seh_stackalloc 32
+ ; CHECK: leaq 32(%rsp), %rbp
+ ; CHECK: .seh_setframe 5, 32
+ ; CHECK: .seh_endprologue
+
+ %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst
+ ; PUSHF: lock cmpxchgq
+ ; PUSHF-NEXT: pushfq
+ ; PUSHF-NEXT: popq %[[REG:.*]]
+ ; SAHF: lock cmpxchgq
+ ; SAHF-NEXT: seto %al
+ ; SAHF-NEXT: lahf
+
+ %v = extractvalue { i64, i1 } %cx, 0
+ %p = extractvalue { i64, i1 } %cx, 1
+
+ %call = call i64 @dummy()
+ ; PUSHF: callq dummy
+ ; PUSHF-NEXT: pushq %[[REG]]
+ ; PUSHF-NEXT: popfq
+ ; SAHF: callq dummy
+ ; SAHF-NEXT: pushq
+ ; SAHF: addb $127, %al
+ ; SAHF-NEXT: sahf
+ ; SAHF-NEXT: popq
+
+ %sel = select i1 %p, i64 %call, i64 %bar
+ ; CHECK-NEXT: cmovneq
+
+ ret i64 %sel
+ ; CHECK-NEXT: addq $32, %rsp
+ ; CHECK-NEXT: popq %rdi
+ ; CHECK-NEXT: popq %rsi
+ ; CHECK-NEXT: popq %rbp
+}
+
declare i8* @llvm.returnaddress(i32) nounwind readnone
+declare i64 @llvm.x86.flags.read.u64()
declare void @llvm.va_start(i8*) nounwind