diff options
author | Daniel Berlin <dberlin@dberlin.org> | 2017-03-24 05:30:34 +0000 |
---|---|---|
committer | Daniel Berlin <dberlin@dberlin.org> | 2017-03-24 05:30:34 +0000 |
commit | 9d0796e5d0346c8444adf59c5dfa338ca2fb3f01 (patch) | |
tree | 0f55d2b7bc0d24d785f34d37f8ae1ab976547c0f /llvm/lib/Transforms | |
parent | 9f3fd40aadbd3c0ee2b5fdcd999a21efd7e9f171 (diff) | |
download | bcm5719-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.cpp | 15 |
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; } |