llvm/llvm/test/CodeGen/X86/switch-jmp-edge-split.mir

# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=x86_64-- -run-pass=machine-sink -verify-machineinstrs  -o - %s | FileCheck %s

---
name:            func_no_pic
tracksRegLiveness: true
jumpTable:
  kind:            block-address
  entries:
    - id:              0
      blocks:          [ '%bb.4', '%bb.1', '%bb.2', '%bb.3' ]
body:             |
  ; CHECK-LABEL: name: func_no_pic
  ; CHECK: bb.0:
  ; CHECK-NEXT:   successors: %bb.5(0x20000000), %bb.1(0x20000000), %bb.2(0x20000000), %bb.3(0x20000000)
  ; CHECK-NEXT:   liveins: $edi
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr64_nosp = COPY $rdi
  ; CHECK-NEXT:   JMP64m $noreg, 8, [[COPY]], %jump-table.0, $noreg :: (load (s64) from jump-table)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.5:
  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42
  ; CHECK-NEXT:   JMP_1 %bb.4
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.1:
  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 6
  ; CHECK-NEXT:   JMP_1 %bb.4
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.2:
  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri2:%[0-9]+]]:gr32 = MOV32ri 1
  ; CHECK-NEXT:   JMP_1 %bb.4
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.3:
  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri3:%[0-9]+]]:gr32 = MOV32ri 92
  ; CHECK-NEXT:   JMP_1 %bb.4
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.4:
  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gr32 = PHI [[MOV32ri]], %bb.5, [[MOV32ri1]], %bb.1, [[MOV32ri2]], %bb.2, [[MOV32ri3]], %bb.3
  ; CHECK-NEXT:   $eax = COPY [[PHI]]
  ; CHECK-NEXT:   RET 0
  bb.0:
    successors: %bb.4, %bb.1, %bb.2, %bb.3
    liveins: $edi

    %0:gr64_nosp = COPY $rdi
    ; MachineSink should split the critical edges and sink the next two
    ; insns out of the switch-jump header into new less frequently executed
    ; blocks.
    %1:gr32 = MOV32ri 42
    JMP64m $noreg, 8, %0, %jump-table.0, $noreg :: (load (s64) from jump-table)

  bb.1:
    %2:gr32 = MOV32ri 6
    JMP_1 %bb.4

  bb.2:
    %3:gr32 = MOV32ri 1
    JMP_1 %bb.4

  bb.3:
    %4:gr32 = MOV32ri 92
    JMP_1 %bb.4

  bb.4:
    %5:gr32 = PHI %1, %bb.0, %2, %bb.1, %3, %bb.2, %4, %bb.3
    $eax = COPY %5
    RET 0

...
---
name:            func_pic
tracksRegLiveness: true
jumpTable:
  kind:            label-difference32
  entries:
    - id:              0
      blocks:          [ '%bb.4', '%bb.1', '%bb.2', '%bb.3' ]
body:             |
  ; CHECK-LABEL: name: func_pic
  ; CHECK: bb.0:
  ; CHECK-NEXT:   successors: %bb.5(0x20000000), %bb.1(0x20000000), %bb.2(0x20000000), %bb.3(0x20000000)
  ; CHECK-NEXT:   liveins: $edi
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr64_nosp = COPY $rdi
  ; CHECK-NEXT:   [[LEA64r:%[0-9]+]]:gr64 = LEA64r $rip, 1, $noreg, %jump-table.0, $noreg
  ; CHECK-NEXT:   [[MOVSX64rm32_:%[0-9]+]]:gr64 = MOVSX64rm32 [[LEA64r]], 4, [[COPY]], 0, $noreg :: (load (s32) from jump-table)
  ; CHECK-NEXT:   [[ADD64rr:%[0-9]+]]:gr64 = ADD64rr [[MOVSX64rm32_]], [[LEA64r]], implicit-def dead $eflags
  ; CHECK-NEXT:   JMP64r killed [[ADD64rr]]
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.5:
  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42
  ; CHECK-NEXT:   JMP_1 %bb.4
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.1:
  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 6
  ; CHECK-NEXT:   JMP_1 %bb.4
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.2:
  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri2:%[0-9]+]]:gr32 = MOV32ri 1
  ; CHECK-NEXT:   JMP_1 %bb.4
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.3:
  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri3:%[0-9]+]]:gr32 = MOV32ri 92
  ; CHECK-NEXT:   JMP_1 %bb.4
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.4:
  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gr32 = PHI [[MOV32ri]], %bb.5, [[MOV32ri1]], %bb.1, [[MOV32ri2]], %bb.2, [[MOV32ri3]], %bb.3
  ; CHECK-NEXT:   $eax = COPY [[PHI]]
  ; CHECK-NEXT:   RET 0
  bb.0:
    successors: %bb.4, %bb.1, %bb.2, %bb.3
    liveins: $edi

    %0:gr64_nosp = COPY $rdi
    ; MachineSink should split the critical edges and sink the next two
    ; insns out of the switch-jump header into new less frequently executed
    ; blocks.
    %1:gr32 = MOV32ri 42
    %2:gr64 = LEA64r $rip, 1, $noreg, %jump-table.0, $noreg
    %3:gr64 = MOVSX64rm32 %2, 4, %0, 0, $noreg :: (load (s32) from jump-table)
    %4:gr64 = ADD64rr %3, %2, implicit-def dead $eflags
    JMP64r killed %4

  bb.1:
    %5:gr32 = MOV32ri 6
    JMP_1 %bb.4

  bb.2:
    %6:gr32 = MOV32ri 1
    JMP_1 %bb.4

  bb.3:
    %7:gr32 = MOV32ri 92
    JMP_1 %bb.4

  bb.4:
    %8:gr32 = PHI %1, %bb.0, %5, %bb.1, %6, %bb.2, %7, %bb.3
    $eax = COPY %8
    RET 0

