<commit_before>; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -loop-simplifycfg < %s | FileCheck %s
; RUN: opt -S -passes='require<domtree>,loop(simplify-cfg)' < %s | FileCheck %s
; RUN: opt -S -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"

; Make sure that we can eliminate a provably dead backedge.
define i32 @dead_backedge_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_backedge_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_BE:%.*]], [[HEADER_BACKEDGE:%.*]] ]
; CHECK-NEXT:    [[I_1:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I_1]], 100
; CHECK-NEXT:    br i1 [[CMP1]], label [[HEADER_BACKEDGE]], label [[DEAD_BACKEDGE:%.*]]
; CHECK:       header.backedge:
; CHECK-NEXT:    [[I_BE]] = phi i32 [ [[I_1]], [[HEADER]] ], [ [[I_2:%.*]], [[DEAD_BACKEDGE]] ]
; CHECK-NEXT:    br label [[HEADER]]
; CHECK:       dead_backedge:
; CHECK-NEXT:    [[I_2]] = add i32 [[I_1]], 10
; CHECK-NEXT:    br i1 false, label [[HEADER_BACKEDGE]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_2_LCSSA:%.*]] = phi i32 [ [[I_2]], [[DEAD_BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_2_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.1, %header], [%i.2, %dead_backedge]
  %i.1 = add i32 %i, 1
  %cmp1 = icmp slt i32 %i.1, 100
  br i1 %cmp1, label %header, label %dead_backedge

dead_backedge:
  %i.2 = add i32 %i.1, 10
  br i1 false, label %header, label %exit

exit:
  ret i32 %i.2
}

; Check that we can eliminate a triangle.
define i32 @dead_block_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_block_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %backedge, label %dead

dead:
  %i.2 = add i32 %i, 1
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dead]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we can eliminate dead branches of a switch.
define i32 @dead_block_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_block_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD]]
; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
; CHECK-NEXT:    i32 2, label [[DEAD]]
; CHECK-NEXT:    ]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead [i32 0, label %dead
  i32 1, label %backedge
  i32 2, label %dead]

dead:
  %i.2 = add i32 %i, 1
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dead]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit
exit:
  ret i32 %i.inc
}

; Check that we can eliminate several dead blocks.
define i32 @dead_block_propogate_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_block_propogate_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %backedge, label %dead

dead:
  %i.2 = add i32 %i, 1
  br label %dummy

dummy:
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we can eliminate several blocks while removing a switch.
define i32 @dead_block_propogate_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_block_propogate_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD]]
; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
; CHECK-NEXT:    i32 2, label [[DEAD]]
; CHECK-NEXT:    ]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead [i32 0, label %dead
  i32 1, label %backedge
  i32 2, label %dead]

dead:
  %i.2 = add i32 %i, 1
  br label %dummy

dummy:
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we preserve static reachibility of a dead exit block while deleting
; a branch.
define i32 @dead_exit_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_exit_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
; CHECK:       dead:
; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[HEADER]] ]
; CHECK-NEXT:    br label [[DUMMY:%.*]]
; CHECK:       dummy:
; CHECK-NEXT:    br label [[EXIT:%.*]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK:       exit.loopexit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    br label [[EXIT]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I_LCSSA]], [[DUMMY]] ], [ [[I_INC_LCSSA]], [[EXIT_LOOPEXIT]] ]
; CHECK-NEXT:    ret i32 [[I_1]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %backedge, label %dead

dead:
  br label %dummy

dummy:
  br label %exit

backedge:
  %i.inc = add i32 %i, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  %i.1 = phi i32 [%i.inc, %backedge], [%i, %dummy]
  ret i32 %i.1
}

; Check that we preserve static reachibility of a dead exit block while deleting
; a switch.
define i32 @dead_exit_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_exit_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD]]
; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
; CHECK-NEXT:    i32 2, label [[DEAD]]
; CHECK-NEXT:    ]
; CHECK:       dead:
; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I]], [[HEADER]] ], [ [[I]], [[HEADER]] ]
; CHECK-NEXT:    br label [[DUMMY:%.*]]
; CHECK:       dummy:
; CHECK-NEXT:    br label [[EXIT:%.*]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK:       exit.loopexit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    br label [[EXIT]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I_LCSSA]], [[DUMMY]] ], [ [[I_INC_LCSSA]], [[EXIT_LOOPEXIT]] ]
; CHECK-NEXT:    ret i32 [[I_1]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead [i32 0, label %dead
  i32 1, label %backedge
  i32 2, label %dead]

dead:
  br label %dummy

dummy:
  br label %exit

backedge:
  %i.inc = add i32 %i, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  %i.1 = phi i32 [%i.inc, %backedge], [%i, %dummy]
  ret i32 %i.1
}

