[llvm] [LAA] Catch load/store to invariant address in dependency checker. (PR #187023)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 25 14:52:15 PDT 2026


================
@@ -2140,9 +2144,15 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
   LLVM_DEBUG(dbgs() << "LAA:  Src induction step: " << StrideAPtrInt
                     << " Sink induction step: " << StrideBPtrInt << "\n");
   // At least Src or Sink are loop invariant and the other is strided or
-  // invariant. We can generate a runtime check to disambiguate the accesses.
-  if (!StrideAPtrInt || !StrideBPtrInt)
+  // invariant.
+  if (!StrideAPtrInt || !StrideBPtrInt) {
+    // If both are loop-invariant and access the same location, we cannot
+    // vectorize.
+    if (!StrideAPtrInt && !StrideBPtrInt && Dist->isZero())
+      return MemoryDepChecker::Dependence::InvariantUnsafe;
+    // Otherwise, we can generate a runtime check to disambiguate the accesses.
----------------
artagnon wrote:

Yes, I think it would be better to have a single Unsafe kind, as InvariantUnsafe doesn't seem to be an inherently different kind of Unsafe -- I think trading off some loss in LAA debug output is worth the maintainability and clarity we'd get?

> The problem is that we merge accesses with the same SCEV into the same group, so we never check against them. This should be taken care of by updating the check in the dependency checker,

Hm, I'm not sure if this the complete version of what you wanted to say? Can you kindly explain where we merge accesses with identical SCEVs? I thought MemDepChecker::MemAccessInfo keeps Value pointers? I don't think the following code merges accesses in any way?

```cpp
void MemoryDepChecker::addAccess(StoreInst *SI) {
  visitPointers(SI->getPointerOperand(), *InnermostLoop,
                [this, SI](Value *Ptr) {
                  Accesses[MemAccessInfo(Ptr, true)].push_back(AccessIdx);
                  InstMap.push_back(SI);
                  ++AccessIdx;
                });
}

void MemoryDepChecker::addAccess(LoadInst *LI) {
  visitPointers(LI->getPointerOperand(), *InnermostLoop,
                [this, LI](Value *Ptr) {
                  Accesses[MemAccessInfo(Ptr, false)].push_back(AccessIdx);
                  InstMap.push_back(LI);
                  ++AccessIdx;
                });
}
```

https://github.com/llvm/llvm-project/pull/187023


More information about the llvm-commits mailing list