diff options
Diffstat (limited to 'llvm/test/Transforms/DFAJumpThreading')
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 |