diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h index 31b0b8eb21d..d188327fbf4 100644 --- a/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/include/llvm/Analysis/LoopAccessAnalysis.h @@ -362,6 +362,10 @@ public: return &PtrRtCheck; } + /// \brief Number of memchecks required to prove independence of otherwise + /// may-alias pointers. + unsigned getNumRuntimePointerChecks() const { return NumComparisons; } + /// Return true if the block BB needs to be predicated in order for the loop /// to be vectorized. static bool blockNeedsPredication(BasicBlock *BB, Loop *TheLoop, @@ -416,6 +420,10 @@ private: /// loop-independent and loop-carried dependences between memory accesses. MemoryDepChecker DepChecker; + /// \brief Number of memchecks required to prove independence of otherwise + /// may-alias pointers + unsigned NumComparisons; + Loop *TheLoop; ScalarEvolution *SE; const DataLayout &DL; diff --git a/lib/Analysis/LoopAccessAnalysis.cpp b/lib/Analysis/LoopAccessAnalysis.cpp index 27ccd66541f..d044bb008e9 100644 --- a/lib/Analysis/LoopAccessAnalysis.cpp +++ b/lib/Analysis/LoopAccessAnalysis.cpp @@ -1072,7 +1072,6 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) { // Find pointers with computable bounds. We are going to use this information // to place a runtime bound check. - unsigned NumComparisons = 0; bool CanDoRT = false; if (NeedRTCheck) CanDoRT = Accesses.canCheckPtrAtRT(PtrRtCheck, NumComparisons, SE, TheLoop, @@ -1098,17 +1097,6 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) { return; } - if (NumComparisons > RuntimeMemoryCheckThreshold) { - emitAnalysis(LoopAccessReport() - << NumComparisons << " exceeds limit of " - << RuntimeMemoryCheckThreshold - << " dependent memory operations checked at runtime"); - DEBUG(dbgs() << "LAA: Too many memory checks needed.\n"); - PtrRtCheck.reset(); - CanVecMem = false; - return; - } - PtrRtCheck.Need = NeedRTCheck; CanVecMem = true; @@ -1140,18 +1128,6 @@ void LoopAccessInfo::analyzeLoop(const ValueToValueMap &Strides) { return; } - // Check that we did not collect too many pointers. - if (NumComparisons > RuntimeMemoryCheckThreshold) { - emitAnalysis(LoopAccessReport() - << NumComparisons << " exceeds limit of " - << RuntimeMemoryCheckThreshold - << " dependent memory operations checked at runtime"); - DEBUG(dbgs() << "LAA: Can't vectorize with memory checks\n"); - PtrRtCheck.reset(); - CanVecMem = false; - return; - } - CanVecMem = true; } } @@ -1283,9 +1259,9 @@ LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE, const TargetLibraryInfo *TLI, AliasAnalysis *AA, DominatorTree *DT, const ValueToValueMap &Strides) - : DepChecker(SE, L), TheLoop(L), SE(SE), DL(DL), TLI(TLI), AA(AA), - DT(DT), NumLoads(0), NumStores(0), MaxSafeDepDistBytes(-1U), - CanVecMem(false) { + : DepChecker(SE, L), NumComparisons(0), TheLoop(L), SE(SE), DL(DL), + TLI(TLI), AA(AA), DT(DT), NumLoads(0), NumStores(0), + MaxSafeDepDistBytes(-1U), CanVecMem(false) { if (canAnalyzeLoop()) analyzeLoop(Strides); } diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 18a456f611a..1abefd75c97 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -3874,7 +3874,19 @@ bool LoopVectorizationLegality::canVectorizeMemory() { auto &OptionalReport = LAI->getReport(); if (OptionalReport) emitAnalysis(VectorizationReport(*OptionalReport)); - return LAI->canVectorizeMemory(); + if (!LAI->canVectorizeMemory()) + return false; + + if (LAI->getNumRuntimePointerChecks() > + VectorizerParams::RuntimeMemoryCheckThreshold) { + emitAnalysis(VectorizationReport() + << LAI->getNumRuntimePointerChecks() << " exceeds limit of " + << VectorizerParams::RuntimeMemoryCheckThreshold + << " dependent memory operations checked at runtime"); + DEBUG(dbgs() << "LV: Too many memory checks needed.\n"); + return false; + } + return true; } static bool hasMultipleUsesOf(Instruction *I,