[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
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user