[llvm] [DA] do not handle array accesses of different offsets (PR #123436)

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 27 06:50:33 PST 2025


================
@@ -3569,6 +3569,123 @@ bool DependenceInfo::invalidate(Function &F, const PreservedAnalyses &PA,
          Inv.invalidate<LoopAnalysis>(F, PA);
 }
 
+// Check that memory access offsets in V are multiples of array element size
+// EltSize. Param records the first parametric expression. If the scalar
+// evolution V contains two or more parameters, we check that the subsequent
+// parametric expressions are multiples of the first parametric expression
+// Param.
+static bool checkOffsets(ScalarEvolution *SE, const SCEV *V, const SCEV *&Param,
+                         uint64_t EltSize) {
+  if (auto *AddRec = dyn_cast<SCEVAddRecExpr>(V)) {
+    if (!checkOffsets(SE, AddRec->getStart(), Param, EltSize))
+      return false;
+    return checkOffsets(SE, AddRec->getStepRecurrence(*SE), Param, EltSize);
+  }
+  if (auto *Cst = dyn_cast<SCEVConstant>(V)) {
+    APInt C = Cst->getAPInt();
+
+    // For example, alias_with_different_offsets in
+    // test/Analysis/DependenceAnalysis/DifferentOffsets.ll accesses "%A + 2":
+    //   %arrayidx = getelementptr inbounds i8, ptr %A, i64 2
+    //   store i32 42, ptr %arrayidx, align 1
+    // which is writing an i32, i.e., EltSize = 4 bytes, with an offset C = 2.
+    // checkOffsets returns false, as the offset C=2 is not a multiple of 4.
+    return C.srem(EltSize) == 0;
+  }
+
+  // Use a lambda helper function to check V for parametric expressions.
+  // Param records the first parametric expression. If the scalar evolution V
+  // contains two or more parameters, we check that the subsequent parametric
+  // expressions are multiples of the first parametric expression Param.
+  auto checkParamsMultipleOfSize = [&](const SCEV *V,
+                                       const SCEV *&Param) -> bool {
+    if (EltSize == 1)
+      return true;
+    if (!Param) {
+      Param = V;
+      return true;
----------------
Meinersbur wrote:

I don't understand why if there is only a single SCEVUnknown involved, why is it automatically a multiple of `EltSize`? 

```llvm
  %ptr = getelementptr i8, ptr %base, i32 %offset
  store i64 42, ptr %ptr 
```
So the array is elements of 8 bytes, but the gep is incrementing by single bytes. If the SCEVUnknown %offset is not a multiple of 8, the check should fail?

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


More information about the llvm-commits mailing list