; Check that we can completely eliminate the current loop, branch case.
define i32 @dead_loop_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_loop_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 false, label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %backedge, label %dead

dead:
  %i.2 = add i32 %i, 1
  br label %dummy

dummy:
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 false, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we can completely eliminate the current loop, switch case.
define i32 @dead_loop_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_loop_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD]]
; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
; CHECK-NEXT:    i32 2, label [[DEAD]]
; CHECK-NEXT:    ]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 false, label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header
header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead [i32 0, label %dead
  i32 1, label %backedge
  i32 2, label %dead]
dead:
  %i.2 = add i32 %i, 1
  br label %dummy

dummy:
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 false, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we can delete a dead inner loop entirely.
define i32 @dead_sub_loop_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_sub_loop_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[LIVE_PREHEADER:%.*]], label [[DEAD_PREHEADER:%.*]]
; CHECK:       live_preheader:
; CHECK-NEXT:    br label [[LIVE_LOOP:%.*]]
; CHECK:       live_loop:
; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 0, [[LIVE_PREHEADER]] ], [ [[A_INC:%.*]], [[LIVE_LOOP]] ]
; CHECK-NEXT:    [[A_INC]] = add i32 [[A]], 1
; CHECK-NEXT:    [[CMP_A:%.*]] = icmp slt i32 [[A_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP_A]], label [[LIVE_LOOP]], label [[EXIT_A:%.*]]
; CHECK:       exit.a:
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       dead_preheader:
; CHECK-NEXT:    br label [[DEAD_LOOP:%.*]]
; CHECK:       dead_loop:
; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 0, [[DEAD_PREHEADER]] ], [ [[B_INC:%.*]], [[DEAD_LOOP]] ]
; CHECK-NEXT:    [[B_INC]] = add i32 [[B]], 1
; CHECK-NEXT:    [[CMP_B:%.*]] = icmp slt i32 [[B_INC]], [[END]]
; CHECK-NEXT:    br i1 [[CMP_B]], label [[DEAD_LOOP]], label [[EXIT_B:%.*]]
; CHECK:       exit.b:
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %live_preheader, label %dead_preheader

live_preheader:
  br label %live_loop

live_loop:
  %a = phi i32 [0, %live_preheader], [%a.inc, %live_loop]
  %a.inc = add i32 %a, 1
  %cmp.a = icmp slt i32 %a.inc, %end
  br i1 %cmp.a, label %live_loop, label %exit.a

exit.a:
  br label %backedge

dead_preheader:
  br label %dead_loop

dead_loop:
  %b = phi i32 [0, %dead_preheader], [%b.inc, %dead_loop]
  %b.inc = add i32 %b, 1
  %cmp.b = icmp slt i32 %b.inc, %end
  br i1 %cmp.b, label %dead_loop, label %exit.b

exit.b:
  br label %backedge

backedge:
  %i.inc = add i32 %i, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

define i32 @dead_sub_loop_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_sub_loop_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD_PREHEADER:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD_PREHEADER]]
; CHECK-NEXT:    i32 1, label [[LIVE_PREHEADER:%.*]]
; CHECK-NEXT:    i32 2, label [[DEAD_PREHEADER]]
; CHECK-NEXT:    ]
; CHECK:       live_preheader:
; CHECK-NEXT:    br label [[LIVE_LOOP:%.*]]
; CHECK:       live_loop:
; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 0, [[LIVE_PREHEADER]] ], [ [[A_INC:%.*]], [[LIVE_LOOP]] ]
; CHECK-NEXT:    [[A_INC]] = add i32 [[A]], 1
; CHECK-NEXT:    [[CMP_A:%.*]] = icmp slt i32 [[A_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP_A]], label [[LIVE_LOOP]], label [[EXIT_A:%.*]]
; CHECK:       exit.a:
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       dead_preheader:
; CHECK-NEXT:    br label [[DEAD_LOOP:%.*]]
; CHECK:       dead_loop:
; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 0, [[DEAD_PREHEADER]] ], [ [[B_INC:%.*]], [[DEAD_LOOP]] ]
; CHECK-NEXT:    [[B_INC]] = add i32 [[B]], 1
; CHECK-NEXT:    [[CMP_B:%.*]] = icmp slt i32 [[B_INC]], [[END]]
; CHECK-NEXT:    br i1 [[CMP_B]], label [[DEAD_LOOP]], label [[EXIT_B:%.*]]
; CHECK:       exit.b:
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead_preheader [i32 0, label %dead_preheader
  i32 1, label %live_preheader
  i32 2, label %dead_preheader]

live_preheader:
  br label %live_loop

live_loop:
  %a = phi i32 [0, %live_preheader], [%a.inc, %live_loop]
  %a.inc = add i32 %a, 1
  %cmp.a = icmp slt i32 %a.inc, %end
  br i1 %cmp.a, label %live_loop, label %exit.a

exit.a:
  br label %backedge

dead_preheader:
  br label %dead_loop

dead_loop:
  %b = phi i32 [0, %dead_preheader], [%b.inc, %dead_loop]
  %b.inc = add i32 %b, 1
  %cmp.b = icmp slt i32 %b.inc, %end
  br i1 %cmp.b, label %dead_loop, label %exit.b

exit.b:
  br label %backedge

backedge:
  %i.inc = add i32 %i, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we preserve static reachability of an exit block even if we prove
; that the loop is infinite. Branch case.
define i32 @inf_loop_test_branch_loop(i32 %end) {
; CHECK-LABEL: @inf_loop_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 true, label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %backedge, label %dead

dead:
  %i.2 = add i32 %i, 1
  br label %dummy

dummy:
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 true, label %header, label %exit

exit:
  ret i32 %i.inc
}

define i32 @inf_loop_test_switch_loop(i32 %end) {
; CHECK-LABEL: @inf_loop_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD]]
; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
; CHECK-NEXT:    i32 2, label [[DEAD]]
; CHECK-NEXT:    ]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 true, label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header
header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead [i32 0, label %dead
  i32 1, label %backedge
  i32 2, label %dead]
dead:
  %i.2 = add i32 %i, 1
  br label %dummy
dummy:
  br label %backedge
backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 true, label %header, label %exit
exit:
  ret i32 %i.inc
}

