[llvm] [DA] handle memory accesses with different offsets and strides (PR #123436)
Ryotaro Kasuga via llvm-commits
llvm-commits at lists.llvm.org
Tue May 13 01:48:56 PDT 2025
================
@@ -3617,30 +3633,80 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst) {
break; // The underlying objects alias; test accesses for dependence.
}
- // establish loop nesting levels
- establishNestingLevels(Src, Dst);
- LLVM_DEBUG(dbgs() << " common nesting levels = " << CommonLevels << "\n");
- LLVM_DEBUG(dbgs() << " maximum nesting levels = " << MaxLevels << "\n");
-
- FullDependence Result(Src, Dst, PossiblyLoopIndependent, CommonLevels);
- ++TotalArrayPairs;
+ if (DstLoc.Size != SrcLoc.Size) {
+ // The dependence test gets confused if the size of the memory accesses
+ // differ.
+ LLVM_DEBUG(dbgs() << "can't analyze must alias with different sizes\n");
+ return std::make_unique<Dependence>(Src, Dst,
+ SCEVUnionPredicate(Assume, *SE));
+ }
- unsigned Pairs = 1;
- SmallVector<Subscript, 2> Pair(Pairs);
+ Value *SrcPtr = getLoadStorePointerOperand(Src);
+ Value *DstPtr = getLoadStorePointerOperand(Dst);
const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
const SCEV *DstSCEV = SE->getSCEV(DstPtr);
LLVM_DEBUG(dbgs() << " SrcSCEV = " << *SrcSCEV << "\n");
LLVM_DEBUG(dbgs() << " DstSCEV = " << *DstSCEV << "\n");
- if (SE->getPointerBase(SrcSCEV) != SE->getPointerBase(DstSCEV)) {
+ const SCEV *SrcBase = SE->getPointerBase(SrcSCEV);
+ const SCEV *DstBase = SE->getPointerBase(DstSCEV);
+ if (SrcBase != DstBase) {
// If two pointers have different bases, trying to analyze indexes won't
// work; we can't compare them to each other. This can happen, for example,
// if one is produced by an LCSSA PHI node.
//
// We check this upfront so we don't crash in cases where getMinusSCEV()
// returns a SCEVCouldNotCompute.
LLVM_DEBUG(dbgs() << "can't analyze SCEV with different pointer base\n");
- return std::make_unique<Dependence>(Src, Dst);
+ return std::make_unique<Dependence>(Src, Dst,
+ SCEVUnionPredicate(Assume, *SE));
+ }
+
+ uint64_t EltSize = SrcLoc.Size.toRaw();
+ assert(EltSize == DstLoc.Size.toRaw() && "Array element size differ");
+
+ const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase);
+ const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase);
+
+ if (Src != Dst) {
+ // Check that memory access offsets are multiples of element sizes.
+ if (!SE->isKnownMultipleOf(SrcEv, EltSize, Assume) ||
+ !SE->isKnownMultipleOf(DstEv, EltSize, Assume)) {
+ LLVM_DEBUG(dbgs() << "can't analyze SCEV with different offsets\n");
+ return std::make_unique<Dependence>(Src, Dst,
+ SCEVUnionPredicate(Assume, *SE));
+ }
+ }
+
+ if (!Assume.empty()) {
+ if (!UnderRuntimeAssumptions)
+ return std::make_unique<Dependence>(Src, Dst,
+ SCEVUnionPredicate(Assume, *SE));
+ if (Assumptions.empty()) {
+ Assumptions.append(Assume.begin(), Assume.end());
----------------
kasuga-fj wrote:
I still think this branch is unnecessary.
https://github.com/llvm/llvm-project/pull/123436
More information about the llvm-commits
mailing list