[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