From: Chris Lattner Date: Fri, 10 Dec 2004 20:41:50 +0000 (+0000) Subject: Fix SCCP/2004-12-10-UndefBranchBug.ll X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=fc6ac506192e79f00597f0cf2fdf1892b0fee09d;p=oota-llvm.git Fix SCCP/2004-12-10-UndefBranchBug.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18776 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 5bd3b4a964d..10c70bfdfdb 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -153,6 +153,13 @@ public: /// void Solve(); + /// ResolveBranchesIn - While solving the dataflow for a function, we assume + /// that branches on undef values cannot reach any of their successors. + /// However, this is not a safe assumption. After we solve dataflow, this + /// method should be use to handle this. If this returns true, the solver + /// should be rerun. + bool ResolveBranchesIn(Function &F); + /// getExecutableBlocks - Once we have solved for constants, return the set of /// blocks that is known to be executable. std::set &getExecutableBlocks() { @@ -869,6 +876,36 @@ void SCCPSolver::Solve() { } } +/// ResolveBranchesIn - While solving the dataflow for a function, we assume +/// that branches on undef values cannot reach any of their successors. +/// However, this is not a safe assumption. After we solve dataflow, this +/// method should be use to handle this. If this returns true, the solver +/// should be rerun. +bool SCCPSolver::ResolveBranchesIn(Function &F) { + bool BranchesResolved = false; + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { + TerminatorInst *TI = BB->getTerminator(); + if (BranchInst *BI = dyn_cast(TI)) { + if (BI->isConditional()) { + LatticeVal &BCValue = getValueState(BI->getCondition()); + if (BCValue.isUndefined()) { + BI->setCondition(ConstantBool::True); + BranchesResolved = true; + visit(BI); + } + } + } else if (SwitchInst *SI = dyn_cast(TI)) { + LatticeVal &SCValue = getValueState(SI->getCondition()); + if (SCValue.isUndefined()) { + SI->setCondition(Constant::getNullValue(SI->getCondition()->getType())); + BranchesResolved = true; + visit(SI); + } + } + } + return BranchesResolved; +} + namespace { Statistic<> NumInstRemoved("sccp", "Number of instructions removed"); @@ -916,7 +953,11 @@ bool SCCP::runOnFunction(Function &F) { Values[AI].markOverdefined(); // Solve for constants. - Solver.Solve(); + bool ResolvedBranches = true; + while (ResolvedBranches) { + Solver.Solve(); + ResolvedBranches = Solver.ResolveBranchesIn(F); + } bool MadeChanges = false; @@ -1037,7 +1078,14 @@ bool IPSCCP::runOnModule(Module &M) { } // Solve for constants. - Solver.Solve(); + bool ResolvedBranches = true; + while (ResolvedBranches) { + Solver.Solve(); + + ResolvedBranches = false; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + ResolvedBranches |= Solver.ResolveBranchesIn(*F); + } bool MadeChanges = false; @@ -1065,7 +1113,7 @@ bool IPSCCP::runOnModule(Module &M) { if (!ExecutableBBs.count(BB)) { DEBUG(std::cerr << " BasicBlock Dead:" << *BB); ++IPNumDeadBlocks; - + // Delete the instructions backwards, as it has a reduced likelihood of // having to update as many def-use and use-def chains. std::vector Insts;