diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index f47e740a741..913fd77da3c 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 caae27f47a4..dc18f3c4c7c 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 5bc117d8a05..b49b4d0c6ab 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(I)->hasNoSignedWrap(), - cast(I)->hasNoUnsignedWrap(), TD); - break; + return SimplifyAddInst(I->getOperand(0), I->getOperand(1), + cast(I)->hasNoSignedWrap(), + cast(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(I)->getPredicate(), - I->getOperand(0), I->getOperand(1), TD); - break; + return SimplifyICmpInst(cast(I)->getPredicate(), + I->getOperand(0), I->getOperand(1), TD); case Instruction::FCmp: - Ret = SimplifyFCmpInst(cast(I)->getPredicate(), - I->getOperand(0), I->getOperand(1), TD); - break; + return SimplifyFCmpInst(cast(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 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