; Check that when the block is not actually dead, we don't remove it.
define i32 @no_live_block_test_branch_loop(i1 %c, i32 %end) {
; CHECK-LABEL: @no_live_block_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]]
; CHECK:       check:
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[LIVE]]
; CHECK:       live:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[CHECK]] ], [ [[I_2]], [[LIVE]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 %c, label %check, label %live

check:
  br i1 true, label %backedge, label %live

live:
  %i.2 = add i32 %i, 1
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %check], [%i.2, %live]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

define i32 @no_live_block_test_switch_loop(i1 %c, i32 %end) {
; CHECK-LABEL: @no_live_block_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]]
; CHECK:       check:
; CHECK-NEXT:    switch i32 1, label [[LIVE]] [
; CHECK-NEXT:    i32 0, label [[LIVE]]<commit_msg>[NFC] Add missing test case, some test renaming<commit_after>; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -loop-simplifycfg < %s | FileCheck %s
; RUN: opt -S -passes='require<domtree>,loop(simplify-cfg)' < %s | FileCheck %s
; RUN: opt -S -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"

; Make sure that we can eliminate a provably dead backedge.
define i32 @dead_backedge_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_backedge_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_BE:%.*]], [[HEADER_BACKEDGE:%.*]] ]
; CHECK-NEXT:    [[I_1:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I_1]], 100
; CHECK-NEXT:    br i1 [[CMP1]], label [[HEADER_BACKEDGE]], label [[DEAD_BACKEDGE:%.*]]
; CHECK:       header.backedge:
; CHECK-NEXT:    [[I_BE]] = phi i32 [ [[I_1]], [[HEADER]] ], [ [[I_2:%.*]], [[DEAD_BACKEDGE]] ]
; CHECK-NEXT:    br label [[HEADER]]
; CHECK:       dead_backedge:
; CHECK-NEXT:    [[I_2]] = add i32 [[I_1]], 10
; CHECK-NEXT:    br i1 false, label [[HEADER_BACKEDGE]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_2_LCSSA:%.*]] = phi i32 [ [[I_2]], [[DEAD_BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_2_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.1, %header], [%i.2, %dead_backedge]
  %i.1 = add i32 %i, 1
  %cmp1 = icmp slt i32 %i.1, 100
  br i1 %cmp1, label %header, label %dead_backedge

dead_backedge:
  %i.2 = add i32 %i.1, 10
  br i1 false, label %header, label %exit

exit:
  ret i32 %i.2
}

; Make sure that we can eliminate a provably dead backedge with switch.
define i32 @dead_backedge_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_backedge_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_BE:%.*]], [[HEADER_BACKEDGE:%.*]] ]
; CHECK-NEXT:    [[I_1:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I_1]], 100
; CHECK-NEXT:    br i1 [[CMP1]], label [[HEADER_BACKEDGE]], label [[DEAD_BACKEDGE:%.*]]
; CHECK:       header.backedge:
; CHECK-NEXT:    [[I_BE]] = phi i32 [ [[I_1]], [[HEADER]] ], [ [[I_2:%.*]], [[DEAD_BACKEDGE]] ]
; CHECK-NEXT:    br label [[HEADER]]
; CHECK:       dead_backedge:
; CHECK-NEXT:    [[I_2]] = add i32 [[I_1]], 10
; CHECK-NEXT:    switch i32 1, label [[EXIT:%.*]] [
; CHECK-NEXT:    i32 0, label [[HEADER_BACKEDGE]]
; CHECK-NEXT:    ]
; CHECK:       exit:
; CHECK-NEXT:    [[I_2_LCSSA:%.*]] = phi i32 [ [[I_2]], [[DEAD_BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_2_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.1, %header], [%i.2, %dead_backedge]
  %i.1 = add i32 %i, 1
  %cmp1 = icmp slt i32 %i.1, 100
  br i1 %cmp1, label %header, label %dead_backedge

dead_backedge:
  %i.2 = add i32 %i.1, 10
  switch i32 1, label %exit [i32 0, label %header]

exit:
  ret i32 %i.2
}

; Check that we can eliminate a triangle.
define i32 @dead_block_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_block_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %backedge, label %dead

dead:
  %i.2 = add i32 %i, 1
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dead]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we can eliminate dead branches of a switch.
define i32 @dead_block_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_block_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD]]
; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
; CHECK-NEXT:    i32 2, label [[DEAD]]
; CHECK-NEXT:    ]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead [i32 0, label %dead
  i32 1, label %backedge
  i32 2, label %dead]

dead:
  %i.2 = add i32 %i, 1
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dead]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit
exit:
  ret i32 %i.inc
}

; Check that we can eliminate several dead blocks.
define i32 @dead_block_propogate_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_block_propogate_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %backedge, label %dead

dead:
  %i.2 = add i32 %i, 1
  br label %dummy

dummy:
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we can eliminate several blocks while removing a switch.
define i32 @dead_block_propogate_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_block_propogate_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD]]
; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
; CHECK-NEXT:    i32 2, label [[DEAD]]
; CHECK-NEXT:    ]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead [i32 0, label %dead
  i32 1, label %backedge
  i32 2, label %dead]

dead:
  %i.2 = add i32 %i, 1
  br label %dummy

dummy:
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we preserve static reachibility of a dead exit block while deleting
; a branch.
define i32 @dead_exit_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_exit_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
; CHECK:       dead:
; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[HEADER]] ]
; CHECK-NEXT:    br label [[DUMMY:%.*]]
; CHECK:       dummy:
; CHECK-NEXT:    br label [[EXIT:%.*]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK:       exit.loopexit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    br label [[EXIT]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I_LCSSA]], [[DUMMY]] ], [ [[I_INC_LCSSA]], [[EXIT_LOOPEXIT]] ]
; CHECK-NEXT:    ret i32 [[I_1]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %backedge, label %dead

dead:
  br label %dummy

dummy:
  br label %exit

backedge:
  %i.inc = add i32 %i, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  %i.1 = phi i32 [%i.inc, %backedge], [%i, %dummy]
  ret i32 %i.1
}

