@@ -290,10 +290,16 @@ bool RuntimePointerChecking::tryToCreateDiffCheck(
290
290
if (AccSink[0 ] < AccSrc[0 ])
291
291
std::swap (Src, Sink);
292
292
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))))
297
303
return false ;
298
304
299
305
SmallVector<Instruction *, 4 > SrcInsts =
@@ -305,17 +311,14 @@ bool RuntimePointerChecking::tryToCreateDiffCheck(
305
311
if (isa<ScalableVectorType>(SrcTy) || isa<ScalableVectorType>(DstTy))
306
312
return false ;
307
313
308
- const DataLayout &DL =
309
- SinkAR->getLoop ()->getHeader ()->getDataLayout ();
314
+ const DataLayout &DL = InnerLoop->getHeader ()->getDataLayout ();
310
315
unsigned AllocSize =
311
316
std::max (DL.getTypeAllocSize (SrcTy), DL.getTypeAllocSize (DstTy));
312
317
313
318
// Only matching constant steps matching the AllocSize are supported at the
314
319
// moment. This simplifies the difference computation. Can be extended in the
315
320
// 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)
319
322
return false ;
320
323
321
324
IntegerType *IntTy =
@@ -324,15 +327,14 @@ bool RuntimePointerChecking::tryToCreateDiffCheck(
324
327
325
328
// When counting down, the dependence distance needs to be swapped.
326
329
if (Step->getValue ()->isNegative ())
327
- std::swap (SinkAR, SrcAR );
330
+ std::swap (SinkStart, SrcStart );
328
331
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);
331
334
if (isa<SCEVCouldNotCompute>(SinkStartInt) ||
332
335
isa<SCEVCouldNotCompute>(SrcStartInt))
333
336
return false ;
334
337
335
- const Loop *InnerLoop = SrcAR->getLoop ();
336
338
// If the start values for both Src and Sink also vary according to an outer
337
339
// loop, then it's probably better to avoid creating diff checks because
338
340
// 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
2811
2813
while (auto *C = dyn_cast<SCEVIntegralCastExpr>(V))
2812
2814
V = C->getOperand ();
2813
2815
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))))
2816
2817
return nullptr ;
2817
2818
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
-
2825
2819
// Note that the restriction after this loop invariant check are only
2826
2820
// profitability restrictions.
2827
2821
if (!SE->isLoopInvariant (V, Lp))
0 commit comments