Index: llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp =================================================================== --- llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -82,6 +82,7 @@ AU.addRequired(); AU.addRequired(); AU.addPreserved(); + AU.addPreserved(); } }; @@ -306,7 +307,7 @@ /// that cannot fire no matter what the incoming edge can safely be removed. If /// a case fires on every incoming edge then the entire switch can be removed /// and replaced with a branch to the case destination. -static bool processSwitch(SwitchInst *SI, LazyValueInfo *LVI) { +static bool processSwitch(SwitchInst *SI, LazyValueInfo *LVI, DominatorTree *DT) { Value *Cond = SI->getCondition(); BasicBlock *BB = SI->getParent(); @@ -321,6 +322,10 @@ // Analyse each switch case in turn. bool Changed = false; + DenseMap SuccessorsCount; + for (auto *Succ : successors(BB)) + SuccessorsCount[Succ]++; + for (auto CI = SI->case_begin(), CE = SI->case_end(); CI != CE;) { ConstantInt *Case = CI->getCaseValue(); @@ -355,7 +360,8 @@ if (State == LazyValueInfo::False) { // This case never fires - remove it. - CI->getCaseSuccessor()->removePredecessor(BB); + BasicBlock *Succ = CI->getCaseSuccessor(); + Succ->removePredecessor(BB); CI = SI->removeCase(CI); CE = SI->case_end(); @@ -365,6 +371,8 @@ ++NumDeadCases; Changed = true; + if (--SuccessorsCount[Succ] == 0) + DT->deleteEdge(BB, Succ); continue; } if (State == LazyValueInfo::True) { @@ -381,10 +389,14 @@ ++CI; } - if (Changed) + if (Changed) { // If the switch has been simplified to the point where it can be replaced // by a branch then do so now. - ConstantFoldTerminator(BB); + DeferredDominance DDT(*DT); + ConstantFoldTerminator(BB, /*DeleteDeadConditions = */ false, + /*TLI = */ nullptr, &DDT); + DDT.flush(); + } return Changed; } @@ -722,7 +734,7 @@ Instruction *Term = BB->getTerminator(); switch (Term->getOpcode()) { case Instruction::Switch: - BBChanged |= processSwitch(cast(Term), LVI); + BBChanged |= processSwitch(cast(Term), LVI, DT); break; case Instruction::Ret: { auto *RI = cast(Term); @@ -767,5 +779,6 @@ return PreservedAnalyses::all(); PreservedAnalyses PA; PA.preserve(); + PA.preserve(); return PA; } Index: llvm/test/Other/opt-O2-pipeline.ll =================================================================== --- llvm/test/Other/opt-O2-pipeline.ll +++ llvm/test/Other/opt-O2-pipeline.ll @@ -145,7 +145,6 @@ ; CHECK-NEXT: Lazy Value Information Analysis ; CHECK-NEXT: Jump Threading ; CHECK-NEXT: Value Propagation -; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Basic Alias Analysis (stateless AA impl) ; CHECK-NEXT: Function Alias Analysis Results ; CHECK-NEXT: Memory Dependence Analysis Index: llvm/test/Other/opt-O3-pipeline.ll =================================================================== --- llvm/test/Other/opt-O3-pipeline.ll +++ llvm/test/Other/opt-O3-pipeline.ll @@ -149,7 +149,6 @@ ; CHECK-NEXT: Lazy Value Information Analysis ; CHECK-NEXT: Jump Threading ; CHECK-NEXT: Value Propagation -; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Basic Alias Analysis (stateless AA impl) ; CHECK-NEXT: Function Alias Analysis Results ; CHECK-NEXT: Memory Dependence Analysis Index: llvm/test/Other/opt-Os-pipeline.ll =================================================================== --- llvm/test/Other/opt-Os-pipeline.ll +++ llvm/test/Other/opt-Os-pipeline.ll @@ -131,7 +131,6 @@ ; CHECK-NEXT: Lazy Value Information Analysis ; CHECK-NEXT: Jump Threading ; CHECK-NEXT: Value Propagation -; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Basic Alias Analysis (stateless AA impl) ; CHECK-NEXT: Function Alias Analysis Results ; CHECK-NEXT: Memory Dependence Analysis