forked from OSchip/llvm-project
Fix PR8161, in which an unreachable loop causes recursive instruction simplification to try
to replace an instruction with itself. Add a predicate to the simplifier to prevent this case. llvm-svn: 114097
This commit is contained in:
parent
ee1934a2da
commit
94532cb297
|
@ -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<BinaryOperator>(I)->hasNoSignedWrap(),
|
||||
cast<BinaryOperator>(I)->hasNoUnsignedWrap(), TD);
|
||||
Ret = SimplifyAddInst(I->getOperand(0), I->getOperand(1),
|
||||
cast<BinaryOperator>(I)->hasNoSignedWrap(),
|
||||
cast<BinaryOperator>(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<ICmpInst>(I)->getPredicate(),
|
||||
I->getOperand(0), I->getOperand(1), TD);
|
||||
Ret = SimplifyICmpInst(cast<ICmpInst>(I)->getPredicate(),
|
||||
I->getOperand(0), I->getOperand(1), TD);
|
||||
break;
|
||||
case Instruction::FCmp:
|
||||
return SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(),
|
||||
I->getOperand(0), I->getOperand(1), TD);
|
||||
Ret = SimplifyFCmpInst(cast<FCmpInst>(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<Value*, 8> 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
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue