; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -verify-machineinstrs -mtriple x86_64-linux < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple x86_64-windows < %s | FileCheck %s --check-prefix=WIN64
declare i64 @llvm.x86.flags.read.u64()
declare void @llvm.x86.flags.write.u64(i64)
define i64 @read_flags() {
; CHECK-LABEL: read_flags:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: pushfq
; CHECK-NEXT: popq %rax
; CHECK-NEXT: retq
;
; WIN64-LABEL: read_flags:
; WIN64: # %bb.0: # %entry
; WIN64-NEXT: pushq %rbp
; WIN64-NEXT: .seh_pushreg %rbp
; WIN64-NEXT: movq %rsp, %rbp
; WIN64-NEXT: .seh_setframe %rbp, 0
; WIN64-NEXT: .seh_endprologue
; WIN64-NEXT: pushfq
; WIN64-NEXT: popq %rax
; WIN64-NEXT: popq %rbp
; WIN64-NEXT: retq
; WIN64-NEXT: .seh_endproc
entry:
%flags = call i64 @llvm.x86.flags.read.u64()
ret i64 %flags
}
define void @write_flags(i64 %arg) {
; CHECK-LABEL: write_flags:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: pushq %rdi
; CHECK-NEXT: popfq
; CHECK-NEXT: retq
;
; WIN64-LABEL: write_flags:
; WIN64: # %bb.0: # %entry
; WIN64-NEXT: pushq %rbp
; WIN64-NEXT: .seh_pushreg %rbp
; WIN64-NEXT: movq %rsp, %rbp
; WIN64-NEXT: .seh_setframe %rbp, 0
; WIN64-NEXT: .seh_endprologue
; WIN64-NEXT: pushq %rcx
; WIN64-NEXT: popfq
; WIN64-NEXT: popq %rbp
; WIN64-NEXT: retq
; WIN64-NEXT: .seh_endproc
entry:
call void @llvm.x86.flags.write.u64(i64 %arg)
ret void
}
define i64 @read_flags_reg_pressure() nounwind {
; CHECK-LABEL: read_flags_reg_pressure:
; CHECK: # %bb.0:
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: pushq %r15
; CHECK-NEXT: pushq %r14
; CHECK-NEXT: pushq %r13
; CHECK-NEXT: pushq %r12
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: pushfq
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: movq %rbp, %rax
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: popq %r12
; CHECK-NEXT: popq %r13
; CHECK-NEXT: popq %r14
; CHECK-NEXT: popq %r15
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: retq
;
; WIN64-LABEL: read_flags_reg_pressure:
; WIN64: # %bb.0:
; WIN64-NEXT: pushq %rbp
; WIN64-NEXT: pushq %r15
; WIN64-NEXT: pushq %r14
; WIN64-NEXT: pushq %r13
; WIN64-NEXT: pushq %r12
; WIN64-NEXT: pushq %rsi
; WIN64-NEXT: pushq %rdi
; WIN64-NEXT: pushq %rbx
; WIN64-NEXT: subq $16, %rsp
; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
; WIN64-NEXT: #APP
; WIN64-NEXT: #NO_APP
; WIN64-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
; WIN64-NEXT: pushfq
; WIN64-NEXT: popq %rdx
; WIN64-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
; WIN64-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
; WIN64-NEXT: #APP
; WIN64-NEXT: #NO_APP
; WIN64-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
; WIN64-NEXT: addq $16, %rsp
; WIN64-NEXT: popq %rbx
; WIN64-NEXT: popq %rdi
; WIN64-NEXT: popq %rsi
; WIN64-NEXT: popq %r12
; WIN64-NEXT: popq %r13
; WIN64-NEXT: popq %r14
; WIN64-NEXT: popq %r15
; WIN64-NEXT: popq %rbp
; WIN64-NEXT: retq
%1 = tail call { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } asm sideeffect "", "={ax},={bx},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={r12},={r13},={r14},={r15},~{dirflag},~{fpsr},~{flags}"()
%2 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 0
%3 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 1
%4 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 2
%5 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 3
%6 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 4
%7 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 5
%8 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 6
%9 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 7
%10 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 8
%11 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 9
%12 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 10
%13 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 11
%14 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 12
%15 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 13
%flags = tail call i64 @llvm.x86.flags.read.u64()
tail call void asm sideeffect "", "{ax},{bx},{cx},{dx},{si},{di},{r8},{r9},{r10},{r11},{r12},{r13},{r14},{r15},~{dirflag},~{fpsr},~{flags}"(i64 %2, i64 %3, i64 %4, i64 %5, i64 %6, i64 %7, i64 %8, i64 %9, i64 %10, i64 %11, i64 %12, i64 %13, i64 %14, i64 %15)
ret i64 %flags
}
define void @write_flags_reg_pressure(i64 noundef %0) nounwind {
; CHECK-LABEL: write_flags_reg_pressure:
; CHECK: # %bb.0:
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: pushq %r15
; CHECK-NEXT: pushq %r14
; CHECK-NEXT: pushq %r13
; CHECK-NEXT: pushq %r12
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: movq %rdi, %rbp
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: popfq
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: popq %r12
; CHECK-NEXT: popq %r13
; CHECK-NEXT: popq %r14
; CHECK-NEXT: popq %r15
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: retq
;
; WIN64-LABEL: write_flags_reg_pressure:
; WIN64: # %bb.0:
; WIN64-NEXT: pushq %rbp
; WIN64-NEXT: pushq %r15
; WIN64-NEXT: pushq %r14
; WIN64-NEXT: pushq %r13
; WIN64-NEXT: pushq %r12
; WIN64-NEXT: pushq %rsi
; WIN64-NEXT: pushq %rdi
; WIN64-NEXT: pushq %rbx
; WIN64-NEXT: subq $16, %rsp
; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
; WIN64-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
; WIN64-NEXT: #APP
; WIN64-NEXT: #NO_APP
; WIN64-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
; WIN64-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
; WIN64-NEXT: pushq %rdx
; WIN64-NEXT: popfq
; WIN64-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
; WIN64-NEXT: #APP
; WIN64-NEXT: #NO_APP
; WIN64-NEXT: addq $16, %rsp
; WIN64-NEXT: popq %rbx
; WIN64-NEXT: popq %rdi
; WIN64-NEXT: popq %rsi
; WIN64-NEXT: popq %r12
; WIN64-NEXT: popq %r13
; WIN64-NEXT: popq %r14
; WIN64-NEXT: popq %r15
; WIN64-NEXT: popq %rbp
; WIN64-NEXT: retq
%2 = tail call { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } asm sideeffect "", "={ax},={bx},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={r12},={r13},={r14},={r15},~{dirflag},~{fpsr},~{flags}"()
%3 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 0
%4 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 1
%5 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 2
%6 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 3
%7 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 4
%8 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 5
%9 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 6
%10 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 7
%11 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 8
%12 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 9
%13 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 10
%14 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 11
%15 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 12
%16 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 13
tail call void @llvm.x86.flags.write.u64(i64 %0)
tail call void asm sideeffect "", "{ax},{bx},{cx},{dx},{si},{di},{r8},{r9},{r10},{r11},{r12},{r13},{r14},{r15},~{dirflag},~{fpsr},~{flags}"(i64 %3, i64 %4, i64 %5, i64 %6, i64 %7, i64 %8, i64 %9, i64 %10, i64 %11, i64 %12, i64 %13, i64 %14, i64 %15, i64 %16)
ret void
}