summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorQuentin Colombet <quentin.colombet@gmail.com>2019-04-15 22:23:46 +0000
committerQuentin Colombet <quentin.colombet@gmail.com>2019-04-15 22:23:46 +0000
commitfda04268886028c0b0b7fd9546548714e4209d5e (patch)
tree63f5958acf33d8f9fc9db8afbadd06bb1262e315 /llvm/lib/Transforms
parentde68a375181f4e831f4d558a75508e0426ba7327 (diff)
downloadbcm5719-llvm-fda04268886028c0b0b7fd9546548714e4209d5e.tar.gz
bcm5719-llvm-fda04268886028c0b0b7fd9546548714e4209d5e.zip
[LSR] Rewrite misses some fixup locations if it splits critical edge
If LSR split critical edge during rewriting phi operands and phi node has other pending fixup operands, we need to update those pending fixups. Otherwise formulae will not be implemented completely and some instructions will not be eliminated. llvm.org/PR41445 Differential Revision: https://reviews.llvm.org/D60645 Patch by: Denis Bakhvalov <denis.bakhvalov@intel.com> llvm-svn: 358457
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp43
1 files changed, 42 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 1cd28944350..c5d0a18c387 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -1929,7 +1929,7 @@ class LSRInstance {
SmallSetVector<Type *, 4> Types;
/// The list of interesting uses.
- SmallVector<LSRUse, 16> Uses;
+ mutable SmallVector<LSRUse, 16> Uses;
/// Track which uses use which register candidates.
RegUseTracker RegUses;
@@ -5290,6 +5290,7 @@ void LSRInstance::RewriteForPHI(
DenseMap<BasicBlock *, Value *> Inserted;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
if (PN->getIncomingValue(i) == LF.OperandValToReplace) {
+ bool needUpdateFixups = false;
BasicBlock *BB = PN->getIncomingBlock(i);
// If this is a critical edge, split the edge so that we do not insert
@@ -5328,6 +5329,8 @@ void LSRInstance::RewriteForPHI(
e = PN->getNumIncomingValues();
BB = NewBB;
i = PN->getBasicBlockIndex(BB);
+
+ needUpdateFixups = true;
}
}
}
@@ -5352,6 +5355,44 @@ void LSRInstance::RewriteForPHI(
PN->setIncomingValue(i, FullV);
Pair.first->second = FullV;
}
+
+ // If LSR split critical edge and phi node has other pending
+ // fixup operands, we need to update those pending fixups. Otherwise
+ // formulae will not be implemented completely and some instructions
+ // will not be eliminated.
+ if (needUpdateFixups) {
+ for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx)
+ for (LSRFixup &Fixup : Uses[LUIdx].Fixups)
+ // If fixup is supposed to rewrite some operand in the phi
+ // that was just updated, it may be already moved to
+ // another phi node. Such fixup requires update.
+ if (Fixup.UserInst == PN) {
+ // Check if the operand we try to replace still exists in the
+ // original phi.
+ bool foundInOriginalPHI = false;
+ for (const auto &val : PN->incoming_values())
+ if (val == Fixup.OperandValToReplace) {
+ foundInOriginalPHI = true;
+ break;
+ }
+
+ // If fixup operand found in original PHI - nothing to do.
+ if (foundInOriginalPHI)
+ continue;
+
+ // Otherwise it might be moved to another PHI and requires update.
+ // If fixup operand not found in any of the incoming blocks that
+ // means we have already rewritten it - nothing to do.
+ for (const auto &Block : PN->blocks())
+ for (BasicBlock::iterator I = Block->begin(); isa<PHINode>(I);
+ ++I) {
+ PHINode *NewPN = cast<PHINode>(I);
+ for (const auto &val : NewPN->incoming_values())
+ if (val == Fixup.OperandValToReplace)
+ Fixup.UserInst = NewPN;
+ }
+ }
+ }
}
}
OpenPOWER on IntegriCloud