summaryrefslogtreecommitdiff
path: root/lib/Transforms/Vectorize/LoopVectorize.cpp
diff options
context:
space:
mode:
authorAyal Zaks <ayal.zaks@intel.com>2017-10-05 12:41:49 +0000
committerAyal Zaks <ayal.zaks@intel.com>2017-10-05 12:41:49 +0000
commit0e8a63e67fb85d78c63756f7846d59b2368482bf (patch)
treee3f61c5e21d4afac2b9d45892128c2d97684bb27 /lib/Transforms/Vectorize/LoopVectorize.cpp
parentf7ceddc7e61d486863a6bf9ddcf74bb87fd1b977 (diff)
[LV] Fix PR34711 - widen instruction ranges when sinking casts
Instead of trying to keep LastWidenRecipe updated after creating each recipe, have tryToWiden() retrieve the last recipe of the current VPBasicBlock and check if it's a VPWidenRecipe when attempting to extend its range. This ensures that such extensions, optimized to maintain the original instruction order, do so only when the instructions are to maintain their relative order. The latter does not always hold, e.g., when a cast needs to sink to unravel first order recurrence (r306884). Testcase derived from reproducer of PR34711. Differential Revision: https://reviews.llvm.org/D38339 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314981 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Vectorize/LoopVectorize.cpp')
-rw-r--r--lib/Transforms/Vectorize/LoopVectorize.cpp45
1 files changed, 22 insertions, 23 deletions
diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp
index 6f53b08ef4c..778fed03614 100644
--- a/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -2215,14 +2215,13 @@ private:
VPWidenIntOrFpInductionRecipe *tryToOptimizeInduction(Instruction *I,
VFRange &Range);
- /// Check if \I can be widened within the given VF \p Range. If \I can be
- /// widened for Range.Start, extend \p LastWidenRecipe to include \p I if
- /// possible or else build a new VPWidenRecipe for it, and return the
- /// VPWidenRecipe that includes \p I. If \p I cannot be widened for
- /// Range.Start \return null. Range.End may be decreased to ensure same
- /// decision from \p Range.Start to \p Range.End.
- VPWidenRecipe *tryToWiden(Instruction *I, VPWidenRecipe *LastWidenRecipe,
- VFRange &Range);
+ /// Check if \p I can be widened within the given VF \p Range. If \p I can be
+ /// widened for \p Range.Start, check if the last recipe of \p VPBB can be
+ /// extended to include \p I or else build a new VPWidenRecipe for it and
+ /// append it to \p VPBB. Return true if \p I can be widened for Range.Start,
+ /// false otherwise. Range.End may be decreased to ensure same decision from
+ /// \p Range.Start to \p Range.End.
+ bool tryToWiden(Instruction *I, VPBasicBlock *VPBB, VFRange &Range);
/// Build a VPReplicationRecipe for \p I and enclose it within a Region if it
/// is predicated. \return \p VPBB augmented with this new recipe if \p I is
@@ -7988,11 +7987,11 @@ LoopVectorizationPlanner::tryToOptimizeInduction(Instruction *I,
return nullptr;
}
-VPWidenRecipe *LoopVectorizationPlanner::tryToWiden(
- Instruction *I, VPWidenRecipe *LastWidenRecipe, VFRange &Range) {
+bool LoopVectorizationPlanner::tryToWiden(Instruction *I, VPBasicBlock *VPBB,
+ VFRange &Range) {
if (Legal->isScalarWithPredication(I))
- return nullptr;
+ return false;
auto IsVectorizableOpcode = [](unsigned Opcode) {
switch (Opcode) {
@@ -8041,13 +8040,13 @@ VPWidenRecipe *LoopVectorizationPlanner::tryToWiden(
};
if (!IsVectorizableOpcode(I->getOpcode()))
- return nullptr;
+ return false;
if (CallInst *CI = dyn_cast<CallInst>(I)) {
Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);
if (ID && (ID == Intrinsic::assume || ID == Intrinsic::lifetime_end ||
ID == Intrinsic::lifetime_start))
- return nullptr;
+ return false;
}
auto willWiden = [&](unsigned VF) -> bool {
@@ -8079,13 +8078,18 @@ VPWidenRecipe *LoopVectorizationPlanner::tryToWiden(
};
if (!getDecisionAndClampRange(willWiden, Range))
- return nullptr;
+ return false;
// Success: widen this instruction. We optimize the common case where
// consecutive instructions can be represented by a single recipe.
- if (LastWidenRecipe && LastWidenRecipe->appendInstruction(I))
- return LastWidenRecipe;
- return new VPWidenRecipe(I);
+ if (!VPBB->empty()) {
+ VPWidenRecipe *LastWidenRecipe = dyn_cast<VPWidenRecipe>(&VPBB->back());
+ if (LastWidenRecipe && LastWidenRecipe->appendInstruction(I))
+ return true;
+ }
+
+ VPBB->appendRecipe(new VPWidenRecipe(I));
+ return true;
}
VPBasicBlock *LoopVectorizationPlanner::handleReplication(
@@ -8182,7 +8186,6 @@ VPlan *LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
auto *FirstVPBBForBB = new VPBasicBlock(BB->getName());
VPBB->setOneSuccessor(FirstVPBBForBB);
VPBB = FirstVPBBForBB;
- VPWidenRecipe *LastWidenRecipe = nullptr;
std::vector<Instruction *> Ingredients;
@@ -8250,12 +8253,8 @@ VPlan *LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
// Check if Instr is to be widened by a general VPWidenRecipe, after
// having first checked for specific widening recipes that deal with
// Interleave Groups, Inductions and Phi nodes.
- if ((Recipe = tryToWiden(Instr, LastWidenRecipe, Range))) {
- if (Recipe != LastWidenRecipe)
- VPBB->appendRecipe(Recipe);
- LastWidenRecipe = cast<VPWidenRecipe>(Recipe);
+ if (tryToWiden(Instr, VPBB, Range))
continue;
- }
// Otherwise, if all widening options failed, Instruction is to be
// replicated. This may create a successor for VPBB.