summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorDaniel Berlin <dberlin@dberlin.org>2017-03-24 05:30:34 +0000
committerDaniel Berlin <dberlin@dberlin.org>2017-03-24 05:30:34 +0000
commit9d0796e5d0346c8444adf59c5dfa338ca2fb3f01 (patch)
tree0f55d2b7bc0d24d785f34d37f8ae1ab976547c0f /llvm/lib/Transforms
parent9f3fd40aadbd3c0ee2b5fdcd999a21efd7e9f171 (diff)
downloadbcm5719-llvm-9d0796e5d0346c8444adf59c5dfa338ca2fb3f01.tar.gz
bcm5719-llvm-9d0796e5d0346c8444adf59c5dfa338ca2fb3f01.zip
NewGVN: Fix PR32403 - Handling of undef in phis was not quite correct
due to LLVM's view of phi nodes. It would cause NewGVN not to fixpoint in some interesting edge cases. llvm-svn: 298687
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/NewGVN.cpp15
1 files changed, 14 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 5aa8c5cdcab..437f9d1c488 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -368,6 +368,7 @@ private:
const Expression *performSymbolicPredicateInfoEvaluation(Instruction *);
// Congruence finding.
+ bool someEquivalentDominates(const Instruction *, const Instruction *) const;
Value *lookupOperandLeader(Value *) const;
void performCongruenceFinding(Instruction *, const Expression *);
void moveValueToNewCongruenceClass(Instruction *, CongruenceClass *,
@@ -724,6 +725,18 @@ const CallExpression *NewGVN::createCallExpression(CallInst *CI,
return E;
}
+// Return true if some equivalent of instruction Inst dominates instruction U.
+bool NewGVN::someEquivalentDominates(const Instruction *Inst,
+ const Instruction *U) const {
+ auto *CC = ValueToClass.lookup(Inst);
+ assert(isa<Instruction>(CC->RepLeader) && CC->RepLeader == Inst);
+ if (CC)
+ return llvm::any_of(CC->Members, [&](const Value *Member) {
+ return DT->dominates(cast<Instruction>(Member), U);
+ });
+ return false;
+}
+
// See if we have a congruence class and leader for this operand, and if so,
// return it. Otherwise, return the operand itself.
Value *NewGVN::lookupOperandLeader(Value *V) const {
@@ -1054,7 +1067,7 @@ const Expression *NewGVN::performSymbolicPHIEvaluation(Instruction *I) {
if (HasUndef) {
// Only have to check for instructions
if (auto *AllSameInst = dyn_cast<Instruction>(AllSameValue))
- if (!DT->dominates(AllSameInst, I))
+ if (!someEquivalentDominates(AllSameInst, I))
return E;
}
OpenPOWER on IntegriCloud