llvm/llvm/test/CodeGen/AMDGPU/lower-control-flow-live-intervals.mir

# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
# RUN: llc -run-pass=liveintervals -run-pass=si-lower-control-flow -mtriple=amdgcn--amdpal -mcpu=gfx1030 -verify-machineinstrs -o - %s | FileCheck %s

# Check that verifier passes for the following.

# Caused: Live segment doesn't end at a valid instruction
---
name:            _amdgpu_cs_main1
tracksRegLiveness: true
body:             |
  ; CHECK-LABEL: name: _amdgpu_cs_main1
  ; CHECK: bb.0:
  ; CHECK-NEXT:   successors: %bb.2(0x40000000), %bb.3(0x40000000)
  ; CHECK-NEXT:   liveins: $vgpr0
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
  ; CHECK-NEXT:   [[V_CMP_NE_U32_e64_:%[0-9]+]]:sreg_32 = V_CMP_NE_U32_e64 0, [[COPY]], implicit $exec
  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:sreg_32 = COPY $exec_lo, implicit-def $exec_lo
  ; CHECK-NEXT:   [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], [[V_CMP_NE_U32_e64_]], implicit-def dead $scc
  ; CHECK-NEXT:   [[S_XOR_B32_:%[0-9]+]]:sreg_32 = S_XOR_B32 [[S_AND_B32_]], [[COPY1]], implicit-def dead $scc
  ; CHECK-NEXT:   $exec_lo = S_MOV_B32_term [[S_AND_B32_]]
  ; CHECK-NEXT:   S_CBRANCH_EXECZ %bb.3, implicit $exec
  ; CHECK-NEXT:   S_BRANCH %bb.2
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.1:
  ; CHECK-NEXT:   $exec_lo = S_OR_B32 $exec_lo, %3, implicit-def $scc
  ; CHECK-NEXT:   S_ENDPGM 0
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.2:
  ; CHECK-NEXT:   successors: %bb.3(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.3:
  ; CHECK-NEXT:   successors: %bb.4(0x40000000), %bb.1(0x40000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[S_OR_SAVEEXEC_B32_:%[0-9]+]]:sreg_32 = S_OR_SAVEEXEC_B32 [[S_XOR_B32_]], implicit-def $exec, implicit-def $scc, implicit $exec
  ; CHECK-NEXT:   [[S_AND_B32_1:%[0-9]+]]:sreg_32 = S_AND_B32 $exec_lo, [[S_OR_SAVEEXEC_B32_]], implicit-def $scc
  ; CHECK-NEXT:   $exec_lo = S_XOR_B32_term $exec_lo, [[S_AND_B32_1]], implicit-def $scc
  ; CHECK-NEXT:   S_CBRANCH_EXECZ %bb.1, implicit $exec
  ; CHECK-NEXT:   S_BRANCH %bb.4
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.4:
  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   S_BRANCH %bb.1
  bb.0:
    successors: %bb.2(0x40000000), %bb.3(0x40000000)
    liveins: $vgpr0

    %2:vgpr_32 = COPY killed $vgpr0
    %6:sreg_32 = V_CMP_NE_U32_e64 0, killed %2, implicit $exec
    %0:sreg_32 = SI_IF killed %6, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_BRANCH %bb.2

  bb.1:
    SI_END_CF killed %1, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_ENDPGM 0

  bb.2:
    successors: %bb.3(0x80000000)


  bb.3:
    successors: %bb.4(0x40000000), %bb.1(0x40000000)

    %1:sreg_32 = SI_ELSE killed %0, %bb.1, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_BRANCH %bb.4

  bb.4:
    successors: %bb.1(0x80000000)

    S_BRANCH %bb.1

...

# Caused: Assertion `itr != mi2iMap.end() && "Instruction not in maps."' failed.
---
name:            _amdgpu_cs_main2
tracksRegLiveness: true
body:             |
  ; CHECK-LABEL: name: _amdgpu_cs_main2
  ; CHECK: bb.0:
  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
  ; CHECK-NEXT:   liveins: $vgpr0
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
  ; CHECK-NEXT:   [[V_CMP_GT_I32_e64_:%[0-9]+]]:sreg_32 = V_CMP_GT_I32_e64 1, [[COPY]], implicit $exec
  ; CHECK-NEXT:   [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0
  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:sreg_32 = COPY [[S_MOV_B32_]]
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.1:
  ; CHECK-NEXT:   successors: %bb.2(0x04000000), %bb.1(0x7c000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:sreg_32 = COPY [[COPY1]]
  ; CHECK-NEXT:   [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 $exec_lo, [[V_CMP_GT_I32_e64_]], implicit-def $scc
  ; CHECK-NEXT:   [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_AND_B32_]], [[COPY2]], implicit-def $scc
  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:sreg_32 = COPY [[S_OR_B32_]]
  ; CHECK-NEXT:   $exec_lo = S_ANDN2_B32_term $exec_lo, [[S_OR_B32_]], implicit-def $scc
  ; CHECK-NEXT:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
  ; CHECK-NEXT:   S_BRANCH %bb.2
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.2:
  ; CHECK-NEXT:   $exec_lo = S_OR_B32 $exec_lo, [[S_OR_B32_]], implicit-def $scc
  ; CHECK-NEXT:   S_ENDPGM 0
  bb.0:
    successors: %bb.1(0x80000000)
    liveins: $vgpr0

    %4:vgpr_32 = COPY killed $vgpr0
    %8:sreg_32 = V_CMP_GT_I32_e64 1, killed %4, implicit $exec
    %6:sreg_32 = S_MOV_B32 0
    %10:sreg_32 = COPY killed %6

  bb.1:
    successors: %bb.2(0x04000000), %bb.1(0x7c000000)

    %1:sreg_32 = COPY killed %10
    %2:sreg_32 = SI_IF_BREAK %8, killed %1, implicit-def dead $scc
    %10:sreg_32 = COPY %2
    SI_LOOP %2, %bb.1, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_BRANCH %bb.2

  bb.2:
    SI_END_CF killed %2, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_ENDPGM 0

...

# Caused: Live range continues after kill flag
---
name:            _amdgpu_cs_main3
tracksRegLiveness: true
body:             |
  ; CHECK-LABEL: name: _amdgpu_cs_main3
  ; CHECK: bb.0:
  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.4(0x40000000)
  ; CHECK-NEXT:   liveins: $vgpr0
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
  ; CHECK-NEXT:   [[V_CMP_NGT_F32_e64_:%[0-9]+]]:sreg_32 = nofpexcept V_CMP_NGT_F32_e64 0, 0, 0, [[COPY]], 0, implicit $mode, implicit $exec
  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:sreg_32 = COPY $exec_lo, implicit-def $exec_lo
  ; CHECK-NEXT:   [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], [[V_CMP_NGT_F32_e64_]], implicit-def dead $scc
  ; CHECK-NEXT:   $exec_lo = S_MOV_B32_term [[S_AND_B32_]]
  ; CHECK-NEXT:   S_CBRANCH_EXECZ %bb.4, implicit $exec
  ; CHECK-NEXT:   S_BRANCH %bb.1
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.1:
  ; CHECK-NEXT:   successors: %bb.2(0x40000000), %bb.4(0x40000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[V_CMP_NLT_F32_e64_:%[0-9]+]]:sreg_32 = nofpexcept V_CMP_NLT_F32_e64 0, 0, 0, [[COPY]], 0, implicit $mode, implicit $exec
  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:sreg_32 = COPY $exec_lo, implicit-def $exec_lo
  ; CHECK-NEXT:   [[S_AND_B32_1:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY2]], [[V_CMP_NLT_F32_e64_]], implicit-def dead $scc
  ; CHECK-NEXT:   $exec_lo = S_MOV_B32_term [[S_AND_B32_1]]
  ; CHECK-NEXT:   S_CBRANCH_EXECZ %bb.4, implicit $exec
  ; CHECK-NEXT:   S_BRANCH %bb.2
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.2:
  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.4:
  ; CHECK-NEXT:   $exec_lo = S_OR_B32 $exec_lo, [[COPY1]], implicit-def $scc
  ; CHECK-NEXT:   S_ENDPGM 0
  bb.0:
    successors: %bb.1(0x40000000), %bb.4(0x40000000)
    liveins: $vgpr0

    %2:vgpr_32 = COPY killed $vgpr0
    %5:sreg_32 = nofpexcept V_CMP_NGT_F32_e64 0, 0, 0, %2, 0, implicit $mode, implicit $exec
    %0:sreg_32 = SI_IF killed %5, %bb.4, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_BRANCH %bb.1

  bb.1:
    successors: %bb.2(0x40000000), %bb.3(0x40000000)

    %7:sreg_32 = nofpexcept V_CMP_NLT_F32_e64 0, 0, 0, killed %2, 0, implicit $mode, implicit $exec
    %1:sreg_32 = SI_IF killed %7, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_BRANCH %bb.2

  bb.2:
    successors: %bb.3(0x80000000)


  bb.3:
    successors: %bb.4(0x80000000)

    SI_END_CF killed %1, implicit-def dead $exec, implicit-def dead $scc, implicit $exec

  bb.4:
    SI_END_CF killed %0, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_ENDPGM 0

...

# Caused: Live range continues after dead def flag
---
name:            _amdgpu_cs_main4
tracksRegLiveness: true
body:             |
  ; CHECK-LABEL: name: _amdgpu_cs_main4
  ; CHECK: bb.0:
  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.5(0x40000000)
  ; CHECK-NEXT:   liveins: $vgpr0
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
  ; CHECK-NEXT:   [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0
  ; CHECK-NEXT:   [[V_CMP_NE_U32_e64_:%[0-9]+]]:sreg_32 = V_CMP_NE_U32_e64 0, [[COPY]], implicit $exec
  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:sreg_32 = COPY $exec_lo, implicit-def $exec_lo
  ; CHECK-NEXT:   [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], [[V_CMP_NE_U32_e64_]], implicit-def dead $scc
  ; CHECK-NEXT:   $exec_lo = S_MOV_B32_term [[S_AND_B32_]]
  ; CHECK-NEXT:   S_CBRANCH_EXECZ %bb.5, implicit $exec
  ; CHECK-NEXT:   S_BRANCH %bb.1
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.1:
  ; CHECK-NEXT:   successors: %bb.6(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:sreg_32 = COPY $exec_lo
  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:sreg_32 = COPY [[COPY2]]
  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:sreg_32 = COPY [[S_MOV_B32_]]
  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:sreg_32 = COPY [[COPY3]]
  ; CHECK-NEXT:   S_BRANCH %bb.6
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.2:
  ; CHECK-NEXT:   successors: %bb.5(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE %9, %subreg.sub0, %9, %subreg.sub1, %9, %subreg.sub2, %9, %subreg.sub3
  ; CHECK-NEXT:   [[COPY6:%[0-9]+]]:vgpr_32 = COPY %11
  ; CHECK-NEXT:   BUFFER_ATOMIC_ADD_OFFSET [[COPY6]], [[REG_SEQUENCE]], 0, 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 8)
  ; CHECK-NEXT:   S_BRANCH %bb.5
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.4:
  ; CHECK-NEXT:   S_ENDPGM 0
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.5:
  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   $exec_lo = S_OR_B32 $exec_lo, [[COPY1]], implicit-def $scc
  ; CHECK-NEXT:   S_BRANCH %bb.4
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.6:
  ; CHECK-NEXT:   successors: %bb.7(0x04000000), %bb.6(0x7c000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY7:%[0-9]+]]:sreg_32 = COPY [[COPY4]]
  ; CHECK-NEXT:   [[COPY8:%[0-9]+]]:sreg_32 = COPY [[COPY5]]
  ; CHECK-NEXT:   [[S_FF1_I32_B32_:%[0-9]+]]:sreg_32 = S_FF1_I32_B32 [[COPY8]]
  ; CHECK-NEXT:   [[V_READLANE_B32_:%[0-9]+]]:sreg_32 = V_READLANE_B32 [[COPY]], [[S_FF1_I32_B32_]]
  ; CHECK-NEXT:   [[S_ADD_I32_:%[0-9]+]]:sreg_32 = S_ADD_I32 [[COPY7]], [[V_READLANE_B32_]], implicit-def dead $scc
  ; CHECK-NEXT:   [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 1, [[S_FF1_I32_B32_]], implicit-def dead $scc
  ; CHECK-NEXT:   [[S_ANDN2_B32_:%[0-9]+]]:sreg_32 = S_ANDN2_B32 [[COPY8]], [[S_LSHL_B32_]], implicit-def dead $scc
  ; CHECK-NEXT:   S_CMP_LG_U32 [[S_ANDN2_B32_]], 0, implicit-def $scc
  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:sreg_32 = COPY [[S_ADD_I32_]]
  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:sreg_32 = COPY [[S_ANDN2_B32_]]
  ; CHECK-NEXT:   S_CBRANCH_SCC1 %bb.6, implicit killed $scc
  ; CHECK-NEXT:   S_BRANCH %bb.7
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.7:
  ; CHECK-NEXT:   successors: %bb.2(0x40000000), %bb.5(0x40000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 0
  ; CHECK-NEXT:   [[V_MBCNT_LO_U32_B32_e64_:%[0-9]+]]:vgpr_32 = V_MBCNT_LO_U32_B32_e64 [[COPY2]], 0, implicit $exec
  ; CHECK-NEXT:   [[V_CMP_EQ_U32_e64_:%[0-9]+]]:sreg_32 = V_CMP_EQ_U32_e64 0, [[V_MBCNT_LO_U32_B32_e64_]], implicit $exec
  ; CHECK-NEXT:   [[COPY9:%[0-9]+]]:sreg_32 = COPY $exec_lo, implicit-def $exec_lo
  ; CHECK-NEXT:   [[S_AND_B32_1:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY9]], [[V_CMP_EQ_U32_e64_]], implicit-def dead $scc
  ; CHECK-NEXT:   dead [[S_XOR_B32_:%[0-9]+]]:sreg_32 = S_XOR_B32 [[S_AND_B32_1]], [[COPY9]], implicit-def dead $scc
  ; CHECK-NEXT:   $exec_lo = S_MOV_B32_term [[S_AND_B32_1]]
  ; CHECK-NEXT:   S_CBRANCH_EXECZ %bb.5, implicit $exec
  ; CHECK-NEXT:   S_BRANCH %bb.2
  bb.0:
    successors: %bb.1(0x40000000), %bb.5(0x40000000)
    liveins: $vgpr0

    %8:vgpr_32 = COPY killed $vgpr0
    %10:sreg_32 = S_MOV_B32 0
    %11:sreg_32 = V_CMP_NE_U32_e64 0, %8, implicit $exec
    %0:sreg_32 = SI_IF killed %11, %bb.5, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_BRANCH %bb.1

  bb.1:
    successors: %bb.6(0x80000000)

    %13:sreg_32 = COPY $exec_lo
    %1:sreg_32 = COPY %13
    %25:sreg_32 = COPY killed %10
    %26:sreg_32 = COPY killed %1
    S_BRANCH %bb.6

  bb.2:
    successors: %bb.3(0x80000000)

    %23:sgpr_128 = REG_SEQUENCE killed %19, %subreg.sub0, %19, %subreg.sub1, %19, %subreg.sub2, %19, %subreg.sub3
    %24:vgpr_32 = COPY killed %4
    BUFFER_ATOMIC_ADD_OFFSET killed %24, killed %23, 0, 0, 0, implicit $exec :: (volatile dereferenceable load store (s32), align 1, addrspace 8)

  bb.3:
    successors: %bb.5(0x80000000)

    SI_END_CF killed %7, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_BRANCH %bb.5

  bb.4:
    S_ENDPGM 0

  bb.5:
    successors: %bb.4(0x80000000)

    SI_END_CF killed %0, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_BRANCH %bb.4

  bb.6:
    successors: %bb.7(0x04000000), %bb.6(0x7c000000)

    %2:sreg_32 = COPY killed %25
    %3:sreg_32 = COPY killed %26
    %14:sreg_32 = S_FF1_I32_B32 %3
    %15:sreg_32 = V_READLANE_B32 %8, %14
    %4:sreg_32 = S_ADD_I32 killed %2, killed %15, implicit-def dead $scc
    %17:sreg_32 = S_LSHL_B32 1, killed %14, implicit-def dead $scc
    %5:sreg_32 = S_ANDN2_B32 killed %3, killed %17, implicit-def dead $scc
    S_CMP_LG_U32 %5, 0, implicit-def $scc
    %25:sreg_32 = COPY %4
    %26:sreg_32 = COPY killed %5
    S_CBRANCH_SCC1 %bb.6, implicit killed $scc
    S_BRANCH %bb.7

  bb.7:
    successors: %bb.2(0x40000000), %bb.3(0x40000000)

    %19:sreg_32 = S_MOV_B32 0
    %20:vgpr_32 = V_MBCNT_LO_U32_B32_e64 killed %13, 0, implicit $exec
    %21:sreg_32 = V_CMP_EQ_U32_e64 0, killed %20, implicit $exec
    %7:sreg_32 = SI_IF killed %21, %bb.3, implicit-def dead $exec, implicit-def dead $scc, implicit $exec
    S_BRANCH %bb.2

...