aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h2
-rw-r--r--include/llvm/Transforms/Utils/Local.h4
-rw-r--r--lib/Analysis/InstructionSimplify.cpp35
3 files changed, 17 insertions, 24 deletions
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index f47e740a74..913fd77da3 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -71,6 +71,8 @@ namespace llvm {
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
+ /// WARNING: If called on unreachable code, an instruction may be reported
+ /// to simplify to itself.
Value *SimplifyInstruction(Instruction *I, const TargetData *TD = 0);
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index caae27f47a..dc18f3c4c7 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -69,6 +69,10 @@ bool RecursivelyDeleteDeadPHINode(PHINode *PN);
///
/// This returns true if it changed the code, note that it can delete
/// instructions in other blocks as well in this block.
+///
+/// WARNING: Do not use this function on unreachable blocks, as recursive
+/// simplification is not able to handle corner-case scenarios that can
+/// arise in them.
bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0);
//===----------------------------------------------------------------------===//
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 5bc117d8a0..b49b4d0c6a 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -423,44 +423,31 @@ Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD) {
- Value *Ret = 0;
switch (I->getOpcode()) {
default:
return ConstantFoldInstruction(I, TD);
case Instruction::Add:
- Ret = SimplifyAddInst(I->getOperand(0), I->getOperand(1),
- cast<BinaryOperator>(I)->hasNoSignedWrap(),
- cast<BinaryOperator>(I)->hasNoUnsignedWrap(), TD);
- break;
+ return SimplifyAddInst(I->getOperand(0), I->getOperand(1),
+ cast<BinaryOperator>(I)->hasNoSignedWrap(),
+ cast<BinaryOperator>(I)->hasNoUnsignedWrap(), TD);
case Instruction::And:
- Ret = SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD);
- break;
+ return SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD);
case Instruction::Or:
- Ret = SimplifyOrInst(I->getOperand(0), I->getOperand(1), TD);
- break;
+ return SimplifyOrInst(I->getOperand(0), I->getOperand(1), TD);
case Instruction::ICmp:
- Ret = SimplifyICmpInst(cast<ICmpInst>(I)->getPredicate(),
- I->getOperand(0), I->getOperand(1), TD);
- break;
+ return SimplifyICmpInst(cast<ICmpInst>(I)->getPredicate(),
+ I->getOperand(0), I->getOperand(1), TD);
case Instruction::FCmp:
- Ret = SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(),
- I->getOperand(0), I->getOperand(1), TD);
- break;
+ return SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(),
+ I->getOperand(0), I->getOperand(1), TD);
case Instruction::Select:
- Ret = SimplifySelectInst(I->getOperand(0), I->getOperand(1),
+ return SimplifySelectInst(I->getOperand(0), I->getOperand(1),
I->getOperand(2), TD);
- break;
case Instruction::GetElementPtr: {
SmallVector<Value*, 8> Ops(I->op_begin(), I->op_end());
- Ret = SimplifyGEPInst(&Ops[0], Ops.size(), TD);
- break;
+ return SimplifyGEPInst(&Ops[0], Ops.size(), TD);
}
}
-
- // It is possible, in situations involving unreachable loops, to
- // have a replacement that, through recursive simplification, ends up
- // simplifying to itself.
- return Ret != I ? Ret : 0;
}
/// ReplaceAndSimplifyAllUses - Perform From->replaceAllUsesWith(To) and then