[LSV] Don't move stores across may-load instrs, and loosen restrictions on moving loads.

Summary:
Previously we wouldn't move loads/stores across instructions that had
side-effects, where that was defined as may-write or may-throw.  But
this is not sufficiently restrictive: Stores can't safely be moved
across instructions that may load.

This patch also adds a DEBUG check that all instructions in our chain
are either loads or stores.

Reviewers: asbirlea

Subscribers: llvm-commits, jholewinski, arsenm, mzolotukhin

Differential Revision: https://reviews.llvm.org/D22547

llvm-svn: 276171
This commit is contained in:
Justin Lebar
2016-07-20 20:07:37 +00:00
parent 62b03e344e
commit a272c12b73
2 changed files with 213 additions and 36 deletions

View File

@@ -429,6 +429,18 @@ ArrayRef<Value *> Vectorizer::getVectorizablePrefix(ArrayRef<Value *> Chain) {
SmallVector<std::pair<Value *, unsigned>, 16> MemoryInstrs;
SmallVector<std::pair<Value *, unsigned>, 16> ChainInstrs;
bool IsLoadChain = isa<LoadInst>(Chain[0]);
DEBUG({
for (Value *V : Chain) {
if (IsLoadChain)
assert(isa<LoadInst>(V) &&
"All elements of Chain must be loads, or all must be stores.");
else
assert(isa<StoreInst>(V) &&
"All elements of Chain must be loads, or all must be stores.");
}
});
unsigned InstrIdx = 0;
for (Instruction &I : make_range(getBoundaryInstrs(Chain))) {
++InstrIdx;
@@ -437,8 +449,12 @@ ArrayRef<Value *> Vectorizer::getVectorizablePrefix(ArrayRef<Value *> Chain) {
MemoryInstrs.push_back({&I, InstrIdx});
else
ChainInstrs.push_back({&I, InstrIdx});
} else if (I.mayHaveSideEffects()) {
DEBUG(dbgs() << "LSV: Found side-effecting operation: " << I << '\n');
} else if (IsLoadChain && (I.mayWriteToMemory() || I.mayThrow())) {
DEBUG(dbgs() << "LSV: Found may-write/throw operation: " << I << '\n');
break;
} else if (!IsLoadChain && (I.mayReadOrWriteMemory() || I.mayThrow())) {
DEBUG(dbgs() << "LSV: Found may-read/write/throw operation: " << I
<< '\n');
break;
}
}