generalize a transformation even more: we don't care whether the
authorChris Lattner <sabre@nondot.org>
Sun, 11 Oct 2009 21:29:45 +0000 (21:29 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 11 Oct 2009 21:29:45 +0000 (21:29 +0000)
input the the mul is a zext from bool, just that it is all zeros
other than the low bit.  This fixes some phase ordering issues
that would cause us to miss some xforms in mul.ll when the worklist
is visited differently.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83794 91177308-0d34-0410-b5e6-96231b3b80d8

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

index e9ffb73030551eb9afe0e873d77d87da95105833..549c57633a432ac1c146ab6a6e373001658068f0 100644 (file)
@@ -2781,20 +2781,18 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
   
   // If one of the operands of the multiply is a cast from a boolean value, then
   // 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.
-  {
-    Value *BoolCast = 0, *OtherOp = 0;
-    if (ZExtInst *CI = dyn_cast<ZExtInst>(Op0))
-      if (CI->getOperand(0)->getType() == Type::getInt1Ty(*Context))
-        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;
+  //   X * Y (where Y is 0 or 1) -> X & (0-Y)
+  if (!isa<VectorType>(I.getType())) {
+    // -2 is "-1 << 1" so it is all bits set except the low one.
+    APInt Negative2(I.getType()->getPrimitiveSizeInBits(), -2, true);
     
+    Value *BoolCast = 0, *OtherOp = 0;
+    if (MaskedValueIsZero(Op0, Negative2))
+      BoolCast = Op0, OtherOp = I.getOperand(1);
+    else if (MaskedValueIsZero(I.getOperand(1), Negative2))
+      BoolCast = I.getOperand(1), 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 d8e623c483466d83875486df8b7f869c1ebdbc75..53a56434aede706dfa675869feecdadeb4e2fe6b 100644 (file)
@@ -105,5 +105,12 @@ define i32 @test16(i32 %b, i1 %c) {
         ret i32 %e
 }
 
+; X * Y (when Y is 0 or 1) --> x & (0-Y)
+define i32 @test17(i32 %a, i32 %b) {
+  %a.lobit = lshr i32 %a, 31
+  %e = mul i32 %a.lobit, %b
+  ret i32 %e
+}
+