summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp30
-rw-r--r--test/CodeGen/X86/2013-01-09-DAGCombineBug.ll41
2 files changed, 59 insertions, 12 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index ff00d0dd16..359c4cf8e4 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6735,18 +6735,24 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
if (Op0.getOpcode() == Op1.getOpcode()) {
// Avoid missing important xor optimizations.
SDValue Tmp = visitXOR(TheXor);
- if (Tmp.getNode() && Tmp.getNode() != TheXor) {
- DEBUG(dbgs() << "\nReplacing.8 ";
- TheXor->dump(&DAG);
- dbgs() << "\nWith: ";
- Tmp.getNode()->dump(&DAG);
- dbgs() << '\n');
- WorkListRemover DeadNodes(*this);
- DAG.ReplaceAllUsesOfValueWith(N1, Tmp);
- removeFromWorkList(TheXor);
- DAG.DeleteNode(TheXor);
- return DAG.getNode(ISD::BRCOND, N->getDebugLoc(),
- MVT::Other, Chain, Tmp, N2);
+ if (Tmp.getNode()) {
+ if (Tmp.getNode() != TheXor) {
+ DEBUG(dbgs() << "\nReplacing.8 ";
+ TheXor->dump(&DAG);
+ dbgs() << "\nWith: ";
+ Tmp.getNode()->dump(&DAG);
+ dbgs() << '\n');
+ WorkListRemover DeadNodes(*this);
+ DAG.ReplaceAllUsesOfValueWith(N1, Tmp);
+ removeFromWorkList(TheXor);
+ DAG.DeleteNode(TheXor);
+ return DAG.getNode(ISD::BRCOND, N->getDebugLoc(),
+ MVT::Other, Chain, Tmp, N2);
+ }
+
+ // visitXOR has changed XOR's operands.
+ Op0 = TheXor->getOperand(0);
+ Op1 = TheXor->getOperand(1);
}
}
diff --git a/test/CodeGen/X86/2013-01-09-DAGCombineBug.ll b/test/CodeGen/X86/2013-01-09-DAGCombineBug.ll
new file mode 100644
index 0000000000..db7ec8ae26
--- /dev/null
+++ b/test/CodeGen/X86/2013-01-09-DAGCombineBug.ll
@@ -0,0 +1,41 @@
+; RUN: llc -mtriple=x86_64-apple-macosx10.5.0 < %s
+
+; rdar://12968664
+
+define void @t() nounwind uwtable ssp {
+ br label %4
+
+; <label>:1 ; preds = %4, %2
+ ret void
+
+; <label>:2 ; preds = %6, %5, %3, %2
+ switch i32 undef, label %2 [
+ i32 1090573978, label %1
+ i32 1090573938, label %3
+ i32 1090573957, label %5
+ ]
+
+; <label>:3 ; preds = %4, %2
+ br i1 undef, label %2, label %4
+
+; <label>:4 ; preds = %6, %5, %3, %0
+ switch i32 undef, label %11 [
+ i32 1090573938, label %3
+ i32 1090573957, label %5
+ i32 1090573978, label %1
+ i32 165205179, label %6
+ ]
+
+; <label>:5 ; preds = %4, %2
+ br i1 undef, label %2, label %4
+
+; <label>:6 ; preds = %4
+ %7 = icmp eq i32 undef, 590901838
+ %8 = or i1 false, %7
+ %9 = or i1 true, %8
+ %10 = xor i1 %8, %9
+ br i1 %10, label %4, label %2
+
+; <label>:11 ; preds = %11, %4
+ br label %11
+}