Skip to content

Commit 6b99527

Browse files
[SimplifyCFG] Simplify switch instruction that has duplicate arms (#114262)
I noticed that the two C functions emitted different IR: ``` int switch_duplicate_arms(int switch_val, int v, int w) { switch (switch_val) { default: break; case 0: w = v; break; case 1: w = v; break; } return w; } int if_duplicate_arms(int switch_val, int v, int w) { if (switch_val == 0) w = v; else if (switch_val == 1) w = v; return v0; } ``` We generate IR that looks like this: ``` define i32 @switch_duplicate_arms(i32 %0, i32 %1, i32 %2, i32 %3) { switch i32 %1, label %7 [ i32 0, label %5 i32 1, label %6 ] 5: br label %7 6: br label %7 7: %8 = phi i32 [ %3, %4 ], [ %2, %6 ], [ %2, %5 ] ret i32 %8 } define i32 @if_duplicate_arms(i32 %0, i32 %1, i32 %2, i32 %3) { %5 = icmp ult i32 %1, 2 %6 = select i1 %5, i32 %2, i32 %3 ret i32 %6 } ``` For `switch_duplicate_arms`, taking case 0 and 1 are the same since %5 and %6 branch to the same location and the incoming values for %8 are the same from those blocks. We could remove one on the duplicate switch targets and update the switch with the single target. On RISC-V, prior to this patch, we generate the following code: ``` switch_duplicate_arms: li a4, 1 beq a1, a4, .LBB0_2 mv a0, a3 bnez a1, .LBB0_3 .LBB0_2: mv a0, a2 .LBB0_3: ret if_duplicate_arms: li a4, 2 mv a0, a2 bltu a1, a4, .LBB1_2 mv a0, a3 .LBB1_2: ret ``` After this patch, the O3 code is optimized to the icmp + select pair, which gives us the same code gen as `if_duplicate_arms`, as desired. This results is one less branch instruction in the final assembly. This may help with both code size and further switch simplification. I found that this patch causes no significant impact to spec2006/int/ref and spec2017/intrate/ref. --------- Co-authored-by: Min Hsu <[email protected]>
1 parent 6c1fc82 commit 6b99527

File tree

6 files changed

+313
-13
lines changed

6 files changed

+313
-13
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ class SimplifyCFGOpt {
276276
bool simplifyCleanupReturn(CleanupReturnInst *RI);
277277
bool simplifyUnreachable(UnreachableInst *UI);
278278
bool simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder);
279+
bool simplifyDuplicateSwitchArms(SwitchInst *SI, DomTreeUpdater *DTU);
279280
bool simplifyIndirectBr(IndirectBrInst *IBI);
280281
bool simplifyBranch(BranchInst *Branch, IRBuilder<> &Builder);
281282
bool simplifyUncondBranch(BranchInst *BI, IRBuilder<> &Builder);
@@ -7436,6 +7437,179 @@ static bool simplifySwitchOfCmpIntrinsic(SwitchInst *SI, IRBuilderBase &Builder,
74367437
return true;
74377438
}
74387439

7440+
/// Checking whether two cases of SI are equal depends on the contents of the
7441+
/// BasicBlock and the incoming values of their successor PHINodes.
7442+
/// PHINode::getIncomingValueForBlock is O(|Preds|), so we'd like to avoid
7443+
/// calling this function on each BasicBlock every time isEqual is called,
7444+
/// especially since the same BasicBlock may be passed as an argument multiple
7445+
/// times. To do this, we can precompute a map of PHINode -> Pred BasicBlock ->
7446+
/// IncomingValue and add it in the Wrapper so isEqual can do O(1) checking
7447+
/// of the incoming values.
7448+
struct SwitchSuccWrapper {
7449+
// Keep so we can use SwitchInst::setSuccessor to do the replacement. It won't
7450+
// be important to equality though.
7451+
unsigned SuccNum;
7452+
BasicBlock *Dest;
7453+
DenseMap<PHINode *, SmallDenseMap<BasicBlock *, Value *, 8>> *PhiPredIVs;
7454+
};
7455+
7456+
namespace llvm {
7457+
template <> struct DenseMapInfo<const SwitchSuccWrapper *> {
7458+
static const SwitchSuccWrapper *getEmptyKey() {
7459+
return static_cast<SwitchSuccWrapper *>(
7460+
DenseMapInfo<void *>::getEmptyKey());
7461+
}
7462+
static const SwitchSuccWrapper *getTombstoneKey() {
7463+
return static_cast<SwitchSuccWrapper *>(
7464+
DenseMapInfo<void *>::getTombstoneKey());
7465+
}
7466+
static unsigned getHashValue(const SwitchSuccWrapper *SSW) {
7467+
BasicBlock *Succ = SSW->Dest;
7468+
BranchInst *BI = cast<BranchInst>(Succ->getTerminator());
7469+
assert(BI->isUnconditional() &&
7470+
"Only supporting unconditional branches for now");
7471+
assert(BI->getNumSuccessors() == 1 &&
7472+
"Expected unconditional branches to have one successor");
7473+
assert(Succ->size() == 1 && "Expected just a single branch in the BB");
7474+
7475+
// Since we assume the BB is just a single BranchInst with a single
7476+
// successor, we hash as the BB and the incoming Values of its successor
7477+
// PHIs. Initially, we tried to just use the successor BB as the hash, but
7478+
// including the incoming PHI values leads to better performance.
7479+
// We also tried to build a map from BB -> Succs.IncomingValues ahead of
7480+
// time and passing it in SwitchSuccWrapper, but this slowed down the
7481+
// average compile time without having any impact on the worst case compile
7482+
// time.
7483+
BasicBlock *BB = BI->getSuccessor(0);
7484+
SmallVector<Value *> PhiValsForBB;
7485+
for (PHINode &Phi : BB->phis())
7486+
PhiValsForBB.emplace_back((*SSW->PhiPredIVs)[&Phi][BB]);
7487+
7488+
return hash_combine(
7489+
BB, hash_combine_range(PhiValsForBB.begin(), PhiValsForBB.end()));
7490+
}
7491+
static bool isEqual(const SwitchSuccWrapper *LHS,
7492+
const SwitchSuccWrapper *RHS) {
7493+
auto EKey = DenseMapInfo<SwitchSuccWrapper *>::getEmptyKey();
7494+
auto TKey = DenseMapInfo<SwitchSuccWrapper *>::getTombstoneKey();
7495+
if (LHS == EKey || RHS == EKey || LHS == TKey || RHS == TKey)
7496+
return LHS == RHS;
7497+
7498+
BasicBlock *A = LHS->Dest;
7499+
BasicBlock *B = RHS->Dest;
7500+
7501+
// FIXME: we checked that the size of A and B are both 1 in
7502+
// simplifyDuplicateSwitchArms to make the Case list smaller to
7503+
// improve performance. If we decide to support BasicBlocks with more
7504+
// than just a single instruction, we need to check that A.size() ==
7505+
// B.size() here, and we need to check more than just the BranchInsts
7506+
// for equality.
7507+
7508+
BranchInst *ABI = cast<BranchInst>(A->getTerminator());
7509+
BranchInst *BBI = cast<BranchInst>(B->getTerminator());
7510+
assert(ABI->isUnconditional() && BBI->isUnconditional() &&
7511+
"Only supporting unconditional branches for now");
7512+
if (ABI->getSuccessor(0) != BBI->getSuccessor(0))
7513+
return false;
7514+
7515+
// Need to check that PHIs in successor have matching values
7516+
BasicBlock *Succ = ABI->getSuccessor(0);
7517+
for (PHINode &Phi : Succ->phis()) {
7518+
auto &PredIVs = (*LHS->PhiPredIVs)[&Phi];
7519+
if (PredIVs[A] != PredIVs[B])
7520+
return false;
7521+
}
7522+
7523+
return true;
7524+
}
7525+
};
7526+
} // namespace llvm
7527+
7528+
bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI,
7529+
DomTreeUpdater *DTU) {
7530+
// Build Cases. Skip BBs that are not candidates for simplification. Mark
7531+
// PHINodes which need to be processed into PhiPredIVs. We decide to process
7532+
// an entire PHI at once after the loop, opposed to calling
7533+
// getIncomingValueForBlock inside this loop, since each call to
7534+
// getIncomingValueForBlock is O(|Preds|).
7535+
SmallPtrSet<PHINode *, 8> Phis;
7536+
SmallPtrSet<BasicBlock *, 8> Seen;
7537+
DenseMap<PHINode *, SmallDenseMap<BasicBlock *, Value *, 8>> PhiPredIVs;
7538+
SmallVector<SwitchSuccWrapper> Cases;
7539+
Cases.reserve(SI->getNumSuccessors());
7540+
7541+
for (unsigned I = 0; I < SI->getNumSuccessors(); ++I) {
7542+
BasicBlock *BB = SI->getSuccessor(I);
7543+
7544+
// FIXME: Support more than just a single BranchInst. One way we could do
7545+
// this is by taking a hashing approach of all insts in BB.
7546+
if (BB->size() != 1)
7547+
continue;
7548+
7549+
// FIXME: This case needs some extra care because the terminators other than
7550+
// SI need to be updated.
7551+
if (BB->hasNPredecessorsOrMore(2))
7552+
continue;
7553+
7554+
// FIXME: Relax that the terminator is a BranchInst by checking for equality
7555+
// on other kinds of terminators. We decide to only support unconditional
7556+
// branches for now for compile time reasons.
7557+
auto *BI = dyn_cast<BranchInst>(BB->getTerminator());
7558+
if (!BI || BI->isConditional())
7559+
continue;
7560+
7561+
if (Seen.insert(BB).second) {
7562+
// Keep track of which PHIs we need as keys in PhiPredIVs below.
7563+
for (BasicBlock *Succ : BI->successors())
7564+
for (PHINode &Phi : Succ->phis())
7565+
Phis.insert(&Phi);
7566+
}
7567+
Cases.emplace_back(SwitchSuccWrapper{I, BB, &PhiPredIVs});
7568+
}
7569+
7570+
// Precompute a data structure to improve performance of isEqual for
7571+
// SwitchSuccWrapper.
7572+
PhiPredIVs.reserve(Phis.size());
7573+
for (PHINode *Phi : Phis) {
7574+
PhiPredIVs[Phi] =
7575+
SmallDenseMap<BasicBlock *, Value *, 8>(Phi->getNumIncomingValues());
7576+
for (auto &IV : Phi->incoming_values())
7577+
PhiPredIVs[Phi].insert({Phi->getIncomingBlock(IV), IV.get()});
7578+
}
7579+
7580+
// Build a set such that if the SwitchSuccWrapper exists in the set and
7581+
// another SwitchSuccWrapper isEqual, then the equivalent SwitchSuccWrapper
7582+
// which is not in the set should be replaced with the one in the set. If the
7583+
// SwitchSuccWrapper is not in the set, then it should be added to the set so
7584+
// other SwitchSuccWrappers can check against it in the same manner. We use
7585+
// SwitchSuccWrapper instead of just BasicBlock because we'd like to pass
7586+
// around information to isEquality, getHashValue, and when doing the
7587+
// replacement with better performance.
7588+
DenseSet<const SwitchSuccWrapper *> ReplaceWith;
7589+
ReplaceWith.reserve(Cases.size());
7590+
7591+
SmallVector<DominatorTree::UpdateType> Updates;
7592+
Updates.reserve(ReplaceWith.size());
7593+
bool MadeChange = false;
7594+
for (auto &SSW : Cases) {
7595+
// SSW is a candidate for simplification. If we find a duplicate BB,
7596+
// replace it.
7597+
const auto [It, Inserted] = ReplaceWith.insert(&SSW);
7598+
if (!Inserted) {
7599+
// We know that SI's parent BB no longer dominates the old case successor
7600+
// since we are making it dead.
7601+
Updates.push_back({DominatorTree::Delete, SI->getParent(), SSW.Dest});
7602+
SI->setSuccessor(SSW.SuccNum, (*It)->Dest);
7603+
MadeChange = true;
7604+
}
7605+
}
7606+
7607+
if (DTU)
7608+
DTU->applyUpdates(Updates);
7609+
7610+
return MadeChange;
7611+
}
7612+
74397613
bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
74407614
BasicBlock *BB = SI->getParent();
74417615

