diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 50b5fdb..88adeb5 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -366,6 +366,7 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI, { // Scope for SwitchInstProfUpdateWrapper. It must not live during // ConstantFoldTerminator() as the underlying SwitchInst can be changed. SwitchInstProfUpdateWrapper SI(*I); + unsigned ReachableCaseCount = 0; for (auto CI = SI->case_begin(), CE = SI->case_end(); CI != CE;) { ConstantInt *Case = CI->getCaseValue(); @@ -402,6 +403,31 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI, // Increment the case iterator since we didn't delete it. ++CI; + ++ReachableCaseCount; + } + + BasicBlock *DefaultDest = SI->getDefaultDest(); + if (ReachableCaseCount > 1 && + !isa<UnreachableInst>(DefaultDest->getFirstNonPHIOrDbg())) { + ConstantRange CR = LVI->getConstantRangeAtUse(I->getOperandUse(0), + /*UndefAllowed*/ false); + // The default dest is unreachable if all cases are covered. + if (!CR.isSizeLargerThan(ReachableCaseCount)) { + BasicBlock *NewUnreachableBB = + BasicBlock::Create(BB->getContext(), "default.unreachable", + BB->getParent(), DefaultDest); + new UnreachableInst(BB->getContext(), NewUnreachableBB); + + DefaultDest->removePredecessor(BB); + SI->setDefaultDest(NewUnreachableBB); + + if (SuccessorsCount[DefaultDest] == 1) + DTU.applyUpdates({{DominatorTree::Delete, BB, DefaultDest}}); + DTU.applyUpdates({{DominatorTree::Insert, BB, NewUnreachableBB}}); + + ++NumDeadCases; + Changed = true; + } } } @@ -1283,6 +1309,12 @@ CorrelatedValuePropagationPass::run(Function &F, FunctionAnalysisManager &AM) { if (!Changed) { PA = PreservedAnalyses::all(); } else { +#if defined(EXPENSIVE_CHECKS) + assert(DT->verify(DominatorTree::VerificationLevel::Full)); +#else + assert(DT->verify(DominatorTree::VerificationLevel::Fast)); +#endif // EXPENSIVE_CHECKS + PA.preserve<DominatorTreeAnalysis>(); PA.preserve<LazyValueAnalysis>(); } |