; Check that we preserve static reachibility of a dead exit block while deleting
; a switch.
define i32 @dead_exit_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_exit_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD]]
; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
; CHECK-NEXT:    i32 2, label [[DEAD]]
; CHECK-NEXT:    ]
; CHECK:       dead:
; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I]], [[HEADER]] ], [ [[I]], [[HEADER]] ]
; CHECK-NEXT:    br label [[DUMMY:%.*]]
; CHECK:       dummy:
; CHECK-NEXT:    br label [[EXIT:%.*]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK:       exit.loopexit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    br label [[EXIT]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I_LCSSA]], [[DUMMY]] ], [ [[I_INC_LCSSA]], [[EXIT_LOOPEXIT]] ]
; CHECK-NEXT:    ret i32 [[I_1]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead [i32 0, label %dead
  i32 1, label %backedge
  i32 2, label %dead]

dead:
  br label %dummy

dummy:
  br label %exit

backedge:
  %i.inc = add i32 %i, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  %i.1 = phi i32 [%i.inc, %backedge], [%i, %dummy]
  ret i32 %i.1
}

; Check that we can completely eliminate the current loop, branch case.
define i32 @dead_loop_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_loop_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 false, label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %backedge, label %dead

dead:
  %i.2 = add i32 %i, 1
  br label %dummy

dummy:
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 false, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we can completely eliminate the current loop, switch case.
define i32 @dead_loop_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_loop_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD]]
; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
; CHECK-NEXT:    i32 2, label [[DEAD]]
; CHECK-NEXT:    ]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 false, label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header
header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead [i32 0, label %dead
  i32 1, label %backedge
  i32 2, label %dead]
dead:
  %i.2 = add i32 %i, 1
  br label %dummy

dummy:
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 false, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we can delete a dead inner loop entirely.
define i32 @dead_sub_loop_test_branch_loop(i32 %end) {
; CHECK-LABEL: @dead_sub_loop_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[LIVE_PREHEADER:%.*]], label [[DEAD_PREHEADER:%.*]]
; CHECK:       live_preheader:
; CHECK-NEXT:    br label [[LIVE_LOOP:%.*]]
; CHECK:       live_loop:
; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 0, [[LIVE_PREHEADER]] ], [ [[A_INC:%.*]], [[LIVE_LOOP]] ]
; CHECK-NEXT:    [[A_INC]] = add i32 [[A]], 1
; CHECK-NEXT:    [[CMP_A:%.*]] = icmp slt i32 [[A_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP_A]], label [[LIVE_LOOP]], label [[EXIT_A:%.*]]
; CHECK:       exit.a:
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       dead_preheader:
; CHECK-NEXT:    br label [[DEAD_LOOP:%.*]]
; CHECK:       dead_loop:
; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 0, [[DEAD_PREHEADER]] ], [ [[B_INC:%.*]], [[DEAD_LOOP]] ]
; CHECK-NEXT:    [[B_INC]] = add i32 [[B]], 1
; CHECK-NEXT:    [[CMP_B:%.*]] = icmp slt i32 [[B_INC]], [[END]]
; CHECK-NEXT:    br i1 [[CMP_B]], label [[DEAD_LOOP]], label [[EXIT_B:%.*]]
; CHECK:       exit.b:
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %live_preheader, label %dead_preheader

live_preheader:
  br label %live_loop

live_loop:
  %a = phi i32 [0, %live_preheader], [%a.inc, %live_loop]
  %a.inc = add i32 %a, 1
  %cmp.a = icmp slt i32 %a.inc, %end
  br i1 %cmp.a, label %live_loop, label %exit.a

exit.a:
  br label %backedge

dead_preheader:
  br label %dead_loop

dead_loop:
  %b = phi i32 [0, %dead_preheader], [%b.inc, %dead_loop]
  %b.inc = add i32 %b, 1
  %cmp.b = icmp slt i32 %b.inc, %end
  br i1 %cmp.b, label %dead_loop, label %exit.b

exit.b:
  br label %backedge

backedge:
  %i.inc = add i32 %i, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

define i32 @dead_sub_loop_test_switch_loop(i32 %end) {
; CHECK-LABEL: @dead_sub_loop_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD_PREHEADER:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD_PREHEADER]]
; CHECK-NEXT:    i32 1, label [[LIVE_PREHEADER:%.*]]
; CHECK-NEXT:    i32 2, label [[DEAD_PREHEADER]]
; CHECK-NEXT:    ]
; CHECK:       live_preheader:
; CHECK-NEXT:    br label [[LIVE_LOOP:%.*]]
; CHECK:       live_loop:
; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 0, [[LIVE_PREHEADER]] ], [ [[A_INC:%.*]], [[LIVE_LOOP]] ]
; CHECK-NEXT:    [[A_INC]] = add i32 [[A]], 1
; CHECK-NEXT:    [[CMP_A:%.*]] = icmp slt i32 [[A_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP_A]], label [[LIVE_LOOP]], label [[EXIT_A:%.*]]
; CHECK:       exit.a:
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       dead_preheader:
; CHECK-NEXT:    br label [[DEAD_LOOP:%.*]]
; CHECK:       dead_loop:
; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 0, [[DEAD_PREHEADER]] ], [ [[B_INC:%.*]], [[DEAD_LOOP]] ]
; CHECK-NEXT:    [[B_INC]] = add i32 [[B]], 1
; CHECK-NEXT:    [[CMP_B:%.*]] = icmp slt i32 [[B_INC]], [[END]]
; CHECK-NEXT:    br i1 [[CMP_B]], label [[DEAD_LOOP]], label [[EXIT_B:%.*]]
; CHECK:       exit.b:
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead_preheader [i32 0, label %dead_preheader
  i32 1, label %live_preheader
  i32 2, label %dead_preheader]

