diff options
author | Philip Reames <listmail@philipreames.com> | 2015-08-26 23:56:46 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2015-08-26 23:56:46 +0000 |
commit | 98a2dabc08fd89375f3af4158eb55575be58f13c (patch) | |
tree | fd49a855569c92ec67de35a095dd28fe9f9f143d /llvm/lib/Transforms | |
parent | a06c7e6da7f7367103d5522617cceb2525f2b431 (diff) | |
download | bcm5719-llvm-98a2dabc08fd89375f3af4158eb55575be58f13c.tar.gz bcm5719-llvm-98a2dabc08fd89375f3af4158eb55575be58f13c.zip |
[SimplifyCFG] Prune code from a provably unreachable switch default
As Sanjoy pointed out over in http://reviews.llvm.org/D11819, a switch on an icmp should always be able to become a branch instruction. This patch generalizes that notion slightly to prove that the default case of a switch is unreachable if the cases completely cover all possible bit patterns in the condition. Once that's done, the switch to branch conversion kicks in just fine.
Note: Duplicate case values are disallowed by the LangRef and verifier.
Differential Revision: http://reviews.llvm.org/D11995
llvm-svn: 246125
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index db260b66db6..c6312a3a4e8 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3248,6 +3248,23 @@ static bool EliminateDeadSwitchCases(SwitchInst *SI, AssumptionCache *AC, } } + // If we can prove that the cases must cover all possible values, the + // default destination becomes dead and we can remove it. + bool HasDefault = + !isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg()); + if (HasDefault && Bits < 64 /* avoid overflow */ && + SI->getNumCases() == (1ULL << Bits)) { + DEBUG(dbgs() << "SimplifyCFG: switch default is dead.\n"); + BasicBlock *NewDefault = SplitBlockPredecessors(SI->getDefaultDest(), + SI->getParent(), ""); + SI->setDefaultDest(NewDefault); + SplitBlock(NewDefault, NewDefault->begin()); + auto *OldTI = NewDefault->getTerminator(); + new UnreachableInst(SI->getContext(), OldTI); + EraseTerminatorInstAndDCECond(OldTI); + return true; + } + SmallVector<uint64_t, 8> Weights; bool HasWeight = HasBranchWeights(SI); if (HasWeight) { |