aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2010-09-16 17:42:36 +0000
committerOwen Anderson <resistor@mac.com>2010-09-16 17:42:36 +0000
commit4b91c3ac96fd93c7e9794d427787c29c68c25f68 (patch)
tree0725f1b764911d22043e3de87a6abfbda5ffbb26
parent1d51c41a457b99d646e3a9b9fae1e913f7a60dc0 (diff)
downloadexternal_llvm-4b91c3ac96fd93c7e9794d427787c29c68c25f68.zip
external_llvm-4b91c3ac96fd93c7e9794d427787c29c68c25f68.tar.gz
external_llvm-4b91c3ac96fd93c7e9794d427787c29c68c25f68.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114097 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/InstructionSimplify.cpp35
-rw-r--r--test/Transforms/CorrelatedValuePropagation/crash.ll20
2 files changed, 44 insertions, 11 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index b49b4d0..5bc117d 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/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<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
diff --git a/test/Transforms/CorrelatedValuePropagation/crash.ll b/test/Transforms/CorrelatedValuePropagation/crash.ll
new file mode 100644
index 0000000..8636788
--- /dev/null
+++ b/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
+}