Pull in r321994 from upstream llvm trunk (by Alexey Bataev):
[SLP] Fix PR35777: Incorrect handling of aggregate values. Summary: Fixes the bug with incorrect handling of InsertValue|InsertElement instrucions in SLP vectorizer. Currently, we may use incorrect ExtractElement instructions as the operands of the original InsertValue|InsertElement instructions. Reviewers: mkuper, hfinkel, RKSimon, spatel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D41767 This should fix "Invalid InsertValueInst operands!" errors when building certain parts of editors/libreoffice. Reported by: jbeich PR: 225086
This commit is contained in:
parent
83ae25da0f
commit
782f2e69ab
@ -95,14 +95,9 @@ struct SLPVectorizerPass : public PassInfoMixin<SLPVectorizerPass> {
|
||||
bool tryToVectorizePair(Value *A, Value *B, slpvectorizer::BoUpSLP &R);
|
||||
|
||||
/// \brief Try to vectorize a list of operands.
|
||||
/// \@param BuildVector A list of users to ignore for the purpose of
|
||||
/// scheduling and cost estimation when NeedExtraction
|
||||
/// is false.
|
||||
/// \returns true if a value was vectorized.
|
||||
bool tryToVectorizeList(ArrayRef<Value *> VL, slpvectorizer::BoUpSLP &R,
|
||||
ArrayRef<Value *> BuildVector = None,
|
||||
bool AllowReorder = false,
|
||||
bool NeedExtraction = false);
|
||||
bool AllowReorder = false);
|
||||
|
||||
/// \brief Try to vectorize a chain that may start at the operands of \p I.
|
||||
bool tryToVectorize(Instruction *I, slpvectorizer::BoUpSLP &R);
|
||||
|
@ -4417,13 +4417,11 @@ bool SLPVectorizerPass::tryToVectorizePair(Value *A, Value *B, BoUpSLP &R) {
|
||||
if (!A || !B)
|
||||
return false;
|
||||
Value *VL[] = { A, B };
|
||||
return tryToVectorizeList(VL, R, None, true);
|
||||
return tryToVectorizeList(VL, R, true);
|
||||
}
|
||||
|
||||
bool SLPVectorizerPass::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
|
||||
ArrayRef<Value *> BuildVector,
|
||||
bool AllowReorder,
|
||||
bool NeedExtraction) {
|
||||
bool AllowReorder) {
|
||||
if (VL.size() < 2)
|
||||
return false;
|
||||
|
||||
@ -4517,12 +4515,7 @@ bool SLPVectorizerPass::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
|
||||
<< "\n");
|
||||
ArrayRef<Value *> Ops = VL.slice(I, OpsWidth);
|
||||
|
||||
ArrayRef<Value *> EmptyArray;
|
||||
ArrayRef<Value *> BuildVectorSlice;
|
||||
if (!BuildVector.empty())
|
||||
BuildVectorSlice = BuildVector.slice(I, OpsWidth);
|
||||
|
||||
R.buildTree(Ops, NeedExtraction ? EmptyArray : BuildVectorSlice);
|
||||
R.buildTree(Ops);
|
||||
// TODO: check if we can allow reordering for more cases.
|
||||
if (AllowReorder && R.shouldReorder()) {
|
||||
// Conceptually, there is nothing actually preventing us from trying to
|
||||
@ -4530,7 +4523,6 @@ bool SLPVectorizerPass::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
|
||||
// reductions. However, at this point, we only expect to get here when
|
||||
// there are exactly two operations.
|
||||
assert(Ops.size() == 2);
|
||||
assert(BuildVectorSlice.empty());
|
||||
Value *ReorderedOps[] = {Ops[1], Ops[0]};
|
||||
R.buildTree(ReorderedOps, None);
|
||||
}
|
||||
@ -4550,31 +4542,7 @@ bool SLPVectorizerPass::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
|
||||
<< " and with tree size "
|
||||
<< ore::NV("TreeSize", R.getTreeSize()));
|
||||
|
||||
Value *VectorizedRoot = R.vectorizeTree();
|
||||
|
||||
// Reconstruct the build vector by extracting the vectorized root. This
|
||||
// way we handle the case where some elements of the vector are
|
||||
// undefined.
|
||||
// (return (inserelt <4 xi32> (insertelt undef (opd0) 0) (opd1) 2))
|
||||
if (!BuildVectorSlice.empty()) {
|
||||
// The insert point is the last build vector instruction. The
|
||||
// vectorized root will precede it. This guarantees that we get an
|
||||
// instruction. The vectorized tree could have been constant folded.
|
||||
Instruction *InsertAfter = cast<Instruction>(BuildVectorSlice.back());
|
||||
unsigned VecIdx = 0;
|
||||
for (auto &V : BuildVectorSlice) {
|
||||
IRBuilder<NoFolder> Builder(InsertAfter->getParent(),
|
||||
++BasicBlock::iterator(InsertAfter));
|
||||
Instruction *I = cast<Instruction>(V);
|
||||
assert(isa<InsertElementInst>(I) || isa<InsertValueInst>(I));
|
||||
Instruction *Extract =
|
||||
cast<Instruction>(Builder.CreateExtractElement(
|
||||
VectorizedRoot, Builder.getInt32(VecIdx++)));
|
||||
I->setOperand(1, Extract);
|
||||
I->moveAfter(Extract);
|
||||
InsertAfter = I;
|
||||
}
|
||||
}
|
||||
R.vectorizeTree();
|
||||
// Move to the next bundle.
|
||||
I += VF - 1;
|
||||
NextInst = I + 1;
|
||||
@ -5495,11 +5463,9 @@ class HorizontalReduction {
|
||||
///
|
||||
/// Returns true if it matches
|
||||
static bool findBuildVector(InsertElementInst *LastInsertElem,
|
||||
SmallVectorImpl<Value *> &BuildVector,
|
||||
SmallVectorImpl<Value *> &BuildVectorOpds) {
|
||||
Value *V = nullptr;
|
||||
do {
|
||||
BuildVector.push_back(LastInsertElem);
|
||||
BuildVectorOpds.push_back(LastInsertElem->getOperand(1));
|
||||
V = LastInsertElem->getOperand(0);
|
||||
if (isa<UndefValue>(V))
|
||||
@ -5508,7 +5474,6 @@ static bool findBuildVector(InsertElementInst *LastInsertElem,
|
||||
if (!LastInsertElem || !LastInsertElem->hasOneUse())
|
||||
return false;
|
||||
} while (true);
|
||||
std::reverse(BuildVector.begin(), BuildVector.end());
|
||||
std::reverse(BuildVectorOpds.begin(), BuildVectorOpds.end());
|
||||
return true;
|
||||
}
|
||||
@ -5517,11 +5482,9 @@ static bool findBuildVector(InsertElementInst *LastInsertElem,
|
||||
///
|
||||
/// \return true if it matches.
|
||||
static bool findBuildAggregate(InsertValueInst *IV,
|
||||
SmallVectorImpl<Value *> &BuildVector,
|
||||
SmallVectorImpl<Value *> &BuildVectorOpds) {
|
||||
Value *V;
|
||||
do {
|
||||
BuildVector.push_back(IV);
|
||||
BuildVectorOpds.push_back(IV->getInsertedValueOperand());
|
||||
V = IV->getAggregateOperand();
|
||||
if (isa<UndefValue>(V))
|
||||
@ -5530,7 +5493,6 @@ static bool findBuildAggregate(InsertValueInst *IV,
|
||||
if (!IV || !IV->hasOneUse())
|
||||
return false;
|
||||
} while (true);
|
||||
std::reverse(BuildVector.begin(), BuildVector.end());
|
||||
std::reverse(BuildVectorOpds.begin(), BuildVectorOpds.end());
|
||||
return true;
|
||||
}
|
||||
@ -5706,27 +5668,25 @@ bool SLPVectorizerPass::vectorizeInsertValueInst(InsertValueInst *IVI,
|
||||
if (!R.canMapToVector(IVI->getType(), DL))
|
||||
return false;
|
||||
|
||||
SmallVector<Value *, 16> BuildVector;
|
||||
SmallVector<Value *, 16> BuildVectorOpds;
|
||||
if (!findBuildAggregate(IVI, BuildVector, BuildVectorOpds))
|
||||
if (!findBuildAggregate(IVI, BuildVectorOpds))
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "SLP: array mappable to vector: " << *IVI << "\n");
|
||||
// Aggregate value is unlikely to be processed in vector register, we need to
|
||||
// extract scalars into scalar registers, so NeedExtraction is set true.
|
||||
return tryToVectorizeList(BuildVectorOpds, R, BuildVector, false, true);
|
||||
return tryToVectorizeList(BuildVectorOpds, R);
|
||||
}
|
||||
|
||||
bool SLPVectorizerPass::vectorizeInsertElementInst(InsertElementInst *IEI,
|
||||
BasicBlock *BB, BoUpSLP &R) {
|
||||
SmallVector<Value *, 16> BuildVector;
|
||||
SmallVector<Value *, 16> BuildVectorOpds;
|
||||
if (!findBuildVector(IEI, BuildVector, BuildVectorOpds))
|
||||
if (!findBuildVector(IEI, BuildVectorOpds))
|
||||
return false;
|
||||
|
||||
// Vectorize starting with the build vector operands ignoring the BuildVector
|
||||
// instructions for the purpose of scheduling and user extraction.
|
||||
return tryToVectorizeList(BuildVectorOpds, R, BuildVector);
|
||||
return tryToVectorizeList(BuildVectorOpds, R);
|
||||
}
|
||||
|
||||
bool SLPVectorizerPass::vectorizeCmpInst(CmpInst *CI, BasicBlock *BB,
|
||||
@ -5804,8 +5764,8 @@ bool SLPVectorizerPass::vectorizeChainsInBlock(BasicBlock *BB, BoUpSLP &R) {
|
||||
// is done when there are exactly two elements since tryToVectorizeList
|
||||
// asserts that there are only two values when AllowReorder is true.
|
||||
bool AllowReorder = NumElts == 2;
|
||||
if (NumElts > 1 && tryToVectorizeList(makeArrayRef(IncIt, NumElts), R,
|
||||
None, AllowReorder)) {
|
||||
if (NumElts > 1 &&
|
||||
tryToVectorizeList(makeArrayRef(IncIt, NumElts), R, AllowReorder)) {
|
||||
// Success start over because instructions might have been changed.
|
||||
HaveVectorizedPhiNodes = true;
|
||||
Changed = true;
|
||||
|
Loading…
Reference in New Issue
Block a user