aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/Transforms/DFAJumpThreading
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms/DFAJumpThreading')
-rw-r--r--llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-analysis.ll32
-rw-r--r--llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll42
-rw-r--r--llvm/test/Transforms/DFAJumpThreading/equivalent-states.ll281
-rw-r--r--llvm/test/Transforms/DFAJumpThreading/max-path-length.ll6
4 files changed, 311 insertions, 50 deletions
diff --git a/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-analysis.ll b/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-analysis.ll
index 4173c32..f45798b 100644
--- a/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-analysis.ll
+++ b/llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-analysis.ll
@@ -7,10 +7,10 @@
; state, and the block that determines the next state.
; < path of BBs that form a cycle > [ state, determinator ]
define i32 @test1(i32 %num) !prof !0{
-; CHECK: < case2 for.inc for.body > [ 1, for.inc ]
-; CHECK-NEXT: < for.inc for.body > [ 1, for.inc ]
-; CHECK-NEXT: < case1 for.inc for.body > [ 2, for.inc ]
-; CHECK-NEXT: < case2 sel.si.unfold.false for.inc for.body > [ 2, sel.si.unfold.false ]
+; CHECK: < case2, for.inc, for.body > [ 1, for.inc ]
+; CHECK-NEXT: < for.inc, for.body > [ 1, for.inc ]
+; CHECK-NEXT: < case1, for.inc, for.body > [ 2, for.inc ]
+; CHECK-NEXT: < case2, sel.si.unfold.false, for.inc, for.body > [ 2, sel.si.unfold.false ]
entry:
br label %for.body
@@ -47,12 +47,12 @@ for.end:
; complicated CFG. Here the FSM is represented as a nested loop, with
; fallthrough cases.
define i32 @test2(i32 %init) {
-; CHECK: < loop.1.backedge loop.1 loop.2 loop.3 > [ 1, loop.1 ]
-; CHECK-NEXT: < case4 loop.1.backedge state.1.be2.si.unfold.false loop.1 loop.2 loop.3 > [ 2, loop.1.backedge ]
-; CHECK-NEXT: < case2 loop.1.backedge state.1.be2.si.unfold.false loop.1 loop.2 loop.3 > [ 4, loop.1.backedge ]
-; CHECK-NEXT: < case4 loop.2.backedge loop.2 loop.3 > [ 3, loop.2.backedge ]
-; CHECK-NEXT: < case3 loop.2.backedge loop.2 loop.3 > [ 0, loop.2.backedge ]
-; CHECK-NEXT: < case2 loop.3 > [ 3, loop.3 ]
+; CHECK: < loop.1.backedge, loop.1, loop.2, loop.3 > [ 1, loop.1 ]
+; CHECK-NEXT: < case4, loop.1.backedge, state.1.be2.si.unfold.false, loop.1, loop.2, loop.3 > [ 2, loop.1.backedge ]
+; CHECK-NEXT: < case2, loop.1.backedge, state.1.be2.si.unfold.false, loop.1, loop.2, loop.3 > [ 4, loop.1.backedge ]
+; CHECK-NEXT: < case4, loop.2.backedge, loop.2, loop.3 > [ 3, loop.2.backedge ]
+; CHECK-NEXT: < case3, loop.2.backedge, loop.2, loop.3 > [ 0, loop.2.backedge ]
+; CHECK-NEXT: < case2, loop.3 > [ 3, loop.3 ]
entry:
%cmp = icmp eq i32 %init, 0
%sel = select i1 %cmp, i32 0, i32 2
@@ -187,12 +187,12 @@ bb66: ; preds = %bb59
; Value %init is not predictable but it's okay since it is the value initial to the switch.
define i32 @initial.value.positive1(i32 %init) !prof !0 {
-; CHECK: < loop.1.backedge loop.1 loop.2 loop.3 > [ 1, loop.1 ]
-; CHECK-NEXT: < case4 loop.1.backedge state.1.be2.si.unfold.false loop.1 loop.2 loop.3 > [ 2, loop.1.backedge ]
-; CHECK-NEXT: < case2 loop.1.backedge state.1.be2.si.unfold.false loop.1 loop.2 loop.3 > [ 4, loop.1.backedge ]
-; CHECK-NEXT: < case4 loop.2.backedge loop.2 loop.3 > [ 3, loop.2.backedge ]
-; CHECK-NEXT: < case3 loop.2.backedge loop.2 loop.3 > [ 0, loop.2.backedge ]
-; CHECK-NEXT: < case2 loop.3 > [ 3, loop.3 ]
+; CHECK: < loop.1.backedge, loop.1, loop.2, loop.3 > [ 1, loop.1 ]
+; CHECK-NEXT: < case4, loop.1.backedge, state.1.be2.si.unfold.false, loop.1, loop.2, loop.3 > [ 2, loop.1.backedge ]
+; CHECK-NEXT: < case2, loop.1.backedge, state.1.be2.si.unfold.false, loop.1, loop.2, loop.3 > [ 4, loop.1.backedge ]
+; CHECK-NEXT: < case4, loop.2.backedge, loop.2, loop.3 > [ 3, loop.2.backedge ]
+; CHECK-NEXT: < case3, loop.2.backedge, loop.2, loop.3 > [ 0, loop.2.backedge ]
+; CHECK-NEXT: < case2, loop.3 > [ 3, loop.3 ]
entry:
%cmp = icmp eq i32 %init, 0
br label %loop.1
diff --git a/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll b/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll
index 663f459..de38752 100644
--- a/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll
+++ b/llvm/test/Transforms/DFAJumpThreading/dfa-unfold-select.ll
@@ -227,10 +227,6 @@ define i32 @test3(i32 %num) {
; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
; CHECK-NEXT: i32 2, label [[CASE2:%.*]]
; CHECK-NEXT: ]
-; CHECK: for.body.jt4:
-; CHECK-NEXT: [[COUNT_JT4:%.*]] = phi i32 [ [[INC_JT4:%.*]], [[FOR_INC_JT4:%.*]] ]
-; CHECK-NEXT: [[STATE_JT4:%.*]] = phi i32 [ [[STATE_NEXT_JT4:%.*]], [[FOR_INC_JT4]] ]
-; CHECK-NEXT: br label [[FOR_INC_JT1]]
; CHECK: for.body.jt3:
; CHECK-NEXT: [[COUNT_JT3:%.*]] = phi i32 [ [[INC_JT3:%.*]], [[FOR_INC_JT3:%.*]] ]
; CHECK-NEXT: [[STATE_JT3:%.*]] = phi i32 [ [[STATE_NEXT_JT3:%.*]], [[FOR_INC_JT3]] ]
@@ -261,17 +257,14 @@ define i32 @test3(i32 %num) {
; CHECK: sel.2.si.unfold.false:
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI1:%.*]] = phi i32 [ 4, [[SEL_2_SI_UNFOLD_TRUE_JT3]] ]
; CHECK-NEXT: br label [[SEL_3_SI_UNFOLD_FALSE]]
-; CHECK: sel.2.si.unfold.false.jt4:
+; CHECK: sel.2.si.unfold.false.jt3:
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI1_JT4:%.*]] = phi i32 [ 4, [[SEL_2_SI_UNFOLD_TRUE:%.*]] ]
-; CHECK-NEXT: br label [[SEL_3_SI_UNFOLD_FALSE_JT4:%.*]]
+; CHECK-NEXT: br label [[SEL_3_SI_UNFOLD_FALSE_JT3]]
; CHECK: sel.3.si.unfold.false:
; CHECK-NEXT: [[SEL_2_SI_UNFOLD_PHI:%.*]] = phi i32 [ poison, [[SEL_2_SI_UNFOLD_TRUE]] ], [ [[DOTSI_UNFOLD_PHI1]], [[SEL_2_SI_UNFOLD_FALSE]] ]
; CHECK-NEXT: br label [[FOR_INC]]
-; CHECK: sel.3.si.unfold.false.jt4:
-; CHECK-NEXT: [[SEL_2_SI_UNFOLD_PHI_JT4:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI1_JT4]], [[SEL_2_SI_UNFOLD_FALSE_JT4]] ]
-; CHECK-NEXT: br label [[FOR_INC_JT4]]
; CHECK: sel.3.si.unfold.false.jt3:
-; CHECK-NEXT: [[SEL_2_SI_UNFOLD_PHI_JT3:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI_JT3]], [[SEL_2_SI_UNFOLD_TRUE_JT3]] ]
+; CHECK-NEXT: [[SEL_2_SI_UNFOLD_PHI_JT3:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI_JT3]], [[SEL_2_SI_UNFOLD_TRUE_JT3]] ], [ [[DOTSI_UNFOLD_PHI1_JT4]], [[SEL_2_SI_UNFOLD_FALSE_JT4]] ]
; CHECK-NEXT: br label [[FOR_INC_JT3]]
; CHECK: sel.1.si.unfold.true:
; CHECK-NEXT: br i1 [[CMP_1]], label [[FOR_INC]], label [[SEL_1_SI_UNFOLD_FALSE_JT2:%.*]]
@@ -289,11 +282,6 @@ define i32 @test3(i32 %num) {
; CHECK-NEXT: [[INC]] = add nsw i32 [[COUNT5]], 1
; CHECK-NEXT: [[CMP_EXIT:%.*]] = icmp slt i32 [[INC]], [[NUM:%.*]]
; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]]
-; CHECK: for.inc.jt4:
-; CHECK-NEXT: [[STATE_NEXT_JT4]] = phi i32 [ [[SEL_2_SI_UNFOLD_PHI_JT4]], [[SEL_3_SI_UNFOLD_FALSE_JT4]] ]
-; CHECK-NEXT: [[INC_JT4]] = add nsw i32 undef, 1
-; CHECK-NEXT: [[CMP_EXIT_JT4:%.*]] = icmp slt i32 [[INC_JT4]], [[NUM]]
-; CHECK-NEXT: br i1 [[CMP_EXIT_JT4]], label [[FOR_BODY_JT4:%.*]], label [[FOR_END]]
; CHECK: for.inc.jt3:
; CHECK-NEXT: [[STATE_NEXT_JT3]] = phi i32 [ [[SEL_2_SI_UNFOLD_PHI_JT3]], [[SEL_3_SI_UNFOLD_FALSE_JT3]] ]
; CHECK-NEXT: [[INC_JT3]] = add nsw i32 [[COUNT5]], 1
@@ -305,8 +293,8 @@ define i32 @test3(i32 %num) {
; CHECK-NEXT: [[CMP_EXIT_JT2:%.*]] = icmp slt i32 [[INC_JT2]], [[NUM]]
; CHECK-NEXT: br i1 [[CMP_EXIT_JT2]], label [[FOR_BODY_JT2]], label [[FOR_END]]
; CHECK: for.inc.jt1:
-; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT_JT4]], [[FOR_BODY_JT4]] ], [ [[COUNT_JT3]], [[FOR_BODY_JT3]] ], [ [[COUNT5]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ], [ [[COUNT]], [[FOR_BODY]] ]
-; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[FOR_BODY]] ], [ 1, [[FOR_BODY_JT3]] ], [ 1, [[FOR_BODY_JT4]] ], [ [[DOTSI_UNFOLD_PHI2_JT1]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ]
+; CHECK-NEXT: [[COUNT4:%.*]] = phi i32 [ [[COUNT_JT3]], [[FOR_BODY_JT3]] ], [ [[COUNT5]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ], [ [[COUNT]], [[FOR_BODY]] ]
+; CHECK-NEXT: [[STATE_NEXT_JT1]] = phi i32 [ 1, [[FOR_BODY]] ], [ 1, [[FOR_BODY_JT3]] ], [ [[DOTSI_UNFOLD_PHI2_JT1]], [[SEL_1_SI_UNFOLD_TRUE_JT1]] ]
; CHECK-NEXT: [[INC_JT1]] = add nsw i32 [[COUNT4]], 1
; CHECK-NEXT: [[CMP_EXIT_JT1:%.*]] = icmp slt i32 [[INC_JT1]], [[NUM]]
; CHECK-NEXT: br i1 [[CMP_EXIT_JT1]], label [[FOR_BODY_JT1]], label [[FOR_END]]
@@ -402,36 +390,28 @@ define void @pr65222(i32 %flags, i1 %cmp, i1 %tobool.not) {
; CHECK-NEXT: br label [[IF_END_JT2:%.*]]
; CHECK: cond1.si.unfold.true:
; CHECK-NEXT: br i1 [[CMP]], label [[IF_END]], label [[COND1_SI_UNFOLD_FALSE_JT1:%.*]]
-; CHECK: cond1.si.unfold.true.jt3:
+; CHECK: cond1.si.unfold.true.jt2:
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI2:%.*]] = phi i32 [ 3, [[THEN]] ]
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_END_JT3:%.*]], label [[COND1_SI_UNFOLD_FALSE:%.*]]
+; CHECK-NEXT: br i1 [[CMP]], label [[IF_END_JT2]], label [[COND1_SI_UNFOLD_FALSE:%.*]]
; CHECK: cond1.si.unfold.false:
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI3:%.*]] = phi i32 [ 1, [[COND1_SI_UNFOLD_TRUE]] ]
; CHECK-NEXT: br label [[IF_END]]
-; CHECK: cond1.si.unfold.false.jt1:
+; CHECK: cond1.si.unfold.false.jt2:
; CHECK-NEXT: [[DOTSI_UNFOLD_PHI3_JT1:%.*]] = phi i32 [ 1, [[COND1_SI_UNFOLD_TRUE1:%.*]] ]
-; CHECK-NEXT: br label [[IF_END_JT1:%.*]]
+; CHECK-NEXT: br label [[IF_END_JT2]]
; CHECK: if.end:
; CHECK-NEXT: [[UNFOLDED:%.*]] = phi i32 [ [[FLAGS:%.*]], [[WHILE_COND]] ], [ [[COND_SI_UNFOLD_PHI]], [[TOUNFOLD_SI_UNFOLD_FALSE1]] ], [ poison, [[COND1_SI_UNFOLD_TRUE1]] ], [ [[DOTSI_UNFOLD_PHI3]], [[COND1_SI_UNFOLD_FALSE]] ]
; CHECK-NEXT: [[OTHER:%.*]] = phi i32 [ [[FLAGS]], [[WHILE_COND]] ], [ 0, [[TOUNFOLD_SI_UNFOLD_FALSE1]] ], [ 0, [[COND1_SI_UNFOLD_TRUE1]] ], [ 0, [[COND1_SI_UNFOLD_FALSE]] ]
; CHECK-NEXT: switch i32 [[UNFOLDED]], label [[UNREACHABLE:%.*]] [
; CHECK-NEXT: i32 0, label [[SW_BB:%.*]]
; CHECK-NEXT: ]
-; CHECK: if.end.jt1:
-; CHECK-NEXT: [[UNFOLDED_JT1:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI3_JT1]], [[COND1_SI_UNFOLD_FALSE_JT1]] ]
-; CHECK-NEXT: [[OTHER_JT1:%.*]] = phi i32 [ 0, [[COND1_SI_UNFOLD_FALSE_JT1]] ]
-; CHECK-NEXT: br label [[UNREACHABLE]]
-; CHECK: if.end.jt3:
-; CHECK-NEXT: [[UNFOLDED_JT3:%.*]] = phi i32 [ [[DOTSI_UNFOLD_PHI2]], [[COND1_SI_UNFOLD_TRUE]] ]
-; CHECK-NEXT: [[OTHER_JT3:%.*]] = phi i32 [ 0, [[COND1_SI_UNFOLD_TRUE]] ]
-; CHECK-NEXT: br label [[UNREACHABLE]]
; CHECK: if.end.jt0:
; CHECK-NEXT: [[UNFOLDED_JT0:%.*]] = phi i32 [ [[COND_SI_UNFOLD_PHI_JT0]], [[TOUNFOLD_SI_UNFOLD_FALSE_JT0]] ]
; CHECK-NEXT: [[OTHER_JT0:%.*]] = phi i32 [ 0, [[TOUNFOLD_SI_UNFOLD_FALSE_JT0]] ]
; CHECK-NEXT: br label [[SW_BB]]
; CHECK: if.end.jt2:
-; CHECK-NEXT: [[UNFOLDED_JT2:%.*]] = phi i32 [ [[COND_SI_UNFOLD_PHI_JT2]], [[TOUNFOLD_SI_UNFOLD_FALSE]] ]
-; CHECK-NEXT: [[OTHER_JT2:%.*]] = phi i32 [ 0, [[TOUNFOLD_SI_UNFOLD_FALSE]] ]
+; CHECK-NEXT: [[UNFOLDED_JT2:%.*]] = phi i32 [ [[COND_SI_UNFOLD_PHI_JT2]], [[TOUNFOLD_SI_UNFOLD_FALSE]] ], [ [[DOTSI_UNFOLD_PHI2]], [[COND1_SI_UNFOLD_TRUE]] ], [ [[DOTSI_UNFOLD_PHI3_JT1]], [[COND1_SI_UNFOLD_FALSE_JT1]] ]
+; CHECK-NEXT: [[OTHER_JT2:%.*]] = phi i32 [ 0, [[TOUNFOLD_SI_UNFOLD_FALSE]] ], [ 0, [[COND1_SI_UNFOLD_TRUE]] ], [ 0, [[COND1_SI_UNFOLD_FALSE_JT1]] ]
; CHECK-NEXT: br label [[UNREACHABLE]]
; CHECK: unreachable:
; CHECK-NEXT: unreachable
diff --git a/llvm/test/Transforms/DFAJumpThreading/equivalent-states.ll b/llvm/test/Transforms/DFAJumpThreading/equivalent-states.ll
new file mode 100644
index 0000000..4555dfb
--- /dev/null
+++ b/llvm/test/Transforms/DFAJumpThreading/equivalent-states.ll
@@ -0,0 +1,281 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt -S -passes=dfa-jump-threading %s | FileCheck %s
+
+declare void @do_something()
+declare void @user(i32)
+
+define void @equivalent_on_default(i1 %c1) {
+; CHECK-LABEL: define void @equivalent_on_default(
+; CHECK-SAME: i1 [[C1:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[SWITCH_BB:%.*]]
+; CHECK: switch_bb:
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ poison, [[CASE2END:%.*]] ]
+; CHECK-NEXT: switch i32 [[PHI]], label [[DEFAULT_DEST:%.*]] [
+; CHECK-NEXT: i32 0, label [[CASE1:%.*]]
+; CHECK-NEXT: i32 1, label [[CASE2:%.*]]
+; CHECK-NEXT: ]
+; CHECK: switch_bb.jt2:
+; CHECK-NEXT: [[PHI_JT2:%.*]] = phi i32 [ [[PHI_CASE2_JT2:%.*]], [[CASE2END_JT2:%.*]] ]
+; CHECK-NEXT: br label [[DEFAULT_DEST]]
+; CHECK: switch_bb.jt1:
+; CHECK-NEXT: [[PHI_JT1:%.*]] = phi i32 [ 1, [[CASE1]] ]
+; CHECK-NEXT: br label [[CASE2]]
+; CHECK: case1:
+; CHECK-NEXT: br label [[SWITCH_BB_JT1:%.*]]
+; CHECK: case2:
+; CHECK-NEXT: br i1 [[C1]], label [[CASE2THEN:%.*]], label [[CASE2END_JT2]]
+; CHECK: case2then:
+; CHECK-NEXT: br label [[CASE2END_JT2]]
+; CHECK: case2end:
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: br label [[SWITCH_BB]]
+; CHECK: case2end.jt2:
+; CHECK-NEXT: [[PHI_CASE2_JT2]] = phi i32 [ 2, [[CASE2]] ], [ 3, [[CASE2THEN]] ]
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: br label [[SWITCH_BB_JT2:%.*]]
+; CHECK: default_dest:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %switch_bb
+
+switch_bb:
+ %phi = phi i32 [ 0, %entry ], [ 1, %case1 ], [ %phi_case2, %case2end ]
+ switch i32 %phi, label %default_dest [
+ i32 0, label %case1
+ i32 1, label %case2
+ ]
+
+case1:
+ br label %switch_bb
+
+case2:
+ br i1 %c1, label %case2then, label %case2end
+
+case2then:
+ br label %case2end
+
+case2end:
+ %phi_case2 = phi i32 [ 2, %case2 ] , [ 3, %case2then ]
+ call void @do_something()
+ br label %switch_bb
+
+default_dest:
+ ret void
+}
+
+define void @equivalent_on_default_user(i1 %c1) {
+; CHECK-LABEL: define void @equivalent_on_default_user(
+; CHECK-SAME: i1 [[C1:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[SWITCH_BB:%.*]]
+; CHECK: switch_bb:
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ poison, [[CASE2END:%.*]] ]
+; CHECK-NEXT: switch i32 [[PHI]], label [[DEFAULT_DEST:%.*]] [
+; CHECK-NEXT: i32 0, label [[CASE1:%.*]]
+; CHECK-NEXT: i32 1, label [[CASE2:%.*]]
+; CHECK-NEXT: ]
+; CHECK: switch_bb.jt2:
+; CHECK-NEXT: [[PHI_JT2:%.*]] = phi i32 [ [[PHI_CASE2_JT2:%.*]], [[CASE2END_JT2:%.*]] ]
+; CHECK-NEXT: br label [[DEFAULT_DEST]]
+; CHECK: switch_bb.jt1:
+; CHECK-NEXT: [[PHI_JT1:%.*]] = phi i32 [ 1, [[CASE1]] ]
+; CHECK-NEXT: br label [[CASE2]]
+; CHECK: case1:
+; CHECK-NEXT: br label [[SWITCH_BB_JT1:%.*]]
+; CHECK: case2:
+; CHECK-NEXT: br i1 [[C1]], label [[CASE2THEN:%.*]], label [[CASE2END_JT2]]
+; CHECK: case2then:
+; CHECK-NEXT: br label [[CASE2END_JT2]]
+; CHECK: case2end:
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: call void @user(i32 poison)
+; CHECK-NEXT: br label [[SWITCH_BB]]
+; CHECK: case2end.jt2:
+; CHECK-NEXT: [[PHI_CASE2_JT2]] = phi i32 [ 2, [[CASE2]] ], [ 3, [[CASE2THEN]] ]
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: call void @user(i32 [[PHI_CASE2_JT2]])
+; CHECK-NEXT: br label [[SWITCH_BB_JT2:%.*]]
+; CHECK: default_dest:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %switch_bb
+
+switch_bb:
+ %phi = phi i32 [ 0, %entry ], [ 1, %case1 ], [ %phi_case2, %case2end ]
+ switch i32 %phi, label %default_dest [
+ i32 0, label %case1
+ i32 1, label %case2
+ ]
+
+case1:
+ br label %switch_bb
+
+case2:
+ br i1 %c1, label %case2then, label %case2end
+
+case2then:
+ br label %case2end
+
+case2end:
+ %phi_case2 = phi i32 [ 2, %case2 ] , [ 3, %case2then ]
+ call void @do_something()
+ call void @user(i32 %phi_case2)
+ br label %switch_bb
+
+default_dest:
+ ret void
+}
+
+define void @equivalent_only_cases(i1 %c1) {
+; CHECK-LABEL: define void @equivalent_only_cases(
+; CHECK-SAME: i1 [[C1:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[SWITCH_BB:%.*]]
+; CHECK: switch_bb:
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ poison, [[CASE2END:%.*]] ]
+; CHECK-NEXT: switch i32 [[PHI]], label [[DEFAULT_DEST:%.*]] [
+; CHECK-NEXT: i32 0, label [[CASE1:%.*]]
+; CHECK-NEXT: i32 1, label [[CASE2:%.*]]
+; CHECK-NEXT: i32 2, label [[CASE1]]
+; CHECK-NEXT: i32 3, label [[CASE1]]
+; CHECK-NEXT: ]
+; CHECK: switch_bb.jt2:
+; CHECK-NEXT: [[PHI_JT2:%.*]] = phi i32 [ [[PHI_CASE2_JT2:%.*]], [[CASE2END_JT2:%.*]] ]
+; CHECK-NEXT: br label [[CASE1]]
+; CHECK: switch_bb.jt1:
+; CHECK-NEXT: [[PHI_JT1:%.*]] = phi i32 [ 1, [[CASE1]] ]
+; CHECK-NEXT: br label [[CASE2]]
+; CHECK: case1:
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: br label [[SWITCH_BB_JT1:%.*]]
+; CHECK: case2:
+; CHECK-NEXT: br i1 [[C1]], label [[CASE2THEN:%.*]], label [[CASE2END_JT2]]
+; CHECK: case2then:
+; CHECK-NEXT: br label [[CASE2END_JT2]]
+; CHECK: case2end:
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: br label [[SWITCH_BB]]
+; CHECK: case2end.jt2:
+; CHECK-NEXT: [[PHI_CASE2_JT2]] = phi i32 [ 2, [[CASE2]] ], [ 3, [[CASE2THEN]] ]
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: br label [[SWITCH_BB_JT2:%.*]]
+; CHECK: default_dest:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %switch_bb
+
+switch_bb:
+ %phi = phi i32 [ 0, %entry ], [ 1, %case1 ], [ %phi_case2, %case2end ]
+ switch i32 %phi, label %default_dest [
+ i32 0, label %case1
+ i32 1, label %case2
+ i32 2, label %case1
+ i32 3, label %case1
+ ]
+
+case1:
+ call void @do_something()
+ br label %switch_bb
+
+case2:
+ br i1 %c1, label %case2then, label %case2end
+
+case2then:
+ br label %case2end
+
+case2end:
+ %phi_case2 = phi i32 [ 2, %case2 ] , [ 3, %case2then ]
+ call void @do_something()
+ br label %switch_bb
+
+default_dest:
+ ret void
+}
+
+define void @equivalent_both_case_and_default(i1 %c1, i1 %c2) {
+; CHECK-LABEL: define void @equivalent_both_case_and_default(
+; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[SWITCH_BB:%.*]]
+; CHECK: switch_bb:
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ poison, [[CASE2END:%.*]] ]
+; CHECK-NEXT: switch i32 [[PHI]], label [[DEFAULT_DEST:%.*]] [
+; CHECK-NEXT: i32 0, label [[CASE1:%.*]]
+; CHECK-NEXT: i32 1, label [[CASE2:%.*]]
+; CHECK-NEXT: i32 2, label [[CASE1]]
+; CHECK-NEXT: i32 3, label [[CASE1]]
+; CHECK-NEXT: ]
+; CHECK: switch_bb.jt4:
+; CHECK-NEXT: [[PHI_JT3:%.*]] = phi i32 [ [[PHI_CASE2_JT3:%.*]], [[CASE2END_JT3:%.*]] ]
+; CHECK-NEXT: br label [[DEFAULT_DEST]]
+; CHECK: switch_bb.jt2:
+; CHECK-NEXT: [[PHI_JT2:%.*]] = phi i32 [ [[PHI_CASE2_JT2:%.*]], [[CASE2END_JT2:%.*]] ]
+; CHECK-NEXT: br label [[CASE1]]
+; CHECK: switch_bb.jt1:
+; CHECK-NEXT: [[PHI_JT1:%.*]] = phi i32 [ 1, [[CASE1]] ]
+; CHECK-NEXT: br label [[CASE2]]
+; CHECK: case1:
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: br label [[SWITCH_BB_JT1:%.*]]
+; CHECK: case2:
+; CHECK-NEXT: br i1 [[C1]], label [[CASE2THEN:%.*]], label [[CASE2END_JT2]]
+; CHECK: case2then:
+; CHECK-NEXT: br i1 [[C2]], label [[CASE2THEN2:%.*]], label [[CASE2END_JT2]]
+; CHECK: case2then2:
+; CHECK-NEXT: br i1 [[C2]], label [[CASE2THEN3:%.*]], label [[CASE2END_JT3]]
+; CHECK: case2then3:
+; CHECK-NEXT: br label [[CASE2END_JT3]]
+; CHECK: case2end:
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: br label [[SWITCH_BB]]
+; CHECK: case2end.jt4:
+; CHECK-NEXT: [[PHI_CASE2_JT3]] = phi i32 [ 4, [[CASE2THEN2]] ], [ 5, [[CASE2THEN3]] ]
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: br label [[SWITCH_BB_JT3:%.*]]
+; CHECK: case2end.jt2:
+; CHECK-NEXT: [[PHI_CASE2_JT2]] = phi i32 [ 2, [[CASE2]] ], [ 3, [[CASE2THEN]] ]
+; CHECK-NEXT: call void @do_something()
+; CHECK-NEXT: br label [[SWITCH_BB_JT2:%.*]]
+; CHECK: default_dest:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %switch_bb
+
+switch_bb:
+ %phi = phi i32 [ 0, %entry ], [ 1, %case1 ], [ %phi_case2, %case2end ]
+ switch i32 %phi, label %default_dest [
+ i32 0, label %case1
+ i32 1, label %case2
+ i32 2, label %case1
+ i32 3, label %case1
+ ]
+
+case1:
+ call void @do_something()
+ br label %switch_bb
+
+case2:
+ br i1 %c1, label %case2then, label %case2end
+
+case2then:
+ br i1 %c2, label %case2then2, label %case2end
+
+case2then2:
+ br i1 %c2, label %case2then3, label %case2end
+
+case2then3:
+ br label %case2end
+
+case2end:
+ %phi_case2 = phi i32 [ 2, %case2 ], [ 3, %case2then ], [ 4, %case2then2 ], [ 5, %case2then3 ]
+ call void @do_something()
+ br label %switch_bb
+
+default_dest:
+ ret void
+}
diff --git a/llvm/test/Transforms/DFAJumpThreading/max-path-length.ll b/llvm/test/Transforms/DFAJumpThreading/max-path-length.ll
index 92747629..cb7c46e 100644
--- a/llvm/test/Transforms/DFAJumpThreading/max-path-length.ll
+++ b/llvm/test/Transforms/DFAJumpThreading/max-path-length.ll
@@ -9,9 +9,9 @@
; too long so that it is not jump-threaded.
define i32 @max_path_length(i32 %num) {
; CHECK-NOT: 3, case1
-; CHECK: < case2 for.inc for.body > [ 1, for.inc ]
-; CHECK-NEXT: < for.inc for.body > [ 1, for.inc ]
-; CHECK-NEXT: < case2 sel.si.unfold.false for.inc for.body > [ 2, sel.si.unfold.false ]
+; CHECK: < case2, for.inc, for.body > [ 1, for.inc ]
+; CHECK-NEXT: < for.inc, for.body > [ 1, for.inc ]
+; CHECK-NEXT: < case2, sel.si.unfold.false, for.inc, for.body > [ 2, sel.si.unfold.false ]
; CHECK-NEXT: DFA-JT: Renaming non-local uses of:
entry:
br label %for.body