simplify a transformation by making it more general.
authorChris Lattner <sabre@nondot.org>
Sun, 11 Oct 2009 21:22:21 +0000 (21:22 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 11 Oct 2009 21:22:21 +0000 (21:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83792 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/icmp.ll
test/Transforms/InstCombine/mul.ll

index 06a5660f72ec8b8af6e3f45274d30f897074af4c..e9ffb73030551eb9afe0e873d77d87da95105833 100644 (file)
@@ -2783,39 +2783,21 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
   // we know the bool is either zero or one, so this is a 'masking' multiply.
   // See if we can simplify things based on how the boolean was originally
   // formed.
-  CastInst *BoolCast = 0;
-  if (ZExtInst *CI = dyn_cast<ZExtInst>(Op0))
-    if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context))
-      BoolCast = CI;
-  if (!BoolCast)
-    if (ZExtInst *CI = dyn_cast<ZExtInst>(I.getOperand(1)))
+  {
+    Value *BoolCast = 0, *OtherOp = 0;
+    if (ZExtInst *CI = dyn_cast<ZExtInst>(Op0))
       if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context))
-        BoolCast = CI;
-  if (BoolCast) {
-    if (ICmpInst *SCI = dyn_cast<ICmpInst>(BoolCast->getOperand(0))) {
-      Value *SCIOp0 = SCI->getOperand(0), *SCIOp1 = SCI->getOperand(1);
-      const Type *SCOpTy = SCIOp0->getType();
-      bool TIS = false;
-      
-      // If the icmp is true iff the sign bit of X is set, then convert this
-      // multiply into a shift/and combination.
-      if (isa<ConstantInt>(SCIOp1) &&
-          isSignBitCheck(SCI->getPredicate(), cast<ConstantInt>(SCIOp1), TIS) &&
-          TIS) {
-        // Shift the X value right to turn it into "all signbits".
-        Constant *Amt = ConstantInt::get(SCIOp0->getType(),
-                                          SCOpTy->getPrimitiveSizeInBits()-1);
-        Value *V = Builder->CreateAShr(SCIOp0, Amt,
-                                    BoolCast->getOperand(0)->getName()+".mask");
-
-        // If the multiply type is not the same as the source type, sign extend
-        // or truncate to the multiply type.
-        if (I.getType() != V->getType())
-          V = Builder->CreateIntCast(V, I.getType(), true);
-
-        Value *OtherOp = Op0 == BoolCast ? I.getOperand(1) : Op0;
-        return BinaryOperator::CreateAnd(V, OtherOp);
-      }
+        BoolCast = CI, OtherOp = I.getOperand(1);
+    if (!BoolCast)
+      if (ZExtInst *CI = dyn_cast<ZExtInst>(I.getOperand(1)))
+        if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context))
+          BoolCast = CI, OtherOp = Op0;
+    
+    if (BoolCast) {
+      // X * Y (where Y is 0 or 1) -> X & (0-Y)
+      Value *V = Builder->CreateSub(Constant::getNullValue(I.getType()),
+                                    BoolCast, "tmp");
+      return BinaryOperator::CreateAnd(V, OtherOp);
     }
   }
 
index 3b6f8c59ce6e9da9b4da0608760aaa188fd89db8..64e88c9ae86d7b0e36d4bb6582b0a4f6f628b7e3 100644 (file)
@@ -33,4 +33,12 @@ define <2 x i1> @test5(<2 x i64> %x) {
 entry:
   %V = icmp eq <2 x i64> %x, undef
   ret <2 x i1> %V
-}
\ No newline at end of file
+}
+
+define i32 @test6(i32 %a, i32 %b) {
+        %c = icmp sle i32 %a, -1
+        %d = zext i1 %c to i32
+        %e = sub i32 0, %d
+        %f = and i32 %e, %b
+        ret i32 %f
+}
index e127efb9dcfd658ebaeb260a34083c4efd1eaca2..d8e623c483466d83875486df8b7f869c1ebdbc75 100644 (file)
@@ -96,3 +96,14 @@ entry:
   %m = mul i32 %shl, %A
   ret i32 %m
 }
+
+; X * Y (when Y is 0 or 1) --> x & (0-Y)
+define i32 @test16(i32 %b, i1 %c) {
+        %d = zext i1 %c to i32          ; <i32> [#uses=1]
+        ; e = b & (a >> 31)
+        %e = mul i32 %d, %b             ; <i32> [#uses=1]
+        ret i32 %e
+}
+
+
+