Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -207,7 +207,8 @@ // In other words, if we know P(cond == true) is unlikely, we know // that P(t == true) is also unlikely. // -static void updatePredecessorProfileMetadata(PHINode *PN, BasicBlock *BB) { +static void updatePredecessorProfileMetadata(PHINode *PN, BasicBlock *BB, + DominatorTree &DT) { BranchInst *CondBr = dyn_cast(BB->getTerminator()); if (!CondBr) return; @@ -220,20 +221,23 @@ // Returns the outgoing edge of the dominating predecessor block // that leads to the PhiNode's incoming block: auto GetPredOutEdge = - [](BasicBlock *IncomingBB, - BasicBlock *PhiBB) -> std::pair { + [&](BasicBlock *IncomingBB, + BasicBlock *PhiBB) -> std::pair { auto *PredBB = IncomingBB; auto *SuccBB = PhiBB; while (true) { + // Stop searching when PredBB is unreachable. It is waste of time + // to propagate prof meta data to unreachable code and may also + // cause infinite loop. + if (!DT.isReachableFromEntry(PredBB)) + return {nullptr, nullptr}; + BranchInst *PredBr = dyn_cast(PredBB->getTerminator()); if (PredBr && PredBr->isConditional()) return {PredBB, SuccBB}; 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; } @@ -1207,7 +1211,7 @@ // Before threading, try to propagate profile data backwards: if (PHINode *PN = dyn_cast(CondInst)) if (PN->getParent() == BB && isa(BB->getTerminator())) - updatePredecessorProfileMetadata(PN, BB); + updatePredecessorProfileMetadata(PN, BB, DTU->getDomTree()); // Handle a variety of cases where we are branching on something derived from // a PHI node in the current block. If we can prove that any predecessors Index: llvm/test/Transforms/JumpThreading/unreachable-single-bb-loop.ll =================================================================== --- llvm/test/Transforms/JumpThreading/unreachable-single-bb-loop.ll +++ llvm/test/Transforms/JumpThreading/unreachable-single-bb-loop.ll @@ -1,11 +1,11 @@ ; 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 +; Check the unreachable 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() +define void @unreachable_single_bb_loop() { +; CHECK-LABEL: @unreachable_single_bb_loop() bb: %tmp = call i32 @a() %tmp1 = icmp eq i32 %tmp, 1 @@ -30,6 +30,34 @@ ret void } +define void @unreachable_multi_bbs_loop() { +; CHECK-LABEL: @unreachable_multi_bbs_loop() +bb: + %tmp = call i32 @a() + %tmp1 = icmp eq i32 %tmp, 1 + br i1 %tmp1, label %bb5, label %bb8 + +; unreachable two bbs loop. +bb3: ; preds = %bb2 + br label %bb2 + +bb2: ; preds = %bb3 + %tmp4 = icmp ne i32 %tmp, 1 + switch i1 %tmp4, label %bb3 [ + 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}