aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/Scalar/JumpThreading.cpp25
-rw-r--r--test/Transforms/JumpThreading/crash.ll27
2 files changed, 52 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp
index 3a65c98195..a7b4d157fc 100644
--- a/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1123,6 +1123,11 @@ bool JumpThreading::ProcessBranchOnXOR(BinaryOperator *BO) {
isa<ConstantInt>(BO->getOperand(1)))
return false;
+ // If the first instruction in BB isn't a phi, we won't be able to infer
+ // anything special about any particular predecessor.
+ if (!isa<PHINode>(BB->front()))
+ return false;
+
// If we have a xor as the branch input to this block, and we know that the
// LHS or RHS of the xor in any predecessor is true/false, then we can clone
// the condition into the predecessor and fix that value to true, saving some
@@ -1180,6 +1185,26 @@ bool JumpThreading::ProcessBranchOnXOR(BinaryOperator *BO) {
BlocksToFoldInto.push_back(XorOpValues[i].second);
}
+ // If we inferred a value for all of the predecessors, then duplication won't
+ // help us. However, we can just replace the LHS or RHS with the constant.
+ if (BlocksToFoldInto.size() ==
+ cast<PHINode>(BB->front()).getNumIncomingValues()) {
+ if (SplitVal == 0) {
+ // If all preds provide undef, just nuke the xor, because it is undef too.
+ BO->replaceAllUsesWith(UndefValue::get(BO->getType()));
+ BO->eraseFromParent();
+ } else if (SplitVal->isZero()) {
+ // If all preds provide 0, replace the xor with the other input.
+ BO->replaceAllUsesWith(BO->getOperand(isLHS));
+ BO->eraseFromParent();
+ } else {
+ // If all preds provide 1, set the computed value to 1.
+ BO->setOperand(!isLHS, SplitVal);
+ }
+
+ return true;
+ }
+
// Try to duplicate BB into PredBB.
return DuplicateCondBranchOnPHIIntoPred(BB, BlocksToFoldInto);
}
diff --git a/test/Transforms/JumpThreading/crash.ll b/test/Transforms/JumpThreading/crash.ll
index c0ef078ed2..ff980ffcc6 100644
--- a/test/Transforms/JumpThreading/crash.ll
+++ b/test/Transforms/JumpThreading/crash.ll
@@ -259,3 +259,30 @@ for.cond: ; preds = %for.body, %lor.end
for.body: ; preds = %for.cond
br label %for.cond
}
+
+; PR6119
+define i32 @test9(i32 %action) nounwind {
+entry:
+ switch i32 %action, label %lor.rhs [
+ i32 1, label %if.then
+ i32 0, label %lor.end
+ ]
+
+if.then: ; preds = %for.cond, %lor.end, %entry
+ ret i32 undef
+
+lor.rhs: ; preds = %entry
+ br label %lor.end
+
+lor.end: ; preds = %lor.rhs, %entry
+ %0 = phi i1 [ undef, %lor.rhs ], [ true, %entry ] ; <i1> [#uses=1]
+ %cmp103 = xor i1 undef, %0 ; <i1> [#uses=1]
+ br i1 %cmp103, label %for.cond, label %if.then
+
+for.cond: ; preds = %for.body, %lor.end
+ br i1 undef, label %if.then, label %for.body
+
+for.body: ; preds = %for.cond
+ br label %for.cond
+}
+