[llvm] [IndVarSimplify] Allow predicateLoopExit on some loops with local writes (PR #155901)
Florian Mayer via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 29 14:30:06 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 &&
----------------
fmayer wrote:
> The general idea here is useful also for libcxx hardening, rust bounds checks, etc.
AFAICT, libcxx hardening just calls `llvm.trap()` in the failure path for non-debug mode, so this patch should work as is for that.
https://github.com/llvm/llvm-project/pull/155901
More information about the llvm-commits
mailing list