add an early out to ProcessBranchOnXOR to speed it up,
authorChris Lattner <sabre@nondot.org>
Sat, 23 Jan 2010 19:16:25 +0000 (19:16 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 23 Jan 2010 19:16:25 +0000 (19:16 +0000)
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

lib/Transforms/Scalar/JumpThreading.cpp
test/Transforms/JumpThreading/crash.ll

index 3a65c98195e29ea14fdfee3030838dfea96385d7..a7b4d157fcdbb35ed06235594c8bd15923553e9c 100644 (file)
@@ -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);
 }
index c0ef078ed203370351699e57dfcbdcbb6a7d268c..ff980ffcc62402bf1647f4573cebf798965134d1 100644 (file)
@@ -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
+}
+