[llvm] [ValueTracking] Support multiple predecessors in willNotFreeBetween (PR #223580)
Vy Nguyen via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 09:57:38 PDT 2026
================
@@ -737,50 +737,66 @@ bool llvm::isValidAssumeForContext(const Instruction *Inv,
return false;
}
-bool llvm::willNotFreeBetween(const Instruction *Assume,
- const Instruction *CtxI) {
- // Helper to check if there are any calls in the range that may free memory.
- unsigned NumChecked = 0;
- auto hasNoFreeInRange = [&NumChecked](auto Range) {
- for (const Instruction &I : Range) {
- if (NumChecked++ > MaxInstrsToCheckForFree)
- return false;
-
- if (auto *CB = dyn_cast<CallBase>(&I)) {
- if (!CB->hasFnAttr(Attribute::NoFree))
- return false;
- } else if (I.maySynchronize())
+static bool hasNoFreeInRange(BasicBlock::const_iterator Begin,
+ BasicBlock::const_iterator End,
+ unsigned &NumChecked) {
+ for (const Instruction &I : make_range(Begin, End)) {
+ if (NumChecked++ > MaxInstrsToCheckForFree)
+ return false;
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ if (!CB->hasFnAttr(Attribute::NoFree))
return false;
+ } else if (I.maySynchronize()) {
+ return false;
}
- return true;
- };
+ }
+ return true;
+}
+bool llvm::willNotFreeBetween(const Instruction *Assume,
+ const Instruction *CtxI,
+ const DominatorTree *DT) {
const BasicBlock *CtxBB = CtxI->getParent();
const BasicBlock *AssumeBB = Assume->getParent();
+ unsigned NumChecked = 0;
BasicBlock::const_iterator CtxIter = CtxI->getIterator();
if (CtxBB == AssumeBB) {
- // Same block case: check that Assume comes before CtxI.
if (Assume != CtxI && !Assume->comesBefore(CtxI))
return false;
- return hasNoFreeInRange(make_range(Assume->getIterator(), CtxIter));
+ return hasNoFreeInRange(Assume->getIterator(), CtxIter, NumChecked);
}
-
- // Handle chain of single-predecessor blocks.
- const BasicBlock *CurBB = CtxBB;
- while (true) {
- if (CurBB == AssumeBB)
- return hasNoFreeInRange(
- make_range(Assume->getIterator(), AssumeBB->end()));
-
- const BasicBlock *PredBB = CurBB->getSinglePredecessor();
- if (!PredBB)
+ if (DT && !DT->dominates(Assume, CtxI))
+ return false;
+ if (!hasNoFreeInRange(CtxBB->begin(), CtxIter, NumChecked))
+ return false;
+ if (pred_empty(CtxBB))
+ return false;
+ // Note: CtxBB is NOT pre-inserted into Visited to ensure that loop
+ // backedges returning to CtxBB are enqueued and checked correctly.
+ SmallVector<const BasicBlock *, 16> Worklist(predecessors(CtxBB));
+ SmallPtrSet<const BasicBlock *, 16> Visited;
+ while (!Worklist.empty()) {
+ const BasicBlock *CurBB = Worklist.pop_back_val();
+ if (!Visited.insert(CurBB).second)
+ continue;
+ if (CurBB == AssumeBB) {
----------------
oontvoo wrote:
done
https://github.com/llvm/llvm-project/pull/223580
More information about the llvm-commits
mailing list