getPredecessorWithUniqueSuccessorForBB finds a BB which has a single predecessor and dominates target BB.
At this moment, the function is checking below two things.
- Target BB has single predecessor. If so, it returns predecessor and target BB.
- Target BB is part of loop. If so, it returns the loop's pre-header and header.
We could check one more thing as below.
If Target BB has IDom and the IDom has single predecessor, it also meet the condition of getPredecessorWithUniqueSuccessorForBB and we can return the IDom's predecessor and the IDom.
I was going to suggest that we can generalize this by walking up the idom chain (this also removes the need to special case loops):
Unfortunately, this has a bad compile-time impact: https://llvm-compile-time-tracker.com/compare.php?from=41849a91956755e15591240816d1d0c5ec402895&to=41241255419965bbfbc6d361058ea02449be9c50&stat=instructions ClamAV is up nearly 3%.
So I also tested your original patch: https://llvm-compile-time-tracker.com/compare.php?from=41849a91956755e15591240816d1d0c5ec402895&to=a012ed61e795b191cd7d114bfe972ce05c9f3d6b&stat=instructions This is better, but still bad, especially with little codegen impact.
isImpliedCond() is notoriously expensive, so compile-time is sensitive to the amount of guards we look at. I think if we want to do any extensions here, we need to also aggressively limit the number of edges for which we take conditions into account.