[llvm] [LoopVectorize] - Add tighter runtime memory check threshold for inner loops. (PR #219489)
Pawan Nirpal via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 28 07:47:02 PDT 2026
https://github.com/pawan-nirpal-031 updated https://github.com/llvm/llvm-project/pull/219489
>From 745f52f4e0b0743e9d9a5a78c3b663618b5b6f16 Mon Sep 17 00:00:00 2001
From: Pawan Nirpal <pnirpal at qti.qualcomm.com>
Date: Fri, 28 Aug 2026 07:43:17 -0700
Subject: [PATCH] [LoopVectorize] Add tighter runtime memory check threshold
for inner loops
---
.../Transforms/Vectorize/LoopVectorize.cpp | 26 ++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 1f153afd6bedd..c05098da3247f 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -203,6 +203,13 @@ static cl::opt<unsigned> VectorizeMemoryCheckThreshold(
"vectorize-memory-check-threshold", cl::init(128), cl::Hidden,
cl::desc("The maximum allowed number of runtime memory checks"));
+// Tighter threshold for inner loops where runtime memory checks execute on
+// every outer-loop iteration, unlike top-level loops where they run only once.
+static cl::opt<unsigned> VectorizeMemoryCheckInnerLoopThreshold(
+ "vectorize-memory-check-inner-loop-threshold", cl::init(12), cl::Hidden,
+ cl::desc("The maximum allowed number of runtime memory checks for inner "
+ "loops where checks execute per outer-loop iteration"));
+
static cl::opt<bool> ForcePartialAliasingVectorization(
"force-partial-aliasing-vectorization", cl::init(false), cl::Hidden,
cl::desc("Replace pointer diff checks with alias masks."));
@@ -1588,8 +1595,20 @@ class GeneratedRTChecks {
// runtime checks needs to be generated.
// TODO: Skip cutoff if the loop is guaranteed to execute, e.g. due to
// profile info.
- CostTooHigh =
- LAI.getNumRuntimePointerChecks() > VectorizeMemoryCheckThreshold;
+ unsigned NumChecks = LAI.getNumRuntimePointerChecks();
+ unsigned EffectiveThreshold = VectorizeMemoryCheckThreshold;
+
+ // For inner loops, apply a tighter threshold. When vectorizing an inner
+ // loop, runtime memory overlap checks execute on every iteration of the
+ // enclosing outer loop. If the vectorizer's outer-loop interleaving creates
+ // a large number of pointer groups (from multiple memory ptrs derived from
+ // the same base ptr), the resulting O(N^2) pairwise checks become a
+ // significant overhead that the existing cost model does not account for.
+ if (L->getParentLoop() &&
+ NumChecks > VectorizeMemoryCheckInnerLoopThreshold)
+ EffectiveThreshold = VectorizeMemoryCheckInnerLoopThreshold;
+
+ CostTooHigh = NumChecks > EffectiveThreshold;
if (CostTooHigh) {
// Mark runtime checks as never succeeding when they exceed the threshold.
MemRuntimeCheckCond = ConstantInt::getTrue(L->getHeader()->getContext());
@@ -1600,7 +1619,8 @@ class GeneratedRTChecks {
L->getHeader())
<< "loop not vectorized: too many memory checks needed";
});
- LLVM_DEBUG(dbgs() << "LV: Too many memory checks needed.\n");
+ LLVM_DEBUG(dbgs() << "LV: Too many memory checks needed (" << NumChecks
+ << " > " << EffectiveThreshold << ").\n");
return;
}
More information about the llvm-commits
mailing list