diff --git a/llvm/include/llvm/Transforms/Scalar/JumpThreading.h b/llvm/include/llvm/Transforms/Scalar/JumpThreading.h index 7d11fc0ad6938..84292c716a0a9 100644 --- a/llvm/include/llvm/Transforms/Scalar/JumpThreading.h +++ b/llvm/include/llvm/Transforms/Scalar/JumpThreading.h @@ -94,6 +94,10 @@ class JumpThreadingPass : public PassInfoMixin { SmallPtrSet LoopHeaders; #endif + // JumpThreading must not processes blocks unreachable from entry. It's a + // waste of compute time and can potentially lead to hangs. + SmallPtrSet Unreachable; + unsigned BBDupThreshold; unsigned DefaultBBDupThreshold; diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 7b221a814aabd..9cae65bbdcfbc 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -307,12 +307,11 @@ bool JumpThreadingPass::runImpl(Function &F_, FunctionAnalysisManager *FAM_, else BBDupThreshold = DefaultBBDupThreshold; - // JumpThreading must not processes blocks unreachable from entry. It's a - // waste of compute time and can potentially lead to hangs. - SmallPtrSet Unreachable; assert(DTU && "DTU isn't passed into JumpThreading before using it."); assert(DTU->hasDomTree() && "JumpThreading relies on DomTree to proceed."); DominatorTree &DT = DTU->getDomTree(); + + Unreachable.clear(); for (auto &BB : *F) if (!DT.isReachableFromEntry(&BB)) Unreachable.insert(&BB); @@ -1895,6 +1894,11 @@ bool JumpThreadingPass::maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB) { SinglePred == BB || hasAddressTakenAndUsed(BB)) return false; + // MergeBasicBlockIntoOnlyPred may delete SinglePred, we need to avoid + // deleting a BB pointer from Unreachable. + if (Unreachable.count(SinglePred)) + return false; + // If SinglePred was a loop header, BB becomes one. if (LoopHeaders.erase(SinglePred)) LoopHeaders.insert(BB); diff --git a/llvm/test/Transforms/JumpThreading/pr62908.ll b/llvm/test/Transforms/JumpThreading/pr62908.ll index 4c389ee040b90..cfb647c509f8e 100644 --- a/llvm/test/Transforms/JumpThreading/pr62908.ll +++ b/llvm/test/Transforms/JumpThreading/pr62908.ll @@ -5,7 +5,18 @@ define i32 @test() { ; CHECK-LABEL: define i32 @test() { -; CHECK-NEXT: end: +; CHECK-NEXT: join.thread: +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: unreachable: +; CHECK-NEXT: [[SH_PROM:%.*]] = zext i32 -1 to i64 +; CHECK-NEXT: [[SHL:%.*]] = shl nsw i64 -1, [[SH_PROM]] +; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[SHL]] to i32 +; CHECK-NEXT: br label [[JOIN:%.*]] +; CHECK: join: +; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[CONV]], [[UNREACHABLE:%.*]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[PHI]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[END]], label [[END]] +; CHECK: end: ; CHECK-NEXT: ret i32 0 ; entry: