[llvm] [SimplifyCFG] Simplify identical predessors (PR #173022)
Kunqiu Chen via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 19 23:45:41 PST 2025
https://github.com/Camsyn updated https://github.com/llvm/llvm-project/pull/173022
>From abf72043c8a5416cbb48fcdd43a9eb0681409296 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Fri, 19 Dec 2025 23:27:13 +0800
Subject: [PATCH 1/4] before-commit test
---
llvm/test/Transforms/SimplifyCFG/dup-preds.ll | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 llvm/test/Transforms/SimplifyCFG/dup-preds.ll
diff --git a/llvm/test/Transforms/SimplifyCFG/dup-preds.ll b/llvm/test/Transforms/SimplifyCFG/dup-preds.ll
new file mode 100644
index 0000000000000..859ef2a64e394
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/dup-preds.ll
@@ -0,0 +1,55 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s -check-prefix=SIMPLIFY-CFG
+
+define i8 @foo(i8 %v1, i8 %v2) {
+; SIMPLIFY-CFG-LABEL: @foo(
+; SIMPLIFY-CFG-NEXT: entry:
+; SIMPLIFY-CFG-NEXT: switch i8 [[V1:%.*]], label [[EXIT:%.*]] [
+; SIMPLIFY-CFG-NEXT: i8 0, label [[THEN:%.*]]
+; SIMPLIFY-CFG-NEXT: i8 1, label [[ELSE:%.*]]
+; SIMPLIFY-CFG-NEXT: ]
+; SIMPLIFY-CFG: then:
+; SIMPLIFY-CFG-NEXT: switch i8 [[V2:%.*]], label [[EXIT]] [
+; SIMPLIFY-CFG-NEXT: i8 0, label [[SWITCH_CASE_0:%.*]]
+; SIMPLIFY-CFG-NEXT: i8 1, label [[SWITCH_CASE_1:%.*]]
+; SIMPLIFY-CFG-NEXT: i8 2, label [[SWITCH_CASE_1]]
+; SIMPLIFY-CFG-NEXT: ]
+; SIMPLIFY-CFG: switch.case.0:
+; SIMPLIFY-CFG-NEXT: br label [[EXIT]]
+; SIMPLIFY-CFG: switch.case.1:
+; SIMPLIFY-CFG-NEXT: br label [[EXIT]]
+; SIMPLIFY-CFG: else:
+; SIMPLIFY-CFG-NEXT: br label [[EXIT]]
+; SIMPLIFY-CFG: exit:
+; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = phi i8 [ 0, [[ELSE]] ], [ 0, [[SWITCH_CASE_0]] ], [ 1, [[SWITCH_CASE_1]] ], [ 2, [[THEN]] ], [ 3, [[ENTRY:%.*]] ]
+; SIMPLIFY-CFG-NEXT: ret i8 [[RET]]
+;
+entry:
+ switch i8 %v1, label %exit [
+ i8 0, label %then
+ i8 1, label %else
+ ]
+
+then: ; preds = %entry
+ switch i8 %v2, label %exit [
+ i8 0, label %switch.case.0
+ i8 1, label %switch.case.1
+ i8 2, label %switch.case.2
+ ]
+
+switch.case.0: ; preds = %then
+ br label %exit
+
+switch.case.1: ; preds = %then
+ br label %exit
+
+switch.case.2: ; preds = %then
+ br label %exit
+
+else: ; preds = %entry
+ br label %exit
+
+exit: ; preds = %else, %switch.case.2, %switch.case.1, %switch.case.0, %then, %entry
+ %ret = phi i8 [ 0, %else ], [ 0, %switch.case.0 ], [ 1, %switch.case.1 ], [ 1, %switch.case.2 ], [ 2, %then ], [ 3, %entry ]
+ ret i8 %ret
+}
>From feb66ffeecbbc44f57e1cf8bfb9759b195695a2e Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Fri, 19 Dec 2025 23:20:33 +0800
Subject: [PATCH 2/4] feat: impl generic dup preds merging
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 214 +++++++++++++++++++++-
1 file changed, 212 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 2a957737697c3..80144707cc993 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -319,6 +319,7 @@ class SimplifyCFGOpt {
bool simplifySwitchOnSelect(SwitchInst *SI, SelectInst *Select);
bool simplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI);
bool turnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder);
+ bool simplifyDuplicatePredecessors(BasicBlock *Succ, DomTreeUpdater *DTU);
public:
SimplifyCFGOpt(const TargetTransformInfo &TTI, DomTreeUpdater *DTU,
@@ -8666,6 +8667,212 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
return false;
}
+/// Checking whether two BBs are equal depends on the contents of the
+/// BasicBlock and the incoming values of their successor PHINodes.
+/// PHINode::getIncomingValueForBlock is O(|Preds|), so we'd like to avoid
+/// calling this function on each BasicBlock every time isEqual is called,
+/// especially since the same BasicBlock may be passed as an argument multiple
+/// times. To do this, we can precompute a map of PHINode -> Pred BasicBlock ->
+/// IncomingValue and add it in the Wrapper so isEqual can do O(1) checking
+/// of the incoming values.
+struct EqualBBWrapper {
+ BasicBlock *BB;
+
+ // One Phi usually has < 8 incoming values.
+ using BB2ValueMap = SmallDenseMap<BasicBlock *, Value *, 8>;
+ using Phi2IVsMap = DenseMap<PHINode *, BB2ValueMap>;
+ Phi2IVsMap *PhiPredIVs;
+};
+
+template <> struct llvm::DenseMapInfo<const EqualBBWrapper *> {
+ static const EqualBBWrapper *getEmptyKey() {
+ return static_cast<EqualBBWrapper *>(DenseMapInfo<void *>::getEmptyKey());
+ }
+ static const EqualBBWrapper *getTombstoneKey() {
+ return static_cast<EqualBBWrapper *>(
+ DenseMapInfo<void *>::getTombstoneKey());
+ }
+ static unsigned getHashValue(const EqualBBWrapper *SSW) {
+ BasicBlock *BB = SSW->BB;
+ BranchInst *BI = cast<BranchInst>(BB->getTerminator());
+ assert(BI->isUnconditional() &&
+ "Only supporting unconditional branches for now");
+ assert(BI->getNumSuccessors() == 1 &&
+ "Expected unconditional branches to have one successor");
+ assert(BB->size() == 1 && "Expected just a single branch in the BB");
+
+ // Since we assume the BB is just a single BranchInst with a single
+ // successor, we hash as the BB and the incoming Values of its successor
+ // PHIs. Initially, we tried to just use the successor BB as the hash, but
+ // including the incoming PHI values leads to better performance.
+ // We also tried to build a map from BB -> Succs.IncomingValues ahead of
+ // time and passing it in SwitchSuccWrapper, but this slowed down the
+ // average compile time without having any impact on the worst case compile
+ // time.
+ BasicBlock *Succ = BI->getSuccessor(0);
+ auto PhiValsForBB = map_range(
+ BB->phis(), [BB, &PhiPredIVs = *SSW->PhiPredIVs](PHINode &Phi) {
+ return PhiPredIVs[&Phi][BB];
+ });
+ return hash_combine(Succ, hash_combine_range(PhiValsForBB));
+ }
+ static bool isEqual(const EqualBBWrapper *LHS, const EqualBBWrapper *RHS) {
+ auto *EKey = DenseMapInfo<EqualBBWrapper *>::getEmptyKey();
+ auto *TKey = DenseMapInfo<EqualBBWrapper *>::getTombstoneKey();
+ if (LHS == EKey || RHS == EKey || LHS == TKey || RHS == TKey)
+ return LHS == RHS;
+
+ BasicBlock *A = LHS->BB;
+ BasicBlock *B = RHS->BB;
+
+ // FIXME: we checked that the size of A and B are both 1 in
+ // simplifyDuplicateSwitchArms to make the Case list smaller to
+ // improve performance. If we decide to support BasicBlocks with more
+ // than just a single instruction, we need to check that A.size() ==
+ // B.size() here, and we need to check more than just the BranchInsts
+ // for equality.
+
+ BranchInst *ABI = cast<BranchInst>(A->getTerminator());
+ BranchInst *BBI = cast<BranchInst>(B->getTerminator());
+ assert(ABI->isUnconditional() && BBI->isUnconditional() &&
+ "Only supporting unconditional branches for now");
+ if (ABI->getSuccessor(0) != BBI->getSuccessor(0))
+ return false;
+
+ // Need to check that PHIs in successor have matching values
+ BasicBlock *Succ = ABI->getSuccessor(0);
+ auto IfPhiIVMatch = [A, B, &PhiPredIVs = *LHS->PhiPredIVs](PHINode &Phi) {
+ // Replace O(|Pred|) Phi.getIncomingValueForBlock with this O(1) hashmap
+ // query
+ auto &PredIVs = PhiPredIVs[&Phi];
+ return PredIVs[A] == PredIVs[B];
+ };
+ return all_of(Succ->phis(), IfPhiIVMatch);
+ }
+};
+
+bool SimplifyCFGOpt::simplifyDuplicatePredecessors(BasicBlock *Succ,
+ DomTreeUpdater *DTU) {
+ // Need at least 2 predecessors to do anything.
+ if (!Succ || pred_empty(Succ))
+ return false;
+ // Precompute PHI incoming values in Succ for all candidate preds.
+ // PhiPredIVs[Phi][Pred] = incoming value
+ EqualBBWrapper::Phi2IVsMap PhiPredIVs;
+
+ // We only handle a single successor "Succ"; caller can iterate blocks.
+ // Collect candidate predecessors P with:
+ // - terminator unconditional br to Succ,
+ // - does not have address taken / weird control.
+ auto Filter = [Succ](BasicBlock *Pred) {
+ // Single successor and must be Succ.
+ auto *BI = dyn_cast<BranchInst>(Pred->getTerminator());
+ if (!BI || !BI->isUnconditional())
+ return false;
+
+ // Avoid blocks that are "address-taken" (blockaddress) or have unusual
+ // uses.
+ if (Pred->hasAddressTaken())
+ return false;
+ if (Pred->isLandingPad())
+ return false;
+
+ // TODO: should we support Pred with >1 instructions?
+ if (Pred->size() != 1)
+ return false;
+
+ // Avoid self-loop predecessor merging for now.
+ if (Pred == Succ)
+ return false;
+
+ return true;
+ };
+
+ auto FilteredPreds = make_filter_range(predecessors(Succ), Filter);
+
+ SmallVector<EqualBBWrapper> Preds(
+ map_range(FilteredPreds, [&PhiPredIVs](BasicBlock *Pred) {
+ return EqualBBWrapper{Pred, &PhiPredIVs};
+ }));
+
+ if (Preds.size() < 2)
+ return false;
+
+ SmallVector<PHINode *, 8> Phis(make_pointer_range(Succ->phis()));
+
+ PhiPredIVs.reserve(Phis.size());
+ for (PHINode *Phi : Phis) {
+ auto &IVs =
+ PhiPredIVs.try_emplace(Phi, Phi->getNumIncomingValues()).first->second;
+ // Pre-fill all incoming for O(1) lookup as Phi.getIncomingValueForBlock is
+ // O(|Pred|).
+ for (auto &IV : Phi->incoming_values())
+ IVs.insert({Phi->getIncomingBlock(IV), IV.get()});
+ }
+
+ // Group duplicates using DenseSet with custom equality/hashing.
+ DenseSet<const EqualBBWrapper *> Keep;
+ Keep.reserve(Preds.size());
+
+ SmallVector<DominatorTree::UpdateType> Updates;
+ Updates.reserve(Preds.size() * 2);
+
+ bool MadeChange = false;
+
+ // Helper: redirect all edges X -> DeadPred to X -> LivePred.
+ auto RedirectIncomingEdges = [&](BasicBlock *DeadPred, BasicBlock *LivePred) {
+ // Replace successors in all predecessors of DeadPred.
+ SmallSetVector<BasicBlock *, 8> DeadPredPreds(llvm::from_range,
+ predecessors(DeadPred));
+ if (DTU) {
+ // All predecessors of DeadPred (except the common predecessor) will be
+ // moved to LivePred.
+ Updates.reserve(Updates.size() + DeadPredPreds.size() * 2);
+ SmallPtrSet<BasicBlock *, 16> LivePredPreds(llvm::from_range,
+ predecessors(LivePred));
+ for (BasicBlock *PP : DeadPredPreds) {
+ // Do not modify those common predecessors of DeadPred and LivePred
+ if (!LivePredPreds.contains(PP))
+ Updates.push_back({DominatorTree::Insert, PP, LivePred});
+ Updates.push_back({DominatorTree::Delete, PP, DeadPred});
+ }
+ }
+ for (BasicBlock *PP : DeadPredPreds) {
+ Instruction *T = PP->getTerminator();
+ T->replaceSuccessorWith(DeadPred, LivePred);
+ }
+ };
+
+ // Try to canonicalize duplicates.
+ for (const auto &Pred : Preds) {
+ // Pred is a candidate for simplification. If we find a duplicate BB,
+ // replace it.
+ const auto [It, Inserted] = Keep.insert(&Pred);
+ if (Inserted)
+ continue;
+
+ // Found duplicate: merge P into canonical predecessor It->Pred.
+ BasicBlock *KeepPred = (*It)->BB;
+ BasicBlock *DeadPred = Pred.BB;
+
+ // Avoid merging if either is the other's predecessor in weird ways.
+ if (KeepPred == DeadPred)
+ continue;
+
+ // Redirect all edges into DeadPred to KeepPred.
+ RedirectIncomingEdges(DeadPred, KeepPred);
+
+ // Now DeadPred should become unreachable; leave DCE to later,
+ // but we can try to simplify it if it only branches to Succ.
+ // (We won't erase here to keep the routine simple and DT-safe.)
+ MadeChange = true;
+ }
+
+ if (DTU && !Updates.empty())
+ DTU->applyUpdates(Updates);
+
+ return MadeChange;
+}
/// Check if passing a value to an instruction will cause undefined behavior.
static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValueMayBeModified) {
@@ -8912,8 +9119,6 @@ bool SimplifyCFGOpt::simplifyOnce(BasicBlock *BB) {
return true;
}
- IRBuilder<> Builder(BB);
-
if (Options.SpeculateBlocks &&
!BB->getParent()->hasFnAttribute(Attribute::OptForFuzzing)) {
// If there is a trivial two-entry PHI node in this basic block, and we can
@@ -8925,6 +9130,11 @@ bool SimplifyCFGOpt::simplifyOnce(BasicBlock *BB) {
return true;
}
+ // Merge identical predecessors of this block
+ if (simplifyDuplicatePredecessors(BB, DTU))
+ return true;
+
+ IRBuilder<> Builder(BB);
Instruction *Terminator = BB->getTerminator();
Builder.SetInsertPoint(Terminator);
switch (Terminator->getOpcode()) {
>From df9dbfea32da0b3c0a35a193cc980830fb9eb992 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Sat, 20 Dec 2025 00:24:37 +0800
Subject: [PATCH 3/4] Regenerate some existing tests
---
.../Transforms/LoopDeletion/simplify-then-delete.ll | 5 +++++
.../SimplifyCFG/X86/switch-to-lookup-globals.ll | 13 +++----------
.../SimplifyCFG/X86/switch_to_lookup_table.ll | 2 +-
llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll | 10 ++++------
4 files changed, 13 insertions(+), 17 deletions(-)
diff --git a/llvm/test/Transforms/LoopDeletion/simplify-then-delete.ll b/llvm/test/Transforms/LoopDeletion/simplify-then-delete.ll
index 529ee8919bdb3..869fea650f49f 100644
--- a/llvm/test/Transforms/LoopDeletion/simplify-then-delete.ll
+++ b/llvm/test/Transforms/LoopDeletion/simplify-then-delete.ll
@@ -11,6 +11,11 @@ define i32 @pmat(i32 %m, i32 %n, ptr %y, i1 %arg) nounwind {
; CHECK-LABEL: @pmat(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[M:%.*]], 0
+; CHECK-NEXT: br i1 [[CMP4]], label [[BB_N10:%.*]], label [[W_E12:%.*]]
+; CHECK: bb.n10:
+; CHECK-NEXT: [[CMP51:%.*]] = icmp sgt i32 [[N:%.*]], 0
+; CHECK-NEXT: br label [[W_E12]]
+; CHECK: w.e12:
; CHECK-NEXT: ret i32 0
;
entry:
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-globals.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-globals.ll
index bfcc8344264ea..4745cd0f7ea3a 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-globals.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-globals.ll
@@ -10,16 +10,9 @@ target triple = "x86_64-unknown-linux-gnu"
define i1 @zot(i32 %arg) {
; CHECK-LABEL: @zot(
; CHECK-NEXT: bb:
-; CHECK-NEXT: %0 = icmp ult i32 %arg, 3
-; CHECK-NEXT: br i1 %0, label %switch.lookup, label %bb6
-; CHECK: switch.lookup:
-; CHECK-NEXT: %1 = zext nneg i32 %arg to i64
-; CHECK-NEXT: %switch.gep = getelementptr inbounds [3 x ptr], ptr @switch.table.zot, i64 0, i64 %1
-; CHECK-NEXT: %switch.load = load ptr, ptr %switch.gep, align 8
-; CHECK-NEXT: br label %bb6
-; CHECK: bb6:
-; CHECK-NEXT: %tmp7 = phi ptr [ null, %bb ], [ %switch.load, %switch.lookup ]
-; CHECK-NEXT: %tmp8 = icmp eq ptr %tmp7, getelementptr inbounds ([75 x { i32, i32, i32, i8, i8 }], ptr @global, i64 1, i64 0, i32 0)
+; CHECK-NEXT: %cond = icmp eq i32 %arg, 1
+; CHECK-NEXT: %spec.select = select i1 %cond, ptr getelementptr inbounds ([75 x { i32, i32, i32, i8, i8 }], ptr @global, i64 0, i64 6, i32 0), ptr null
+; CHECK-NEXT: %tmp8 = icmp eq ptr %spec.select, getelementptr inbounds ([75 x { i32, i32, i32, i8, i8 }], ptr @global, i64 1, i64 0, i32 0)
; CHECK-NEXT: ret i1 %tmp8
;
bb:
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
index f91adcc9707d8..25fb09aad5871 100644
--- a/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
+++ b/llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
@@ -1609,7 +1609,7 @@ define i32 @PR26308(i1 %B, i64 %load) {
; CHECK-LABEL: @PR26308(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[CLEANUP4:%.*]]
-; CHECK: cleanup4:
+; CHECK: while.body:
; CHECK-NEXT: br label [[CLEANUP4]]
;
entry:
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll b/llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll
index ae7baeb970689..e9edb33b9420c 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll
@@ -72,16 +72,14 @@ define i32 @switch_duplicate_arms_multipred(i1 %0, i32 %1, i32 %2, i32 %3, i32 %
; SIMPLIFY-CFG-SAME: i1 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]], i32 [[TMP4:%.*]]) {
; SIMPLIFY-CFG-NEXT: br i1 [[TMP0]], label %[[BB6:.*]], label %[[BB7:.*]]
; SIMPLIFY-CFG: [[BB6]]:
-; SIMPLIFY-CFG-NEXT: switch i32 [[TMP2]], label %[[BB9:.*]] [
+; SIMPLIFY-CFG-NEXT: switch i32 [[TMP2]], label %[[BB8:.*]] [
; SIMPLIFY-CFG-NEXT: i32 0, label %[[BB7]]
-; SIMPLIFY-CFG-NEXT: i32 1, label %[[BB8:.*]]
+; SIMPLIFY-CFG-NEXT: i32 1, label %[[BB7]]
; SIMPLIFY-CFG-NEXT: ]
; SIMPLIFY-CFG: [[BB7]]:
-; SIMPLIFY-CFG-NEXT: br label %[[BB9]]
+; SIMPLIFY-CFG-NEXT: br label %[[BB8]]
; SIMPLIFY-CFG: [[BB8]]:
-; SIMPLIFY-CFG-NEXT: br label %[[BB9]]
-; SIMPLIFY-CFG: [[BB9]]:
-; SIMPLIFY-CFG-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP4]], %[[BB6]] ], [ [[TMP3]], %[[BB8]] ], [ [[TMP3]], %[[BB7]] ]
+; SIMPLIFY-CFG-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP4]], %[[BB6]] ], [ [[TMP3]], %[[BB7]] ]
; SIMPLIFY-CFG-NEXT: ret i32 [[TMP10]]
;
br i1 %0, label %6, label %7
>From 4e0b53a79e9b888b5675056487afddc14598e567 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Sat, 20 Dec 2025 00:28:36 +0800
Subject: [PATCH 4/4] after-commit test
---
llvm/test/Transforms/SimplifyCFG/dup-preds.ll | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/test/Transforms/SimplifyCFG/dup-preds.ll b/llvm/test/Transforms/SimplifyCFG/dup-preds.ll
index 859ef2a64e394..590e28fb1e67b 100644
--- a/llvm/test/Transforms/SimplifyCFG/dup-preds.ll
+++ b/llvm/test/Transforms/SimplifyCFG/dup-preds.ll
@@ -10,18 +10,16 @@ define i8 @foo(i8 %v1, i8 %v2) {
; SIMPLIFY-CFG-NEXT: ]
; SIMPLIFY-CFG: then:
; SIMPLIFY-CFG-NEXT: switch i8 [[V2:%.*]], label [[EXIT]] [
-; SIMPLIFY-CFG-NEXT: i8 0, label [[SWITCH_CASE_0:%.*]]
+; SIMPLIFY-CFG-NEXT: i8 0, label [[ELSE]]
; SIMPLIFY-CFG-NEXT: i8 1, label [[SWITCH_CASE_1:%.*]]
; SIMPLIFY-CFG-NEXT: i8 2, label [[SWITCH_CASE_1]]
; SIMPLIFY-CFG-NEXT: ]
-; SIMPLIFY-CFG: switch.case.0:
-; SIMPLIFY-CFG-NEXT: br label [[EXIT]]
; SIMPLIFY-CFG: switch.case.1:
; SIMPLIFY-CFG-NEXT: br label [[EXIT]]
; SIMPLIFY-CFG: else:
; SIMPLIFY-CFG-NEXT: br label [[EXIT]]
; SIMPLIFY-CFG: exit:
-; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = phi i8 [ 0, [[ELSE]] ], [ 0, [[SWITCH_CASE_0]] ], [ 1, [[SWITCH_CASE_1]] ], [ 2, [[THEN]] ], [ 3, [[ENTRY:%.*]] ]
+; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = phi i8 [ 0, [[ELSE]] ], [ 1, [[SWITCH_CASE_1]] ], [ 2, [[THEN]] ], [ 3, [[ENTRY:%.*]] ]
; SIMPLIFY-CFG-NEXT: ret i8 [[RET]]
;
entry:
More information about the llvm-commits
mailing list