[PATCH] fix non-determinism issue in SLP
Daniel Reynaud
dreynaud at apple.com
Mon Jan 5 15:31:13 PST 2015
The issue was introduced in r214638:
+ for (auto &BSIter : BlocksSchedules) {
+ scheduleBlock(BSIter.second.get());
+ }
Because BlocksSchedules is a DenseMap with BasicBlock* keys, blocks are scheduled in non-deterministic order, resulting in unpredictable IR.
The following patch fixes the issue with the cost of an extra SetVector:
diff --git a/lib/Transforms/Vectorize/SLPVectorizer.cpp b/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 912e580..e04ea17 100644
--- a/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -382,8 +382,7 @@ public:
ExternalUses.clear();
NumLoadsWantToKeepOrder = 0;
NumLoadsWantToChangeOrder = 0;
- for (auto &Iter : BlocksSchedules) {
- BlockScheduling *BS = Iter.second.get();
+ for (auto BS : BlocksSchedulesSV) {
BS->clear();
}
}
@@ -807,6 +806,7 @@ private:
/// Attaches the BlockScheduling structures to basic blocks.
DenseMap<BasicBlock *, std::unique_ptr<BlockScheduling>> BlocksSchedules;
+ SetVector<BlockScheduling*> BlocksSchedulesSV;
/// Performs the "real" scheduling. Done before vectorization is actually
/// performed in a basic block.
@@ -996,6 +996,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth) {
auto &BSRef = BlocksSchedules[BB];
if (!BSRef) {
BSRef = llvm::make_unique<BlockScheduling>(BB);
+ BlocksSchedulesSV.insert(BSRef.get());
}
BlockScheduling &BS = *BSRef.get();
@@ -2163,8 +2164,8 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
Value *BoUpSLP::vectorizeTree() {
// All blocks must be scheduled before any instructions are inserted.
- for (auto &BSIter : BlocksSchedules) {
- scheduleBlock(BSIter.second.get());
+ for (auto &BSIter : BlocksSchedulesSV) {
+ scheduleBlock(BSIter);
}
Builder.SetInsertPoint(F->getEntryBlock().begin());
More information about the llvm-commits
mailing list