Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions llvm/lib/Analysis/ScalarEvolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15445,6 +15445,12 @@ void ScalarEvolution::LoopGuards::collectFromPHI(
const BasicBlock *InBlock = Phi.getIncomingBlock(IncomingIdx);
if (!VisitedBlocks.insert(InBlock).second)
return {nullptr, scCouldNotCompute};

// Avoid analyzing unreachable blocks so that we don't get trapped
// traversing cycles with ill-formed dominance or infinite cycles
if (!SE.DT.isReachableFromEntry(InBlock))
return {nullptr, scCouldNotCompute};

auto [G, Inserted] = IncomingGuards.try_emplace(InBlock, LoopGuards(SE));
if (Inserted)
collectFromBlock(SE, G->second, Phi.getParent(), InBlock, VisitedBlocks,
Expand Down Expand Up @@ -15499,6 +15505,9 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
const BasicBlock *Block, const BasicBlock *Pred,
SmallPtrSetImpl<const BasicBlock *> &VisitedBlocks, unsigned Depth) {

assert(SE.DT.isReachableFromEntry(Block) && SE.DT.isReachableFromEntry(Pred));

SmallVector<const SCEV *> ExprsToRewrite;
auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
const SCEV *RHS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,29 @@ body:
exit:
ret void
}

define void @hang_due_to_unreachable_phi_inblock() personality ptr null {
bb:
br label %bb6

self-loop: ; preds = %self-loop
%dead = invoke ptr null()
to label %self-loop unwind label %bb4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to replace this invoke + landingpad with simple branches (which I think should work?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that, and it no longer hung on old opt. I might have gone too simple (I used a poison condition), but I suspect we might special case that idiom somewhere. I'll give it one more go before landing to be sure.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, trying multiple variants, up to an including volatile stores, doesn't seem to trip the hang any more. Not sure why we need the invoke, but we appear to.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I figured out the difference.

for (; Pair.first;
       Pair = SE.getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
    VisitedBlocks.insert(Pair.second);
    const BranchInst *LoopEntryPredicate =
        dyn_cast<BranchInst>(Pair.first->getTerminator());
    if (!LoopEntryPredicate || LoopEntryPredicate->isUnconditional())
      continue;

    Terms.emplace_back(LoopEntryPredicate->getCondition(),
                       LoopEntryPredicate->getSuccessor(0) == Pair.second);
    NumCollectedConditions++;

    // If we are recursively collecting guards stop after 2
    // conditions to limit compile-time impact for now.
    if (Depth > 0 && NumCollectedConditions == 2)
      break;
  }

This the loop which is actually infintte. The Depth on this example is 1. As a result, if the cycle we're looping on contains a conditional branch, we hit the NumCollectedConditions guard. Per the comment, it wasn't meant to be functional, but that explains why we hit this so rarely.


bb4: ; preds = %self-loop
%i5 = landingpad { ptr, i32 }
cleanup
br label %bb6

bb6: ; preds = %bb4, %bb
%i7 = phi ptr [ null, %bb4 ], [ null, %bb ]
br label %bb8

bb8: ; preds = %bb8, %bb6
%i9 = phi ptr [ null, %bb8 ], [ null, %bb6 ]
%i11 = icmp eq ptr %i9, null
br i1 %i11, label %bb12, label %bb8

bb12: ; preds = %bb8, %bb6
ret void
}
Loading