diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index b49b4d0c6aba..5bc117d8a055 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -423,31 +423,44 @@ 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: - return SimplifyAddInst(I->getOperand(0), I->getOperand(1), - cast(I)->hasNoSignedWrap(), - cast(I)->hasNoUnsignedWrap(), TD); + Ret = SimplifyAddInst(I->getOperand(0), I->getOperand(1), + cast(I)->hasNoSignedWrap(), + cast(I)->hasNoUnsignedWrap(), TD); + break; case Instruction::And: - return SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD); + Ret = SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD); + break; case Instruction::Or: - return SimplifyOrInst(I->getOperand(0), I->getOperand(1), TD); + Ret = SimplifyOrInst(I->getOperand(0), I->getOperand(1), TD); + break; case Instruction::ICmp: - return SimplifyICmpInst(cast(I)->getPredicate(), - I->getOperand(0), I->getOperand(1), TD); + Ret = SimplifyICmpInst(cast(I)->getPredicate(), + I->getOperand(0), I->getOperand(1), TD); + break; case Instruction::FCmp: - return SimplifyFCmpInst(cast(I)->getPredicate(), - I->getOperand(0), I->getOperand(1), TD); + Ret = SimplifyFCmpInst(cast(I)->getPredicate(), + I->getOperand(0), I->getOperand(1), TD); + break; case Instruction::Select: - return SimplifySelectInst(I->getOperand(0), I->getOperand(1), + Ret = SimplifySelectInst(I->getOperand(0), I->getOperand(1), I->getOperand(2), TD); + break; case Instruction::GetElementPtr: { SmallVector Ops(I->op_begin(), I->op_end()); - return SimplifyGEPInst(&Ops[0], Ops.size(), TD); + Ret = SimplifyGEPInst(&Ops[0], Ops.size(), TD); + break; } } + + // 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 diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/crash.ll b/llvm/test/Transforms/CorrelatedValuePropagation/crash.ll new file mode 100644 index 000000000000..8636788511e5 --- /dev/null +++ b/llvm/test/Transforms/CorrelatedValuePropagation/crash.ll @@ -0,0 +1,20 @@ +; RUN: opt < %s -correlated-propagation + +; PR8161 +define void @test1() nounwind ssp { +entry: + br label %for.end + +for.cond.us.us: ; preds = %for.cond.us.us + %cmp6.i.us.us = icmp sgt i32 1, 0 + %lor.ext.i.us.us = zext i1 %cmp6.i.us.us to i32 + %lor.ext.add.i.us.us = select i1 %cmp6.i.us.us, i32 %lor.ext.i.us.us, i32 undef + %conv.i.us.us = trunc i32 %lor.ext.add.i.us.us to i16 + %sext.us.us = shl i16 %conv.i.us.us, 8 + %conv6.us.us = ashr i16 %sext.us.us, 8 + %and.us.us = and i16 %conv6.us.us, %and.us.us + br i1 false, label %for.end, label %for.cond.us.us + +for.end: ; preds = %for.cond.us, %for.cond.us.us, %entry + ret void +}