From 3a998c06a8e93989319238e12b56a731198cc1c2 Mon Sep 17 00:00:00 2001 From: Jun Ma Date: Mon, 27 Sep 2021 20:39:05 +0800 Subject: [PATCH] Revert "Recommit "Revert "[CVP] processSwitch: Remove default case when switch cover all possible values.""" This reverts commit 8ba2adcf9e54b34ba8efa73ac0d81a1192e4f614. --- llvm/include/llvm/Transforms/Utils/Local.h | 5 ---- .../Scalar/CorrelatedValuePropagation.cpp | 27 +------------------ llvm/lib/Transforms/Utils/Local.cpp | 20 -------------- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 20 ++++++++++++++ .../CorrelatedValuePropagation/basic.ll | 11 ++++---- 5 files changed, 26 insertions(+), 57 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h index f003615eca78..97686d7d5f2f 100644 --- a/llvm/include/llvm/Transforms/Utils/Local.h +++ b/llvm/include/llvm/Transforms/Utils/Local.h @@ -55,7 +55,6 @@ class MDNode; class MemorySSAUpdater; class PHINode; class StoreInst; -class SwitchInst; class TargetLibraryInfo; class TargetTransformInfo; @@ -237,10 +236,6 @@ CallInst *createCallMatchingInvoke(InvokeInst *II); /// This function converts the specified invoek into a normall call. void changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr); -/// This function removes the default destination from the specified switch. -void createUnreachableSwitchDefault(SwitchInst *Switch, - DomTreeUpdater *DTU = nullptr); - ///===---------------------------------------------------------------------===// /// Dbg Intrinsic utilities /// diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 4b8392db9628..6dbd3da24059 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -341,13 +341,7 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI, // ConstantFoldTerminator() as the underlying SwitchInst can be changed. SwitchInstProfUpdateWrapper SI(*I); - APInt Low = - APInt::getSignedMaxValue(Cond->getType()->getScalarSizeInBits()); - APInt High = - APInt::getSignedMinValue(Cond->getType()->getScalarSizeInBits()); - - SwitchInst::CaseIt CI = SI->case_begin(); - for (auto CE = SI->case_end(); CI != CE;) { + for (auto CI = SI->case_begin(), CE = SI->case_end(); CI != CE;) { ConstantInt *Case = CI->getCaseValue(); LazyValueInfo::Tristate State = LVI->getPredicateAt(CmpInst::ICMP_EQ, Cond, Case, I, @@ -380,28 +374,9 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI, break; } - // Get Lower/Upper bound from switch cases. - Low = APIntOps::smin(Case->getValue(), Low); - High = APIntOps::smax(Case->getValue(), High); - // Increment the case iterator since we didn't delete it. ++CI; } - - // Try to simplify default case as unreachable - if (CI == SI->case_end() && SI->getNumCases() != 0 && - !isa(SI->getDefaultDest()->getFirstNonPHIOrDbg())) { - const ConstantRange SIRange = - LVI->getConstantRange(SI->getCondition(), SI); - - // If the numbered switch cases cover the entire range of the condition, - // then the default case is not reachable. - if (SIRange.getSignedMin() == Low && SIRange.getSignedMax() == High && - SI->getNumCases() == High - Low + 1) { - createUnreachableSwitchDefault(SI, &DTU); - Changed = true; - } - } } if (Changed) diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 5aeafb775f21..0274eef248db 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -2182,26 +2182,6 @@ void llvm::changeToCall(InvokeInst *II, DomTreeUpdater *DTU) { DTU->applyUpdates({{DominatorTree::Delete, BB, UnwindDestBB}}); } -void llvm::createUnreachableSwitchDefault(SwitchInst *Switch, - DomTreeUpdater *DTU) { - LLVM_DEBUG(dbgs() << "SimplifyCFG: switch default is dead.\n"); - auto *BB = Switch->getParent(); - auto *OrigDefaultBlock = Switch->getDefaultDest(); - OrigDefaultBlock->removePredecessor(BB); - BasicBlock *NewDefaultBlock = BasicBlock::Create( - BB->getContext(), BB->getName() + ".unreachabledefault", BB->getParent(), - OrigDefaultBlock); - new UnreachableInst(Switch->getContext(), NewDefaultBlock); - Switch->setDefaultDest(&*NewDefaultBlock); - if (DTU) { - SmallVector Updates; - Updates.push_back({DominatorTree::Insert, BB, &*NewDefaultBlock}); - if (!is_contained(successors(BB), OrigDefaultBlock)) - Updates.push_back({DominatorTree::Delete, BB, &*OrigDefaultBlock}); - DTU->applyUpdates(Updates); - } -} - BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI, BasicBlock *UnwindEdge, DomTreeUpdater *DTU) { diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index a3bd89e72af9..3add561c66d5 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -4784,6 +4784,26 @@ static bool CasesAreContiguous(SmallVectorImpl &Cases) { return true; } +static void createUnreachableSwitchDefault(SwitchInst *Switch, + DomTreeUpdater *DTU) { + LLVM_DEBUG(dbgs() << "SimplifyCFG: switch default is dead.\n"); + auto *BB = Switch->getParent(); + auto *OrigDefaultBlock = Switch->getDefaultDest(); + OrigDefaultBlock->removePredecessor(BB); + BasicBlock *NewDefaultBlock = BasicBlock::Create( + BB->getContext(), BB->getName() + ".unreachabledefault", BB->getParent(), + OrigDefaultBlock); + new UnreachableInst(Switch->getContext(), NewDefaultBlock); + Switch->setDefaultDest(&*NewDefaultBlock); + if (DTU) { + SmallVector Updates; + Updates.push_back({DominatorTree::Insert, BB, &*NewDefaultBlock}); + if (!is_contained(successors(BB), OrigDefaultBlock)) + Updates.push_back({DominatorTree::Delete, BB, &*OrigDefaultBlock}); + DTU->applyUpdates(Updates); + } +} + /// Turn a switch with two reachable destinations into an integer range /// comparison and branch. bool SimplifyCFGOpt::TurnSwitchRangeIntoICmp(SwitchInst *SI, diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll index a620c8468d4d..5abbcbc90e01 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll @@ -382,7 +382,7 @@ define i32 @switch_range(i32 %cond) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND:%.*]], 3 ; CHECK-NEXT: [[S1:%.*]] = add nuw nsw i32 [[S]], 1 -; CHECK-NEXT: switch i32 [[S1]], label [[ENTRY_UNREACHABLEDEFAULT:%.*]] [ +; CHECK-NEXT: switch i32 [[S1]], label [[UNREACHABLE:%.*]] [ ; CHECK-NEXT: i32 1, label [[EXIT1:%.*]] ; CHECK-NEXT: i32 2, label [[EXIT2:%.*]] ; CHECK-NEXT: i32 3, label [[EXIT1]] @@ -391,8 +391,6 @@ define i32 @switch_range(i32 %cond) { ; CHECK-NEXT: ret i32 1 ; CHECK: exit2: ; CHECK-NEXT: ret i32 2 -; CHECK: entry.unreachabledefault: -; CHECK-NEXT: unreachable ; CHECK: unreachable: ; CHECK-NEXT: ret i32 0 ; @@ -455,9 +453,10 @@ define i8 @switch_defaultdest_multipleuse(i8 %t0) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[O:%.*]] = or i8 [[T0:%.*]], 1 ; CHECK-NEXT: [[R:%.*]] = srem i8 1, [[O]] -; CHECK-NEXT: br label [[EXIT:%.*]] -; CHECK: entry.unreachabledefault: -; CHECK-NEXT: unreachable +; CHECK-NEXT: switch i8 [[R]], label [[EXIT:%.*]] [ +; CHECK-NEXT: i8 0, label [[EXIT]] +; CHECK-NEXT: i8 1, label [[EXIT]] +; CHECK-NEXT: ] ; CHECK: exit: ; CHECK-NEXT: ret i8 0 ;