diff options
author | Chris Lattner <sabre@nondot.org> | 2006-10-20 00:42:07 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-10-20 00:42:07 +0000 |
commit | b74b1816305affe25da32c2f29532df41a23cd55 (patch) | |
tree | 3f7e05efb0daa08366016031d31946a5b6261f92 /lib/Transforms/Utils/SimplifyCFG.cpp | |
parent | 8a53688a135e9207392b99cdf8270646d06d38ca (diff) |
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
Diffstat (limited to 'lib/Transforms/Utils/SimplifyCFG.cpp')
-rw-r--r-- | lib/Transforms/Utils/SimplifyCFG.cpp | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 7ac944446e..867455e3e7 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<Instruction*> *AggressiveInsts) { Instruction *I = dyn_cast<Instruction>(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<ConstantExpr>(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()); - - // 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<Instruction>(BrCond)) - if (isInstructionTriviallyDead(BrCondI)) - BrCondI->eraseFromParent(); - return true; + // 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<ConstantExpr>(TrueValue) || + !cast<ConstantExpr>(TrueValue)->canTrap()) && + (!isa<ConstantExpr>(TrueValue) || + !cast<ConstantExpr>(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); + + new ReturnInst(NewRetVal, BI); + BI->eraseFromParent(); + if (Instruction *BrCondI = dyn_cast<Instruction>(BrCond)) + if (isInstructionTriviallyDead(BrCondI)) + BrCondI->eraseFromParent(); + return true; + } } } } |