diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index a75f29000ca18..75c96503d556d 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -7493,7 +7493,7 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI, SmallPtrSet Phis; SmallPtrSet Seen; DenseMap> PhiPredIVs; - DenseMap> BBToSuccessorIndexes; + DenseMap> BBToSuccessorIndexes; SmallVector Cases; Cases.reserve(SI->getNumSuccessors()); @@ -7505,12 +7505,6 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI, if (BB->size() != 1) continue; - // FIXME: This case needs some extra care because the terminators other than - // SI need to be updated. For now, consider only backedges to the SI. - if (BB->hasNPredecessorsOrMore(4) || - BB->getUniquePredecessor() != SI->getParent()) - continue; - // FIXME: Relax that the terminator is a BranchInst by checking for equality // on other kinds of terminators. We decide to only support unconditional // branches for now for compile time reasons. @@ -7518,14 +7512,24 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI, if (!BI || BI->isConditional()) continue; - if (Seen.insert(BB).second) { - // Keep track of which PHIs we need as keys in PhiPredIVs below. - for (BasicBlock *Succ : BI->successors()) - Phis.insert_range(llvm::make_pointer_range(Succ->phis())); - // Add the successor only if not previously visited. - Cases.emplace_back(SwitchSuccWrapper{BB, &PhiPredIVs}); + if (!Seen.insert(BB).second) { + auto It = BBToSuccessorIndexes.find(BB); + if (It != BBToSuccessorIndexes.end()) + It->second.emplace_back(I); + continue; } + // FIXME: This case needs some extra care because the terminators other than + // SI need to be updated. For now, consider only backedges to the SI. + if (BB->getUniquePredecessor() != SI->getParent()) + continue; + + // Keep track of which PHIs we need as keys in PhiPredIVs below. + for (BasicBlock *Succ : BI->successors()) + Phis.insert_range(llvm::make_pointer_range(Succ->phis())); + + // Add the successor only if not previously visited. + Cases.emplace_back(SwitchSuccWrapper{BB, &PhiPredIVs}); BBToSuccessorIndexes[BB].emplace_back(I); } diff --git a/llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll b/llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll index 32581bbf8f141..d2d917de11897 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll @@ -199,3 +199,44 @@ exit: %ret = phi i64 [ 0, %default ], [ 0, %bb1 ], [ 1, %entry ], [ 1, %bb2 ] ret i64 %ret } + +define i32 @switch_dup_unbounded_predecessors(i32 %val) { +; SIMPLIFY-CFG-LABEL: define i32 @switch_dup_unbounded_predecessors( +; SIMPLIFY-CFG-SAME: i32 [[VAL:%.*]]) { +; SIMPLIFY-CFG-NEXT: [[ENTRY:.*]]: +; SIMPLIFY-CFG-NEXT: switch i32 [[VAL]], label %[[EXIT:.*]] [ +; SIMPLIFY-CFG-NEXT: i32 99, label %[[BB1:.*]] +; SIMPLIFY-CFG-NEXT: i32 115, label %[[BB1]] +; SIMPLIFY-CFG-NEXT: i32 102, label %[[BB1]] +; SIMPLIFY-CFG-NEXT: i32 70, label %[[BB1]] +; SIMPLIFY-CFG-NEXT: i32 101, label %[[BB1]] +; SIMPLIFY-CFG-NEXT: i32 69, label %[[BB1]] +; SIMPLIFY-CFG-NEXT: i32 103, label %[[BB1]] +; SIMPLIFY-CFG-NEXT: ] +; SIMPLIFY-CFG: [[BB1]]: +; SIMPLIFY-CFG-NEXT: br label %[[EXIT]] +; SIMPLIFY-CFG: [[EXIT]]: +; SIMPLIFY-CFG-NEXT: [[PHI:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ 1, %[[BB1]] ] +; SIMPLIFY-CFG-NEXT: ret i32 [[PHI]] +; +entry: + switch i32 %val, label %exit [ + i32 99, label %bb1 + i32 115, label %bb1 + i32 102, label %bb2 + i32 70, label %bb2 + i32 101, label %bb2 + i32 69, label %bb2 + i32 103, label %bb2 + ] + +bb1: + br label %exit + +bb2: + br label %exit + +exit: + %phi = phi i32 [ 0, %entry ], [ 1, %bb1 ], [ 1, %bb2 ] + ret i32 %phi +} diff --git a/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll b/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll index 4136f33983a2b..8f2ae2d054f1e 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll @@ -149,7 +149,7 @@ unreach2: define void @pr53208_single_reachable_dest(i8 %sw, ptr %p0) { ; CHECK-LABEL: @pr53208_single_reachable_dest( -; CHECK-NEXT: group2: +; CHECK-NEXT: exit: ; CHECK-NEXT: call void @bar(ptr [[P0:%.*]]) ; CHECK-NEXT: ret void ;