@@ -7496,6 +7670,9 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
74967670
hoistCommonCodeFromSuccessors(SI, !Options.HoistCommonInsts))
74977671
return requestResimplify();
74987672

7673+
if (simplifyDuplicateSwitchArms(SI, DTU))
7674+
return requestResimplify();
7675+
74997676
return false;
75007677
}
75017678

llvm/test/Transforms/PhaseOrdering/switch-sext.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ define i8 @test_switch_with_sext_phi(i8 %code) {
66
; CHECK-SAME: i8 [[CODE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
77
; CHECK-NEXT: entry:
88
; CHECK-NEXT: switch i8 [[CODE]], label [[SW_EPILOG:%.*]] [
9-
; CHECK-NEXT: i8 76, label [[SW_BB3:%.*]]
109
; CHECK-NEXT: i8 108, label [[SW_BB2:%.*]]
10+
; CHECK-NEXT: i8 76, label [[SW_BB3:%.*]]
1111
; CHECK-NEXT: ]
1212
; CHECK: sw.bb2:
1313
; CHECK-NEXT: br label [[SW_EPILOG]]

llvm/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,16 +139,14 @@ define i32 @PR34471(i32 %x) {
139139
; NO_FWD-NEXT: switch i32 [[X:%.*]], label [[ELSE3:%.*]] [
140140
; NO_FWD-NEXT: i32 17, label [[RETURN:%.*]]
141141
; NO_FWD-NEXT: i32 19, label [[IF19:%.*]]
142-
; NO_FWD-NEXT: i32 42, label [[IF42:%.*]]
142+
; NO_FWD-NEXT: i32 42, label [[IF19]]
143143
; NO_FWD-NEXT: ]
144144
; NO_FWD: if19:
145145
; NO_FWD-NEXT: br label [[RETURN]]
146-
; NO_FWD: if42:
147-
; NO_FWD-NEXT: br label [[RETURN]]
148146
; NO_FWD: else3:
149147
; NO_FWD-NEXT: br label [[RETURN]]
150148
; NO_FWD: return:
151-
; NO_FWD-NEXT: [[R:%.*]] = phi i32 [ [[X]], [[IF19]] ], [ [[X]], [[IF42]] ], [ 0, [[ELSE3]] ], [ 17, [[ENTRY:%.*]] ]
149+
; NO_FWD-NEXT: [[R:%.*]] = phi i32 [ [[X]], [[IF19]] ], [ 0, [[ELSE3]] ], [ 17, [[ENTRY:%.*]] ]
152150
; NO_FWD-NEXT: ret i32 [[R]]
153151
;
154152
; FWD-LABEL: @PR34471(

llvm/test/Transforms/SimplifyCFG/HoistCode.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,12 @@ define float @PR39535min_switch(i64 %i, float %x) {
6565
; CHECK-NEXT: entry:
6666
; CHECK-NEXT: switch i64 [[I:%.*]], label [[END:%.*]] [
6767
; CHECK-NEXT: i64 1, label [[BB1:%.*]]
68-
; CHECK-NEXT: i64 2, label [[BB2:%.*]]
68+
; CHECK-NEXT: i64 2, label [[BB1]]
6969
; CHECK-NEXT: ]
7070
; CHECK: bb1:
7171
; CHECK-NEXT: br label [[END]]
72-
; CHECK: bb2:
73-
; CHECK-NEXT: br label [[END]]
7472
; CHECK: end:
75-
; CHECK-NEXT: [[COND:%.*]] = phi fast float [ [[X:%.*]], [[BB1]] ], [ [[X]], [[BB2]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]
73+
; CHECK-NEXT: [[COND:%.*]] = phi fast float [ [[X:%.*]], [[BB1]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]
7674
; CHECK-NEXT: ret float [[COND]]
7775
;
7876
entry:
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S \
3+
; RUN: | FileCheck %s -check-prefix=SIMPLIFY-CFG
4+
5+
define i32 @switch_all_duplicate_arms(i32 %0, i32 %1, i32 %2, i32 %3) {
6+
; SIMPLIFY-CFG-LABEL: define i32 @switch_all_duplicate_arms(
7+
; SIMPLIFY-CFG-SAME: i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]]) {
8+
; SIMPLIFY-CFG-NEXT: switch i32 [[TMP1]], label %[[BB6:.*]] [
9+
; SIMPLIFY-CFG-NEXT: i32 0, label %[[BB5:.*]]
10+
; SIMPLIFY-CFG-NEXT: i32 1, label %[[BB5]]
11+
; SIMPLIFY-CFG-NEXT: ]
12+
; SIMPLIFY-CFG: [[BB5]]:
13+
; SIMPLIFY-CFG-NEXT: br label %[[BB6]]
14+
; SIMPLIFY-CFG: [[BB6]]:
15+
; SIMPLIFY-CFG-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP4:%.*]] ], [ [[TMP2]], %[[BB5]] ]
16+
; SIMPLIFY-CFG-NEXT: ret i32 [[TMP8]]
17+
;
18+
switch i32 %1, label %7 [
19+
i32 0, label %5
20+
i32 1, label %6
21+
]
22+
23+
5:
24+
br label %7
25+
26+
6:
27+
br label %7
28+
29+
7:
30+
%8 = phi i32 [ %3, %4 ], [ %2, %6 ], [ %2, %5 ]
31+
ret i32 %8
32+
}
33+
34+
define i32 @switch_some_duplicate_arms(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4) {
35+
; SIMPLIFY-CFG-LABEL: define i32 @switch_some_duplicate_arms(
36+
; SIMPLIFY-CFG-SAME: i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]], i32 [[TMP4:%.*]]) {
37+
; SIMPLIFY-CFG-NEXT: switch i32 [[TMP1]], label %[[BB8:.*]] [
38+
; SIMPLIFY-CFG-NEXT: i32 0, label %[[BB6:.*]]
39+
; SIMPLIFY-CFG-NEXT: i32 1, label %[[BB6]]
40+
; SIMPLIFY-CFG-NEXT: i32 2, label %[[BB7:.*]]
41+
; SIMPLIFY-CFG-NEXT: ]
42+
; SIMPLIFY-CFG: [[BB6]]:
43+
; SIMPLIFY-CFG-NEXT: br label %[[BB8]]
44+
; SIMPLIFY-CFG: [[BB7]]:
45+
; SIMPLIFY-CFG-NEXT: br label %[[BB8]]
46+
; SIMPLIFY-CFG: [[BB8]]:
47+
; SIMPLIFY-CFG-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP3]], [[TMP5:%.*]] ], [ [[TMP4]], %[[BB7]] ], [ [[TMP2]], %[[BB6]] ]
48+
; SIMPLIFY-CFG-NEXT: ret i32 [[TMP10]]
49+
;
50+
switch i32 %1, label %9 [
51+
i32 0, label %6
52+
i32 1, label %7
53+
i32 2, label %8
54+
]
55+
56+
6:
57+
br label %9
58+
59+
7:
60+
br label %9
61+
62+
8:
63+
br label %9
64+
65+
9:
66+
%10 = phi i32 [ %3, %5 ], [ %4, %8 ], [ %2, %7 ], [ %2, %6 ]
67+
ret i32 %10
68+
}
69+
70+
define i32 @switch_duplicate_arms_multipred(i1 %0, i32 %1, i32 %2, i32 %3, i32 %4) {
71+
; SIMPLIFY-CFG-LABEL: define i32 @switch_duplicate_arms_multipred(
72+
; SIMPLIFY-CFG-SAME: i1 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]], i32 [[TMP4:%.*]]) {
73+
; SIMPLIFY-CFG-NEXT: br i1 [[TMP0]], label %[[BB6:.*]], label %[[BB7:.*]]
74+
; SIMPLIFY-CFG: [[BB6]]:
75+
; SIMPLIFY-CFG-NEXT: switch i32 [[TMP2]], label %[[BB9:.*]] [
76+
; SIMPLIFY-CFG-NEXT: i32 0, label %[[BB7]]
77+
; SIMPLIFY-CFG-NEXT: i32 1, label %[[BB8:.*]]
78+
; SIMPLIFY-CFG-NEXT: ]
79+
; SIMPLIFY-CFG: [[BB7]]:
80+
; SIMPLIFY-CFG-NEXT: br label %[[BB9]]
81+
; SIMPLIFY-CFG: [[BB8]]:
82+
; SIMPLIFY-CFG-NEXT: br label %[[BB9]]
83+
; SIMPLIFY-CFG: [[BB9]]:
84+
; SIMPLIFY-CFG-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP4]], %[[BB6]] ], [ [[TMP3]], %[[BB8]] ], [ [[TMP3]], %[[BB7]] ]
85+
; SIMPLIFY-CFG-NEXT: ret i32 [[TMP10]]
86+
;
87+
br i1 %0, label %6, label %7
88+
6:
89+
switch i32 %2, label %9 [
90+
i32 0, label %7
91+
i32 1, label %8
92+
]
93+
94+
7:
95+
br label %9
96+
97+
8:
98+
br label %9
99+
100+
9:
101+
%10 = phi i32 [ %4, %6 ], [ %3, %8 ], [ %3, %7 ]
102+
ret i32 %10
103+
}
104+
105+
define i32 @switch_dup_default(i32 %0, i32 %1, i32 %2, i32 %3) {
106+
; SIMPLIFY-CFG-LABEL: define i32 @switch_dup_default(
107+
; SIMPLIFY-CFG-SAME: i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]]) {
108+
; SIMPLIFY-CFG-NEXT: [[COND:%.*]] = icmp eq i32 [[TMP1]], 0
109+
; SIMPLIFY-CFG-NEXT: [[TMP8:%.*]] = select i1 [[COND]], i32 [[TMP3]], i32 [[TMP2]]
110+
; SIMPLIFY-CFG-NEXT: ret i32 [[TMP8]]
111+
;
112+
switch i32 %1, label %7 [
113+
i32 0, label %5
114+
i32 1, label %6
115+
]
116+
117+
5:
118+
br label %8
119+
120+
6:
121+
br label %8
122+
123+
7:
124+
br label %8
125+
126+
8:
127+
%9 = phi i32 [ %3, %5 ], [ %2, %6 ], [ %2, %7 ]
128+
ret i32 %9
129+
}

llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,16 +272,14 @@ define i8 @switch_to_select_two_case_results_no_default(i32 %i) {
272272
; CHECK-NEXT: i32 0, label [[END:%.*]]
273273
; CHECK-NEXT: i32 2, label [[END]]
274274
; CHECK-NEXT: i32 4, label [[CASE3:%.*]]
275-
; CHECK-NEXT: i32 6, label [[CASE4:%.*]]
275+
; CHECK-NEXT: i32 6, label [[CASE3]]
276276
; CHECK-NEXT: ]
277277
; CHECK: case3:
278278
; CHECK-NEXT: br label [[END]]
279-
; CHECK: case4:
280-
; CHECK-NEXT: br label [[END]]
281279
; CHECK: default:
282280
; CHECK-NEXT: unreachable
283281
; CHECK: end:
284-
; CHECK-NEXT: [[T0:%.*]] = phi i8 [ 44, [[CASE3]] ], [ 44, [[CASE4]] ], [ 42, [[ENTRY:%.*]] ], [ 42, [[ENTRY]] ]
282+
; CHECK-NEXT: [[T0:%.*]] = phi i8 [ 44, [[CASE3]] ], [ 42, [[ENTRY:%.*]] ], [ 42, [[ENTRY]] ]
285283
; CHECK-NEXT: ret i8 [[T0]]
286284
;
287285
entry:

0 commit comments

Comments
 (0)