From b74b1816305affe25da32c2f29532df41a23cd55 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 20 Oct 2006 00:42:07 +0000 Subject: [PATCH] Fix SimplifyCFG/2006-10-19-UncondDiv.ll by disabling a bad xform. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31061 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/SimplifyCFG.cpp | 59 ++++++++++++++++++---------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 7ac944446e2..867455e3e73 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -323,7 +323,14 @@ static Value *GetIfCondition(BasicBlock *BB, static bool DominatesMergePoint(Value *V, BasicBlock *BB, std::set *AggressiveInsts) { Instruction *I = dyn_cast(V); - if (!I) return true; // Non-instructions all dominate instructions. + if (!I) { + // Non-instructions all dominate instructions, but not all constantexprs + // can be executed unconditionally. + if (ConstantExpr *C = dyn_cast(V)) + if (C->canTrap()) + return false; + return true; + } BasicBlock *PBB = I->getParent(); // We don't want to allow weird loops that might have the "if condition" in @@ -1297,28 +1304,38 @@ bool llvm::SimplifyCFG(BasicBlock *BB) { if (FVPN->getParent() == FalseSucc) FalseValue = FVPN->getIncomingValueForBlock(BI->getParent()); - TrueSucc->removePredecessor(BI->getParent()); - FalseSucc->removePredecessor(BI->getParent()); + // In order for this transformation to be safe, we must be able to + // unconditionally execute both operands to the return. This is + // normally the case, but we could have a potentially-trapping + // constant expression that prevents this transformation from being + // safe. + if ((!isa(TrueValue) || + !cast(TrueValue)->canTrap()) && + (!isa(TrueValue) || + !cast(TrueValue)->canTrap())) { + TrueSucc->removePredecessor(BI->getParent()); + FalseSucc->removePredecessor(BI->getParent()); - // Insert a new select instruction. - Value *NewRetVal; - Value *BrCond = BI->getCondition(); - if (TrueValue != FalseValue) - NewRetVal = new SelectInst(BrCond, TrueValue, - FalseValue, "retval", BI); - else - NewRetVal = TrueValue; - - DEBUG(std::cerr << "\nCHANGING BRANCH TO TWO RETURNS INTO SELECT:" - << "\n " << *BI << "Select = " << *NewRetVal - << "TRUEBLOCK: " << *TrueSucc << "FALSEBLOCK: "<< *FalseSucc); + // Insert a new select instruction. + Value *NewRetVal; + Value *BrCond = BI->getCondition(); + if (TrueValue != FalseValue) + NewRetVal = new SelectInst(BrCond, TrueValue, + FalseValue, "retval", BI); + else + NewRetVal = TrueValue; + + DEBUG(std::cerr << "\nCHANGING BRANCH TO TWO RETURNS INTO SELECT:" + << "\n " << *BI << "Select = " << *NewRetVal + << "TRUEBLOCK: " << *TrueSucc << "FALSEBLOCK: "<< *FalseSucc); - new ReturnInst(NewRetVal, BI); - BI->eraseFromParent(); - if (Instruction *BrCondI = dyn_cast(BrCond)) - if (isInstructionTriviallyDead(BrCondI)) - BrCondI->eraseFromParent(); - return true; + new ReturnInst(NewRetVal, BI); + BI->eraseFromParent(); + if (Instruction *BrCondI = dyn_cast(BrCond)) + if (isInstructionTriviallyDead(BrCondI)) + BrCondI->eraseFromParent(); + return true; + } } } }