@@ -290,10 +290,16 @@ bool RuntimePointerChecking::tryToCreateDiffCheck(
290290 if (AccSink[0 ] < AccSrc[0 ])
291291 std::swap (Src, Sink);
292292
293- auto *SrcAR = dyn_cast<SCEVAddRecExpr>(Src->Expr );
294- auto *SinkAR = dyn_cast<SCEVAddRecExpr>(Sink->Expr );
295- if (!SrcAR || !SinkAR || SrcAR->getLoop () != DC.getInnermostLoop () ||
296- SinkAR->getLoop () != DC.getInnermostLoop ())
293+ const SCEVConstant *Step;
294+ const SCEV *SrcStart;
295+ const SCEV *SinkStart;
296+ const Loop *InnerLoop = DC.getInnermostLoop ();
297+ if (!match (Src->Expr ,
298+ m_scev_AffineAddRec (m_SCEV (SrcStart), m_SCEVConstant (Step),
299+ m_SpecificLoop (InnerLoop))) ||
300+ !match (Sink->Expr ,
301+ m_scev_AffineAddRec (m_SCEV (SinkStart), m_scev_Specific (Step),
302+ m_SpecificLoop (InnerLoop))))
297303 return false ;
298304
299305 SmallVector<Instruction *, 4 > SrcInsts =
@@ -305,17 +311,14 @@ bool RuntimePointerChecking::tryToCreateDiffCheck(
305311 if (isa<ScalableVectorType>(SrcTy) || isa<ScalableVectorType>(DstTy))
306312 return false ;
307313
308- const DataLayout &DL =
309- SinkAR->getLoop ()->getHeader ()->getDataLayout ();
314+ const DataLayout &DL = InnerLoop->getHeader ()->getDataLayout ();
310315 unsigned AllocSize =
311316 std::max (DL.getTypeAllocSize (SrcTy), DL.getTypeAllocSize (DstTy));
312317
313318 // Only matching constant steps matching the AllocSize are supported at the
314319 // moment. This simplifies the difference computation. Can be extended in the
315320 // future.
316- auto *Step = dyn_cast<SCEVConstant>(SinkAR->getStepRecurrence (*SE));
317- if (!Step || Step != SrcAR->getStepRecurrence (*SE) ||
318- Step->getAPInt ().abs () != AllocSize)
321+ if (Step->getAPInt ().abs () != AllocSize)
319322 return false ;
320323
321324 IntegerType *IntTy =
@@ -324,15 +327,14 @@ bool RuntimePointerChecking::tryToCreateDiffCheck(
324327
325328 // When counting down, the dependence distance needs to be swapped.
326329 if (Step->getValue ()->isNegative ())
327- std::swap (SinkAR, SrcAR );
330+ std::swap (SinkStart, SrcStart );
328331
329- const SCEV *SinkStartInt = SE->getPtrToIntExpr (SinkAR-> getStart () , IntTy);
330- const SCEV *SrcStartInt = SE->getPtrToIntExpr (SrcAR-> getStart () , IntTy);
332+ const SCEV *SinkStartInt = SE->getPtrToIntExpr (SinkStart , IntTy);
333+ const SCEV *SrcStartInt = SE->getPtrToIntExpr (SrcStart , IntTy);
331334 if (isa<SCEVCouldNotCompute>(SinkStartInt) ||
332335 isa<SCEVCouldNotCompute>(SrcStartInt))
333336 return false ;
334337
335- const Loop *InnerLoop = SrcAR->getLoop ();
336338 // If the start values for both Src and Sink also vary according to an outer
337339 // loop, then it's probably better to avoid creating diff checks because
338340 // they may not be hoisted. We should instead let llvm::addRuntimeChecks
@@ -2811,17 +2813,9 @@ static const SCEV *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *L
28112813 while (auto *C = dyn_cast<SCEVIntegralCastExpr>(V))
28122814 V = C->getOperand ();
28132815
2814- auto *S = dyn_cast<SCEVAddRecExpr>(V);
2815- if (!S)
2816+ if (!match (V, m_scev_AffineAddRec (m_SCEV (), m_SCEV (V), m_SpecificLoop (Lp))))
28162817 return nullptr ;
28172818
2818- // If the pointer is invariant then there is no stride and it makes no
2819- // sense to add it here.
2820- if (Lp != S->getLoop ())
2821- return nullptr ;
2822-
2823- V = S->getStepRecurrence (*SE);
2824-
28252819 // Note that the restriction after this loop invariant check are only
28262820 // profitability restrictions.
28272821 if (!SE->isLoopInvariant (V, Lp))
0 commit comments