@@ -813,6 +813,48 @@ static bool hasComputableBounds(PredicatedScalarEvolution &PSE, Value *Ptr,
813813 return AR->isAffine ();
814814}
815815
816+ // / Try to compute the stride for \p AR. Used by getPtrStride.
817+ static std::optional<int64_t >
818+ getStrideFromAddRec (const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy,
819+ Value *Ptr, PredicatedScalarEvolution &PSE) {
820+ // The access function must stride over the innermost loop.
821+ if (Lp != AR->getLoop ()) {
822+ LLVM_DEBUG (dbgs () << " LAA: Bad stride - Not striding over innermost loop "
823+ << *Ptr << " SCEV: " << *AR << " \n " );
824+ return std::nullopt ;
825+ }
826+
827+ // Check the step is constant.
828+ const SCEV *Step = AR->getStepRecurrence (*PSE.getSE ());
829+
830+ // Calculate the pointer stride and check if it is constant.
831+ const SCEVConstant *C = dyn_cast<SCEVConstant>(Step);
832+ if (!C) {
833+ LLVM_DEBUG (dbgs () << " LAA: Bad stride - Not a constant strided " << *Ptr
834+ << " SCEV: " << *AR << " \n " );
835+ return std::nullopt ;
836+ }
837+
838+ const auto &DL = Lp->getHeader ()->getDataLayout ();
839+ TypeSize AllocSize = DL.getTypeAllocSize (AccessTy);
840+ int64_t Size = AllocSize.getFixedValue ();
841+ const APInt &APStepVal = C->getAPInt ();
842+
843+ // Huge step value - give up.
844+ if (APStepVal.getBitWidth () > 64 )
845+ return std::nullopt ;
846+
847+ int64_t StepVal = APStepVal.getSExtValue ();
848+
849+ // Strided access.
850+ int64_t Stride = StepVal / Size;
851+ int64_t Rem = StepVal % Size;
852+ if (Rem)
853+ return std::nullopt ;
854+
855+ return Stride;
856+ }
857+
816858// / Check whether a pointer address cannot wrap.
817859static bool isNoWrap (PredicatedScalarEvolution &PSE,
818860 const DenseMap<Value *, const SCEV *> &Strides, Value *Ptr,
@@ -1458,42 +1500,9 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
14581500 return std::nullopt ;
14591501 }
14601502
1461- // The access function must stride over the innermost loop.
1462- if (Lp != AR->getLoop ()) {
1463- LLVM_DEBUG (dbgs () << " LAA: Bad stride - Not striding over innermost loop "
1464- << *Ptr << " SCEV: " << *AR << " \n " );
1465- return std::nullopt ;
1466- }
1467-
1468- // Check the step is constant.
1469- const SCEV *Step = AR->getStepRecurrence (*PSE.getSE ());
1470-
1471- // Calculate the pointer stride and check if it is constant.
1472- const SCEVConstant *C = dyn_cast<SCEVConstant>(Step);
1473- if (!C) {
1474- LLVM_DEBUG (dbgs () << " LAA: Bad stride - Not a constant strided " << *Ptr
1475- << " SCEV: " << *AR << " \n " );
1476- return std::nullopt ;
1477- }
1478-
1479- const auto &DL = Lp->getHeader ()->getDataLayout ();
1480- TypeSize AllocSize = DL.getTypeAllocSize (AccessTy);
1481- int64_t Size = AllocSize.getFixedValue ();
1482- const APInt &APStepVal = C->getAPInt ();
1483-
1484- // Huge step value - give up.
1485- if (APStepVal.getBitWidth () > 64 )
1486- return std::nullopt ;
1487-
1488- int64_t StepVal = APStepVal.getSExtValue ();
1489-
1490- // Strided access.
1491- int64_t Stride = StepVal / Size;
1492- int64_t Rem = StepVal % Size;
1493- if (Rem)
1494- return std::nullopt ;
1495-
1496- if (!ShouldCheckWrap)
1503+ std::optional<int64_t > Stride =
1504+ getStrideFromAddRec (AR, Lp, AccessTy, Ptr, PSE);
1505+ if (!ShouldCheckWrap || !Stride)
14971506 return Stride;
14981507
14991508 // The address calculation must not wrap. Otherwise, a dependence could be
0 commit comments