Skip to content

Commit 1debdc1

Browse files
committed
[LAA] Introduce helper to get SCEV for pointer stride. (NFC)
1 parent 19c9a1c commit 1debdc1

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,12 +1458,11 @@ static bool isNoWrapAddRec(Value *Ptr, const SCEVAddRecExpr *AR,
14581458
return false;
14591459
}
14601460

1461-
/// Check whether the access through \p Ptr has a constant stride.
1462-
std::optional<int64_t> llvm::getPtrStride(PredicatedScalarEvolution &PSE,
1463-
Type *AccessTy, Value *Ptr,
1464-
const Loop *Lp,
1465-
const DenseMap<Value *, const SCEV *> &StridesMap,
1466-
bool Assume, bool ShouldCheckWrap) {
1461+
static std::optional<const SCEV *>
1462+
getPtrStrideSCEV(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
1463+
const Loop *Lp,
1464+
const DenseMap<Value *, const SCEV *> &StridesMap, bool Assume,
1465+
bool ShouldCheckWrap) {
14671466
Type *Ty = Ptr->getType();
14681467
assert(Ty->isPointerTy() && "Unexpected non-ptr");
14691468

@@ -1520,44 +1519,58 @@ std::optional<int64_t> llvm::getPtrStride(PredicatedScalarEvolution &PSE,
15201519
if (Rem)
15211520
return std::nullopt;
15221521

1522+
const SCEV *StrideSCEV = PSE.getSE()->getConstant(C->getType(), Stride);
15231523
if (!ShouldCheckWrap)
1524-
return Stride;
1524+
return StrideSCEV;
15251525

15261526
// The address calculation must not wrap. Otherwise, a dependence could be
15271527
// inverted.
15281528
if (isNoWrapAddRec(Ptr, AR, PSE, Lp))
1529-
return Stride;
1529+
return StrideSCEV;
15301530

15311531
// An inbounds getelementptr that is a AddRec with a unit stride
15321532
// cannot wrap per definition. If it did, the result would be poison
15331533
// and any memory access dependent on it would be immediate UB
15341534
// when executed.
15351535
if (auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
15361536
GEP && GEP->isInBounds() && (Stride == 1 || Stride == -1))
1537-
return Stride;
1537+
return StrideSCEV;
15381538

15391539
// If the null pointer is undefined, then a access sequence which would
15401540
// otherwise access it can be assumed not to unsigned wrap. Note that this
15411541
// assumes the object in memory is aligned to the natural alignment.
15421542
unsigned AddrSpace = Ty->getPointerAddressSpace();
15431543
if (!NullPointerIsDefined(Lp->getHeader()->getParent(), AddrSpace) &&
15441544
(Stride == 1 || Stride == -1))
1545-
return Stride;
1545+
return StrideSCEV;
15461546

15471547
if (Assume) {
15481548
PSE.setNoOverflow(Ptr, SCEVWrapPredicate::IncrementNUSW);
15491549
LLVM_DEBUG(dbgs() << "LAA: Pointer may wrap:\n"
15501550
<< "LAA: Pointer: " << *Ptr << "\n"
15511551
<< "LAA: SCEV: " << *AR << "\n"
15521552
<< "LAA: Added an overflow assumption\n");
1553-
return Stride;
1553+
return StrideSCEV;
15541554
}
15551555
LLVM_DEBUG(
15561556
dbgs() << "LAA: Bad stride - Pointer may wrap in the address space "
15571557
<< *Ptr << " SCEV: " << *AR << "\n");
15581558
return std::nullopt;
15591559
}
15601560

1561+
/// Check whether the access through \p Ptr has a constant stride.
1562+
std::optional<int64_t>
1563+
llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
1564+
const Loop *Lp,
1565+
const DenseMap<Value *, const SCEV *> &StridesMap,
1566+
bool Assume, bool ShouldCheckWrap) {
1567+
std::optional<const SCEV *> StrideSCEV = getPtrStrideSCEV(
1568+
PSE, AccessTy, Ptr, Lp, StridesMap, Assume, ShouldCheckWrap);
1569+
if (StrideSCEV && isa<SCEVConstant>(*StrideSCEV))
1570+
return cast<SCEVConstant>(*StrideSCEV)->getAPInt().getSExtValue();
1571+
return std::nullopt;
1572+
}
1573+
15611574
std::optional<int> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA,
15621575
Type *ElemTyB, Value *PtrB,
15631576
const DataLayout &DL,

0 commit comments

Comments
 (0)