live_preheader:
  br label %live_loop

live_loop:
  %a = phi i32 [0, %live_preheader], [%a.inc, %live_loop]
  %a.inc = add i32 %a, 1
  %cmp.a = icmp slt i32 %a.inc, %end
  br i1 %cmp.a, label %live_loop, label %exit.a

exit.a:
  br label %backedge

dead_preheader:
  br label %dead_loop

dead_loop:
  %b = phi i32 [0, %dead_preheader], [%b.inc, %dead_loop]
  %b.inc = add i32 %b, 1
  %cmp.b = icmp slt i32 %b.inc, %end
  br i1 %cmp.b, label %dead_loop, label %exit.b

exit.b:
  br label %backedge

backedge:
  %i.inc = add i32 %i, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

; Check that we preserve static reachability of an exit block even if we prove
; that the loop is infinite. Branch case.
define i32 @inf_loop_test_branch_loop(i32 %end) {
; CHECK-LABEL: @inf_loop_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 true, label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 true, label %backedge, label %dead

dead:
  %i.2 = add i32 %i, 1
  br label %dummy

dummy:
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 true, label %header, label %exit

exit:
  ret i32 %i.inc
}

define i32 @inf_loop_test_switch_loop(i32 %end) {
; CHECK-LABEL: @inf_loop_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
; CHECK-NEXT:    i32 0, label [[DEAD]]
; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
; CHECK-NEXT:    i32 2, label [[DEAD]]
; CHECK-NEXT:    ]
; CHECK:       dead:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 true, label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header
header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  switch i32 1, label %dead [i32 0, label %dead
  i32 1, label %backedge
  i32 2, label %dead]
dead:
  %i.2 = add i32 %i, 1
  br label %dummy
dummy:
  br label %backedge
backedge:
  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 true, label %header, label %exit
exit:
  ret i32 %i.inc
}

; Check that when the block is not actually dead, we don't remove it.
define i32 @live_block_test_branch_loop(i1 %c, i32 %end) {
; CHECK-LABEL: @live_block_test_branch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]]
; CHECK:       check:
; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[LIVE]]
; CHECK:       live:
; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
; CHECK-NEXT:    br label [[BACKEDGE]]
; CHECK:       backedge:
; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[CHECK]] ], [ [[I_2]], [[LIVE]] ]
; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
;
preheader:
  br label %header

header:
  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
  br i1 %c, label %check, label %live

check:
  br i1 true, label %backedge, label %live

live:
  %i.2 = add i32 %i, 1
  br label %backedge

backedge:
  %i.1 = phi i32 [%i, %check], [%i.2, %live]
  %i.inc = add i32 %i.1, 1
  %cmp = icmp slt i32 %i.inc, %end
  br i1 %cmp, label %header, label %exit

exit:
  ret i32 %i.inc
}

define i32 @live_block_test_switch_loop(i1 %c, i32 %end) {
; CHECK-LABEL: @live_block_test_switch_loop(
; CHECK-NEXT:  preheader:
; CHECK-NEXT:    br label [[HEADER:%.*]]
; CHECK:       header:
; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT:    br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]]
; CHECK:       check:
; CHECK-NEXT:    switch i32 1, label [[LIVE]] [
; CHECK-NEXT:    i32 0, label [[LIVE]]
{'fraction_non_alphanumeric': 0.2246841313354082, 'fraction_numerical': 0.03784240575468392, 'mean_word_length': 3.292868518846222, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4623638', 'n_tokens_mistral': 20556, 'n_tokens_neox': 20315, 'n_words': 5486}