| ; 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: subq $16, %rsp |
| ; CHECK-NEXT: #APP |
| ; CHECK-NEXT: #NO_APP |
| ; CHECK-NEXT: movq %rdx, (%rsp) # 8-byte Spill |
| ; CHECK-NEXT: pushfq |
| ; CHECK-NEXT: popq %rdx |
| ; CHECK-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill |
| ; CHECK-NEXT: movq (%rsp), %rdx # 8-byte Reload |
| ; CHECK-NEXT: #APP |
| ; CHECK-NEXT: #NO_APP |
| ; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload |
| ; CHECK-NEXT: addq $16, %rsp |
| ; 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, i64 } asm sideeffect "", "={ax},={bx},={cx},={dx},={si},={di},={bp},={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, i64 } %1, 0 |
| %3 = extractvalue { i64, 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, i64 } %1, 2 |
| %5 = extractvalue { i64, 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, i64 } %1, 4 |
| %7 = extractvalue { i64, 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, i64 } %1, 6 |
| %9 = extractvalue { i64, 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, i64 } %1, 8 |
| %11 = extractvalue { i64, 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, i64 } %1, 10 |
| %13 = extractvalue { i64, 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, i64 } %1, 12 |
| %15 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 13 |
| %16 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 14 |
| %17 = tail call i64 @llvm.x86.flags.read.u64() |
| tail call void asm sideeffect "", "{ax},{bx},{cx},{dx},{si},{di},{bp},{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, i64 %16) |
| ret i64 %17 |
| } |
| |
| 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: subq $16, %rsp |
| ; CHECK-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill |
| ; CHECK-NEXT: #APP |
| ; CHECK-NEXT: #NO_APP |
| ; CHECK-NEXT: movq %rdx, (%rsp) # 8-byte Spill |
| ; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload |
| ; CHECK-NEXT: pushq %rdx |
| ; CHECK-NEXT: popfq |
| ; CHECK-NEXT: movq (%rsp), %rdx # 8-byte Reload |
| ; CHECK-NEXT: #APP |
| ; CHECK-NEXT: #NO_APP |
| ; CHECK-NEXT: addq $16, %rsp |
| ; 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, i64 } asm sideeffect "", "={ax},={bx},={cx},={dx},={si},={di},={bp},={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, i64 } %2, 0 |
| %4 = extractvalue { i64, 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, i64 } %2, 2 |
| %6 = extractvalue { i64, 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, i64 } %2, 4 |
| %8 = extractvalue { i64, 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, i64 } %2, 6 |
| %10 = extractvalue { i64, 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, i64 } %2, 8 |
| %12 = extractvalue { i64, 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, i64 } %2, 10 |
| %14 = extractvalue { i64, 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, i64 } %2, 12 |
| %16 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 13 |
| %17 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 14 |
| tail call void @llvm.x86.flags.write.u64(i64 %0) |
| tail call void asm sideeffect "", "{ax},{bx},{cx},{dx},{si},{di},{bp},{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, i64 %17) |
| ret void |
| } |