Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -231,6 +231,9 @@ auto *SinglePredBB = PredBB->getSinglePredecessor(); if (!SinglePredBB) return {nullptr, nullptr}; + // For unreachable one block loop, stop searching. + if (PredBB == SinglePredBB) + return {PredBB, SuccBB}; SuccBB = PredBB; PredBB = SinglePredBB; } @@ -253,7 +256,9 @@ return; BasicBlock *PredBB = PredOutEdge.first; - BranchInst *PredBr = cast(PredBB->getTerminator()); + BranchInst *PredBr = dyn_cast(PredBB->getTerminator()); + if (!PredBr) + return; uint64_t PredTrueWeight, PredFalseWeight; // FIXME: We currently only set the profile data when it is missing. Index: llvm/test/Transforms/JumpThreading/unreachable-single-bb-loop.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/JumpThreading/unreachable-single-bb-loop.ll @@ -0,0 +1,35 @@ +; RUN: opt -jump-threading -S < %s | FileCheck %s +; RUN: opt -passes=jump-threading -S < %s | FileCheck %s +; Check the unreachable single bb loop won't cause infinite loop +; in jump-threading when it tries to update the predecessors' +; profile metadata from a phi node. + +define void @test() { +; CHECK-LABEL: @test() +bb: + %tmp = call i32 @a() + %tmp1 = icmp eq i32 %tmp, 1 + br i1 %tmp1, label %bb5, label %bb8 + +; unreachable single bb loop. +bb2: ; preds = %bb2 + %tmp4 = icmp ne i32 %tmp, 1 + switch i1 %tmp4, label %bb2 [ + i1 0, label %bb5 + i1 1, label %bb8 + ] + +bb5: ; preds = %bb2, %bb + %tmp6 = phi i1 [ %tmp1, %bb ], [ false, %bb2 ] + br i1 %tmp6, label %bb8, label %bb7, !prof !0 + +bb7: ; preds = %bb5 + br label %bb8 + +bb8: ; preds = %bb8, %bb7, %bb5, %bb2 + ret void +} + +declare i32 @a() + +!0 = !{!"branch_weights", i32 2146410443, i32 1073205}