implement a TODO by teaching jump threading about "xor x, 1".
authorChris Lattner <sabre@nondot.org>
Tue, 10 Nov 2009 22:39:16 +0000 (22:39 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 10 Nov 2009 22:39:16 +0000 (22:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86739 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 36cc1fab40d36f1080dba0a1c6b3751621b68f88..cbd8702a4227fbac7970002ecb71779c1b1bdefa 100644 (file)
@@ -299,8 +299,20 @@ ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,PredValueInfo &Result){
       return !Result.empty();
     }
     
-    // TODO: Should handle the NOT form of XOR.
-    
+    // Handle the NOT form of XOR.
+    if (I->getOpcode() == Instruction::Xor &&
+        isa<ConstantInt>(I->getOperand(1)) &&
+        cast<ConstantInt>(I->getOperand(1))->isOne()) {
+      ComputeValueKnownInPredecessors(I->getOperand(0), BB, Result);
+      if (Result.empty())
+        return false;
+
+      // Invert the known values.
+      for (unsigned i = 0, e = Result.size(); i != e; ++i)
+        Result[i].first =
+          cast<ConstantInt>(ConstantExpr::getNot(Result[i].first));
+      return true;
+    }
   }
   
   // Handle compare with phi operand, where the PHI is defined in this block.
index ccb2a3f833010da35f91e91e5e8ac2f81ee8998c..c161a772f2c6b310e49c0b22996780e3e5998527 100644 (file)
@@ -245,3 +245,42 @@ Y:
         ret i32 2
 }
 
+
+;;; Verify that we can handle constraint propagation through "xor x, 1".
+define i32 @test9(i1 %cond, i1 %cond2) {
+Entry:
+; CHECK: @test9
+       %v1 = call i32 @f1()
+       br i1 %cond, label %Merge, label %F1
+
+; CHECK: Entry:
+; CHECK-NEXT:  %v1 = call i32 @f1()
+; CHECK-NEXT:  br i1 %cond, label %F2, label %Merge
+
+F1:
+       %v2 = call i32 @f2()
+       br label %Merge
+
+Merge:
+       %B = phi i32 [%v1, %Entry], [%v2, %F1]
+        %M = icmp eq i32 %B, %v1
+        %M1 = xor i1 %M, 1
+        %N = icmp eq i32 %B, 47
+        %O = and i1 %M1, %N
+       br i1 %O, label %T2, label %F2
+
+; CHECK: Merge:
+; CHECK-NOT: phi
+; CHECK-NEXT:   %v2 = call i32 @f2()
+
+T2:
+       %Q = zext i1 %M to i32
+       ret i32 %Q
+
+F2:
+       ret i32 %B
+; CHECK: F2:
+; CHECK-NEXT: phi i32
+}
+
+