diff options
author | Alina Sbirlea <asbirlea@google.com> | 2016-11-23 17:43:15 +0000 |
---|---|---|
committer | Alina Sbirlea <asbirlea@google.com> | 2016-11-23 17:43:15 +0000 |
commit | a3d2f703a5b3cf531cd8a472454c0f7b4fd87bbc (patch) | |
tree | baae0a5c78995cf9b26a3ed2060c33e4945776f7 /llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp | |
parent | f174a0bbd24b0efda7c7acb6fff1ed5ed9013a00 (diff) | |
download | bcm5719-llvm-a3d2f703a5b3cf531cd8a472454c0f7b4fd87bbc.tar.gz bcm5719-llvm-a3d2f703a5b3cf531cd8a472454c0f7b4fd87bbc.zip |
[LoadStoreVectorizer] Enable vectorization of stores in the presence of an aliasing load
Summary:
The "getVectorizablePrefix" method would give up if it found an aliasing load for a store chain.
In practice, the aliasing load can be treated as a memory barrier and all stores that precede it
are a valid vectorizable prefix.
Issue found by volkan in D26962. Testcase is a pruned version of the one in the original patch.
Reviewers: jlebar, arsenm, tstellarAMD
Subscribers: mzolotukhin, wdng, nhaehnle, anna, volkan, llvm-commits
Differential Revision: https://reviews.llvm.org/D27008
llvm-svn: 287781
Diffstat (limited to 'llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp')
-rw-r--r-- | llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp b/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp index ead17d01a96..c44a393cf84 100644 --- a/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp @@ -477,10 +477,23 @@ Vectorizer::getVectorizablePrefix(ArrayRef<Instruction *> Chain) { // Loop until we find an instruction in ChainInstrs that we can't vectorize. unsigned ChainInstrIdx = 0; + Instruction *BarrierMemoryInstr = nullptr; + for (unsigned E = ChainInstrs.size(); ChainInstrIdx < E; ++ChainInstrIdx) { Instruction *ChainInstr = ChainInstrs[ChainInstrIdx]; - bool AliasFound = false; + + // If a barrier memory instruction was found, chain instructions that follow + // will not be added to the valid prefix. + if (BarrierMemoryInstr && OBB.dominates(BarrierMemoryInstr, ChainInstr)) + break; + + // Check (in BB order) if any instruction prevents ChainInstr from being + // vectorized. Find and store the first such "conflicting" instruction. for (Instruction *MemInstr : MemoryInstrs) { + // If a barrier memory instruction was found, do not check past it. + if (BarrierMemoryInstr && OBB.dominates(BarrierMemoryInstr, MemInstr)) + break; + if (isa<LoadInst>(MemInstr) && isa<LoadInst>(ChainInstr)) continue; @@ -508,12 +521,21 @@ Vectorizer::getVectorizablePrefix(ArrayRef<Instruction *> Chain) { << " " << *ChainInstr << '\n' << " " << *getPointerOperand(ChainInstr) << '\n'; }); - AliasFound = true; + // Save this aliasing memory instruction as a barrier, but allow other + // instructions that precede the barrier to be vectorized with this one. + BarrierMemoryInstr = MemInstr; break; } } - if (AliasFound) + // Continue the search only for store chains, since vectorizing stores that + // precede an aliasing load is valid. Conversely, vectorizing loads is valid + // up to an aliasing store, but should not pull loads from further down in + // the basic block. + if (IsLoadChain && BarrierMemoryInstr) { + // The BarrierMemoryInstr is a store that precedes ChainInstr. + assert(OBB.dominates(BarrierMemoryInstr, ChainInstr)); break; + } } // Find the largest prefix of Chain whose elements are all in |