From 8cd8473e96d324fc548ec17a32b0f934981f08d0 Mon Sep 17 00:00:00 2001 From: Amjad Aboud Date: Wed, 8 Mar 2017 05:09:10 +0000 Subject: [PATCH] [SLP] Fixed non-deterministic behavior in Loop Vectorizer. Differential Revision: https://reviews.llvm.org/D30638 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297257 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/LoopAccessAnalysis.h | 4 ++-- lib/Analysis/LoopAccessAnalysis.cpp | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h index 0ad52c0e62b..78d7ccb2927 100644 --- a/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/include/llvm/Analysis/LoopAccessAnalysis.h @@ -93,7 +93,7 @@ struct VectorizerParams { class MemoryDepChecker { public: typedef PointerIntPair MemAccessInfo; - typedef SmallPtrSet MemAccessInfoSet; + typedef SmallVector MemAccessInfoList; /// \brief Set of potential dependent memory accesses. typedef EquivalenceClasses DepCandidates; @@ -188,7 +188,7 @@ public: /// \brief Check whether the dependencies between the accesses are safe. /// /// Only checks sets with elements in \p CheckDeps. - bool areDepsSafe(DepCandidates &AccessSets, MemAccessInfoSet &CheckDeps, + bool areDepsSafe(DepCandidates &AccessSets, MemAccessInfoList &CheckDeps, const ValueToValueMap &Strides); /// \brief No memory dependence was encountered that would inhibit diff --git a/lib/Analysis/LoopAccessAnalysis.cpp b/lib/Analysis/LoopAccessAnalysis.cpp index a3ed412b738..c294527d5b0 100644 --- a/lib/Analysis/LoopAccessAnalysis.cpp +++ b/lib/Analysis/LoopAccessAnalysis.cpp @@ -498,7 +498,7 @@ class AccessAnalysis { public: /// \brief Read or write access location. typedef PointerIntPair MemAccessInfo; - typedef SmallPtrSet MemAccessInfoSet; + typedef SmallVector MemAccessInfoList; AccessAnalysis(const DataLayout &Dl, AliasAnalysis *AA, LoopInfo *LI, MemoryDepChecker::DepCandidates &DA, @@ -550,7 +550,7 @@ public: DepChecker.clearDependences(); } - MemAccessInfoSet &getDependenciesToCheck() { return CheckDeps; } + MemAccessInfoList &getDependenciesToCheck() { return CheckDeps; } private: typedef SetVector PtrAccessSet; @@ -564,8 +564,8 @@ private: const DataLayout &DL; - /// Set of accesses that need a further dependence check. - MemAccessInfoSet CheckDeps; + /// List of accesses that need a further dependence check. + MemAccessInfoList CheckDeps; /// Set of pointers that are read only. SmallPtrSet ReadOnlyPtr; @@ -822,7 +822,7 @@ void AccessAnalysis::processMemAccesses() { // there is no other write to the ptr - this is an optimization to // catch "a[i] = a[i] + " without having to do a dependence check). if ((IsWrite || IsReadOnlyPtr) && SetHasWrite) { - CheckDeps.insert(Access); + CheckDeps.push_back(Access); IsRTCheckAnalysisNeeded = true; } @@ -1530,12 +1530,14 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx, } bool MemoryDepChecker::areDepsSafe(DepCandidates &AccessSets, - MemAccessInfoSet &CheckDeps, + MemAccessInfoList &CheckDeps, const ValueToValueMap &Strides) { MaxSafeDepDistBytes = -1; - while (!CheckDeps.empty()) { - MemAccessInfo CurAccess = *CheckDeps.begin(); + SmallPtrSet Visited; + for (MemAccessInfo CurAccess : CheckDeps) { + if (Visited.count(CurAccess)) + continue; // Get the relevant memory access set. EquivalenceClasses::iterator I = @@ -1549,7 +1551,7 @@ bool MemoryDepChecker::areDepsSafe(DepCandidates &AccessSets, // Check every access pair. while (AI != AE) { - CheckDeps.erase(*AI); + Visited.insert(*AI); EquivalenceClasses::member_iterator OI = std::next(AI); while (OI != AE) { // Check every accessing instruction pair in program order. -- 2.50.1