[llvm] [IndVarSimplify] Allow predicateLoopExit on some loops with local writes (PR #155901)
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 29 10:42:23 PDT 2025
================
@@ -1840,6 +1865,34 @@ bool IndVarSimplify::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
const SCEV *ExitCount = SE->getExitCount(L, ExitingBB);
auto *BI = cast<BranchInst>(ExitingBB->getTerminator());
+ if (HasLocalSideEffects) {
+ BasicBlock *Unreachable = nullptr;
+ BasicBlock *InLoop = nullptr;
+ for (BasicBlock *Succ : BI->successors()) {
+ if (isa<UnreachableInst>(Succ->getTerminator()))
+ Unreachable = Succ;
+ else if (L->contains(Succ))
+ InLoop = Succ;
+ }
+ // Exit BB which have one branch back into the loop and another one to
+ // a trap can still be optimized, because local side effects cannot
+ // be observed in the exit case (the trap). We could be smarter about
+ // this, but for now lets pattern match common cases that directly trap.
+ if (Unreachable == nullptr || InLoop == nullptr)
+ return Changed;
+ if (llvm::any_of(*Unreachable, [](Instruction &I) {
+ if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
+ if (II->getIntrinsicID() != Intrinsic::trap &&
----------------
preames wrote:
@nikic - I think you slightly misread this. I don't see anything in the logic which is assuming an alloca, instead the approach seems to be to say that the side effect being removed can't be observed before termination of the program. In particular, I believe this currently allows arbitrary heap memory.
https://github.com/llvm/llvm-project/pull/155901
More information about the llvm-commits
mailing list