@@ -1458,12 +1458,11 @@ static bool isNoWrapAddRec(Value *Ptr, const SCEVAddRecExpr *AR,
1458
1458
return false ;
1459
1459
}
1460
1460
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) {
1467
1466
Type *Ty = Ptr->getType ();
1468
1467
assert (Ty->isPointerTy () && " Unexpected non-ptr" );
1469
1468
@@ -1520,44 +1519,58 @@ std::optional<int64_t> llvm::getPtrStride(PredicatedScalarEvolution &PSE,
1520
1519
if (Rem)
1521
1520
return std::nullopt;
1522
1521
1522
+ const SCEV *StrideSCEV = PSE.getSE ()->getConstant (C->getType (), Stride);
1523
1523
if (!ShouldCheckWrap)
1524
- return Stride ;
1524
+ return StrideSCEV ;
1525
1525
1526
1526
// The address calculation must not wrap. Otherwise, a dependence could be
1527
1527
// inverted.
1528
1528
if (isNoWrapAddRec (Ptr, AR, PSE, Lp))
1529
- return Stride ;
1529
+ return StrideSCEV ;
1530
1530
1531
1531
// An inbounds getelementptr that is a AddRec with a unit stride
1532
1532
// cannot wrap per definition. If it did, the result would be poison
1533
1533
// and any memory access dependent on it would be immediate UB
1534
1534
// when executed.
1535
1535
if (auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1536
1536
GEP && GEP->isInBounds () && (Stride == 1 || Stride == -1 ))
1537
- return Stride ;
1537
+ return StrideSCEV ;
1538
1538
1539
1539
// If the null pointer is undefined, then a access sequence which would
1540
1540
// otherwise access it can be assumed not to unsigned wrap. Note that this
1541
1541
// assumes the object in memory is aligned to the natural alignment.
1542
1542
unsigned AddrSpace = Ty->getPointerAddressSpace ();
1543
1543
if (!NullPointerIsDefined (Lp->getHeader ()->getParent (), AddrSpace) &&
1544
1544
(Stride == 1 || Stride == -1 ))
1545
- return Stride ;
1545
+ return StrideSCEV ;
1546
1546
1547
1547
if (Assume) {
1548
1548
PSE.setNoOverflow (Ptr, SCEVWrapPredicate::IncrementNUSW);
1549
1549
LLVM_DEBUG (dbgs () << " LAA: Pointer may wrap:\n "
1550
1550
<< " LAA: Pointer: " << *Ptr << " \n "
1551
1551
<< " LAA: SCEV: " << *AR << " \n "
1552
1552
<< " LAA: Added an overflow assumption\n " );
1553
- return Stride ;
1553
+ return StrideSCEV ;
1554
1554
}
1555
1555
LLVM_DEBUG (
1556
1556
dbgs () << " LAA: Bad stride - Pointer may wrap in the address space "
1557
1557
<< *Ptr << " SCEV: " << *AR << " \n " );
1558
1558
return std::nullopt;
1559
1559
}
1560
1560
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
+
1561
1574
std::optional<int > llvm::getPointersDiff (Type *ElemTyA, Value *PtrA,
1562
1575
Type *ElemTyB, Value *PtrB,
1563
1576
const DataLayout &DL,
0 commit comments