From 32bc789b6c46cee1bde37b7488d02b2febcb9102 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Sat, 16 Jun 2007 00:26:54 +0000 Subject: [PATCH] Fix test/Transforms/GVNPRE/2007-06-15-InvokeInst.ll by ignoring all instructions that depend on invokes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37610 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/GVNPRE.cpp | 39 +++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/Scalar/GVNPRE.cpp b/lib/Transforms/Scalar/GVNPRE.cpp index d52e4d378f8..a2a77436672 100644 --- a/lib/Transforms/Scalar/GVNPRE.cpp +++ b/lib/Transforms/Scalar/GVNPRE.cpp @@ -285,6 +285,33 @@ void GVNPRE::phi_translate_set(std::set& anticIn, } } +bool dependsOnInvoke(Value* V) { + if (!isa(V)) + return false; + + User* U = cast(V); + std::vector worklist(U->op_begin(), U->op_end()); + std::set visited; + + while (!worklist.empty()) { + Value* current = worklist.back(); + worklist.pop_back(); + visited.insert(current); + + if (!isa(current)) + continue; + else if (isa(current)) + return true; + + User* curr = cast(current); + for (unsigned i = 0; i < curr->getNumOperands(); ++i) + if (visited.find(curr->getOperand(i)) == visited.end()) + worklist.push_back(curr->getOperand(i)); + } + + return false; +} + // Remove all expressions whose operands are not themselves in the set void GVNPRE::clean(std::set& set) { std::vector worklist; @@ -302,6 +329,7 @@ void GVNPRE::clean(std::set& set) { lhsValid = true; break; } + lhsValid &= !dependsOnInvoke(BO->getOperand(0)); bool rhsValid = !isa(BO->getOperand(1)); if (!rhsValid) @@ -311,6 +339,7 @@ void GVNPRE::clean(std::set& set) { rhsValid = true; break; } + rhsValid &= !dependsOnInvoke(BO->getOperand(1)); if (!lhsValid || !rhsValid) set.erase(BO); @@ -323,7 +352,8 @@ void GVNPRE::clean(std::set& set) { lhsValid = true; break; } - + lhsValid &= !dependsOnInvoke(C->getOperand(0)); + bool rhsValid = !isa(C->getOperand(1)); if (!rhsValid) for (std::set::iterator I = set.begin(), E = set.end(); @@ -332,6 +362,7 @@ void GVNPRE::clean(std::set& set) { rhsValid = true; break; } + rhsValid &= !dependsOnInvoke(C->getOperand(1)); if (!lhsValid || !rhsValid) set.erase(C); @@ -800,13 +831,15 @@ bool GVNPRE::runOnFunction(Function &F) { User* U = cast(e2); Value* s1 = 0; - if (isa(U->getOperand(0))) + if (isa(U->getOperand(0)) || + isa(U->getOperand(0))) s1 = find_leader(availableOut[*PI], U->getOperand(0)); else s1 = U->getOperand(0); Value* s2 = 0; - if (isa(U->getOperand(1))) + if (isa(U->getOperand(1)) || + isa(U->getOperand(1))) s2 = find_leader(availableOut[*PI], U->getOperand(1)); else s2 = U->getOperand(1);