...
---
name:            multiple_jump_table_users
tracksRegLiveness: true
jumpTable:
  kind:            block-address
  entries:
    - id:              0
      blocks:          [ '%bb.6', '%bb.3', '%bb.4', '%bb.5' ]
body:             |
  ; CHECK-LABEL: name: multiple_jump_table_users
  ; CHECK: bb.0:
  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
  ; CHECK-NEXT:   liveins: $edi
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr64_nosp = COPY $rdi
  ; CHECK-NEXT:   CMP64ri8 [[COPY]], 42, implicit-def $eflags
  ; CHECK-NEXT:   JCC_1 %bb.1, 15, implicit $eflags
  ; CHECK-NEXT:   JMP_1 %bb.2
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.1:
  ; CHECK-NEXT:   successors: %bb.6(0x20000000), %bb.3(0x20000000), %bb.4(0x20000000), %bb.5(0x20000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */
  ; CHECK-NEXT:   [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 13
  ; CHECK-NEXT:   JMP64m $noreg, 8, [[COPY]], %jump-table.0, $noreg :: (load (s64) from jump-table)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.2:
  ; CHECK-NEXT:   successors: %bb.6(0x20000000), %bb.3(0x20000000), %bb.4(0x20000000), %bb.5(0x20000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */
  ; CHECK-NEXT:   [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 42
  ; CHECK-NEXT:   JMP64m $noreg, 8, [[COPY]], %jump-table.0, $noreg :: (load (s64) from jump-table)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.3:
  ; CHECK-NEXT:   successors: %bb.6(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri2:%[0-9]+]]:gr32 = MOV32ri 6
  ; CHECK-NEXT:   JMP_1 %bb.6
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.4:
  ; CHECK-NEXT:   successors: %bb.6(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri3:%[0-9]+]]:gr32 = MOV32ri 1
  ; CHECK-NEXT:   JMP_1 %bb.6
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.5:
  ; CHECK-NEXT:   successors: %bb.6(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[MOV32ri4:%[0-9]+]]:gr32 = MOV32ri 92
  ; CHECK-NEXT:   JMP_1 %bb.6
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.6:
  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gr32 = PHI [[MOV32ri]], %bb.1, [[MOV32ri1]], %bb.2, [[MOV32ri2]], %bb.3, [[MOV32ri3]], %bb.4, [[MOV32ri4]], %bb.5
  ; CHECK-NEXT:   $eax = COPY [[PHI]]
  ; CHECK-NEXT:   RET 0
  bb.0:
    liveins: $edi
    %0:gr64_nosp = COPY $rdi

    CMP64ri8 %0:gr64_nosp, 42, implicit-def $eflags
    JCC_1 %bb.1, 15, implicit $eflags
    JMP_1 %bb.2

  bb.1:
    successors: %bb.6, %bb.3, %bb.4, %bb.5
    INLINEASM &"", 1 /* sideeffect attdialect */
    %1:gr32 = MOV32ri 13
    JMP64m $noreg, 8, %0, %jump-table.0, $noreg :: (load (s64) from jump-table)

  bb.2:
    successors: %bb.6, %bb.3, %bb.4, %bb.5
    INLINEASM &"", 1 /* sideeffect attdialect */
    %2:gr32 = MOV32ri 42
    ; This is a 2d user of jump-table.0 . This case is not supported yet;
    ; Should not attempt edge splitting.
    JMP64m $noreg, 8, %0, %jump-table.0, $noreg :: (load (s64) from jump-table)

  bb.3:
    %3:gr32 = MOV32ri 6
    JMP_1 %bb.6

  bb.4:
    %4:gr32 = MOV32ri 1
    JMP_1 %bb.6

  bb.5:
    %5:gr32 = MOV32ri 92
    JMP_1 %bb.6

  bb.6:
    %6:gr32 = PHI %1, %bb.1, %2, %bb.2, %3, %bb.3, %4, %bb.4, %5, %bb.5
    $eax = COPY %6
    RET 0
...