aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-01-23 19:16:25 +0000
committerChris Lattner <sabre@nondot.org>2010-01-23 19:16:25 +0000
commit2dd7657a5b063e6f77c34f418b7e23654b6fe4a0 (patch)
tree67f0ddc05fc97745156f5dac4a37e0b8ef0cb670
parent8231fd1e6ca940511843381ea5f0dbfbc740b1e6 (diff)
add an early out to ProcessBranchOnXOR to speed it up,
handle the case when we can infer an input to the xor from all inputs that agree, instead of going into an infinite loop. Another part of PR6199 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94321 91177308-0d34-0410-b5e6-96231b3b80d8
-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
+}
+