# RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o - %s | FileCheck %s
# This test ensures that the MIR parser parses the callee saved register mask
# correctly and that the MIR parser can infer it as well.

--- |

  define i32 @compute(i32 %a) #0 {
  body:
    %c = mul i32 %a, 11
    ret i32 %c
  }

  define i32 @foo(i32 %a) #0 {
  entry:
    %b = call i32 @compute(i32 %a)
    ret i32 %b
  }

  define i32 @bar(i32 %a) #0 {
  entry:
    %b = call i32 @compute(i32 %a)
    ret i32 %b
  }

  define i32 @empty(i32 %a) #0 {
  entry:
    %b = call i32 @compute(i32 %a)
    ret i32 %b
  }

  attributes #0 = { "no-frame-pointer-elim"="false" }

...
---
# CHECK: name: compute
# CHECK: liveins:
# CHECK-NEXT: - { reg: '%edi' }
# CHECK-NEXT: frameInfo:
name:            compute
liveins:
  - { reg: '%edi' }
frameInfo:
  stackSize:     8
body: |
  bb.0.body:
    liveins: %edi

    %eax = IMUL32rri8 %edi, 11, implicit-def %eflags
    RETQ %eax
...
---
name:            foo
liveins:
  - { reg: '%edi' }
# CHECK: name: foo
# CHECK: calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx',
# CHECK-NEXT:                    '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15',
# CHECK-NEXT:                    '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d',
# CHECK-NEXT:                    '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ]
calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx',
                        '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15',
                        '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d',
                        '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ]
body: |
  bb.0.entry:
    liveins: %edi

    PUSH64r %rax, implicit-def %rsp, implicit %rsp
    CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax
    %rdx = POP64r implicit-def %rsp, implicit %rsp
    RETQ %eax
...
---
name:            bar
liveins:
  - { reg: '%edi' }
# Verify that the callee saved register can be inferred from register mask
# machine operands:
# CHECK: name: bar
# CHECK: calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx',
# CHECK-NEXT:                    '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15',
# CHECK-NEXT:                    '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d',
# CHECK-NEXT:                    '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ]
body: |
  bb.0.entry:
    liveins: %edi

    PUSH64r %rax, implicit-def %rsp, implicit %rsp
    CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax
    %rdx = POP64r implicit-def %rsp, implicit %rsp
    RETQ %eax
...
---
name:            empty
liveins:
  - { reg: '%edi' }
# Verify that the callee saved register can be empty.
# CHECK: name: empty
# CHECK: calleeSavedRegisters: [ ]
calleeSavedRegisters: [ ]
body: |
  bb.0.entry:
    liveins: %edi

    PUSH64r %rax, implicit-def %rsp, implicit %rsp
    CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax
    %rdx = POP64r implicit-def %rsp, implicit %rsp
    RETQ %eax
...