@@ -813,6 +813,48 @@ static bool hasComputableBounds(PredicatedScalarEvolution &PSE, Value *Ptr,
813
813
return AR->isAffine ();
814
814
}
815
815
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
+
816
858
// / Check whether a pointer address cannot wrap.
817
859
static bool isNoWrap (PredicatedScalarEvolution &PSE,
818
860
const DenseMap<Value *, const SCEV *> &Strides, Value *Ptr,
@@ -1458,42 +1500,9 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
1458
1500
return std::nullopt;
1459
1501
}
1460
1502
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)
1497
1506
return Stride;
1498
1507
1499
1508
// The address calculation must not wrap. Otherwise, a dependence could be
0 commit comments