[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner lattner at cs.uiuc.edu
Mon Feb 6 23:28:04 PST 2006



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.420 -> 1.421
---
Log message:

Make MaskedValueIsZero take a uint64_t instead of a ConstantIntegral as a 
mask.  This allows the code to be simpler and more efficient.

Also, generalize some of the cases in MVIZ a bit, making it slightly more aggressive.


---
Diffs of the changes:  (+58 -69)

 InstructionCombining.cpp |  127 +++++++++++++++++++++--------------------------
 1 files changed, 58 insertions(+), 69 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.420 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.421
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.420	Tue Feb  7 01:00:41 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Tue Feb  7 01:27:52 2006
@@ -406,20 +406,19 @@
 }
 
 /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero.  We use
-/// this predicate to simplify operations downstream.  V and Mask are known to
-/// be the same type.
-static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask, 
-                              unsigned Depth = 0) {
+/// this predicate to simplify operations downstream.  Mask is known to be zero
+/// for bits that V cannot have.
+static bool MaskedValueIsZero(Value *V, uint64_t Mask, unsigned Depth = 0) {
   // Note, we cannot consider 'undef' to be "IsZero" here.  The problem is that
   // we cannot optimize based on the assumption that it is zero without changing
-  // to to an explicit zero.  If we don't change it to zero, other code could
+  // it to be an explicit zero.  If we don't change it to zero, other code could
   // optimized based on the contradictory assumption that it is non-zero.
   // Because instcombine aggressively folds operations with undef args anyway,
   // this won't lose us code quality.
-  if (Mask->isNullValue())
+  if (Mask == 0)
     return true;
   if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(V))
-    return ConstantExpr::getAnd(CI, Mask)->isNullValue();
+    return (CI->getRawValue() & Mask) == 0;
 
   if (Depth == 6) return false;  // Limit search depth.
   
@@ -427,12 +426,9 @@
     switch (I->getOpcode()) {
     case Instruction::And:
       // (X & C1) & C2 == 0   iff   C1 & C2 == 0.
-      if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(I->getOperand(1))) {
-        ConstantIntegral *C1C2 = 
-          cast<ConstantIntegral>(ConstantExpr::getAnd(CI, Mask));
-        if (MaskedValueIsZero(I->getOperand(0), C1C2, Depth+1))
-          return true;
-      }
+      if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(I->getOperand(1)))
+        return MaskedValueIsZero(I->getOperand(0), CI->getRawValue() & Mask,
+                                 Depth+1);
       // If either the LHS or the RHS are MaskedValueIsZero, the result is zero.
       return MaskedValueIsZero(I->getOperand(1), Mask, Depth+1) ||
              MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
@@ -448,41 +444,34 @@
     case Instruction::Cast: {
       const Type *SrcTy = I->getOperand(0)->getType();
       if (SrcTy == Type::BoolTy)
-        return (Mask->getRawValue() & 1) == 0;
+        return (Mask & 1) == 0;
+      if (!SrcTy->isInteger()) return false;
       
-      if (SrcTy->isInteger()) {
-        // (cast <ty> X to int) & C2 == 0  iff <ty> could not have contained C2.
-        if (SrcTy->isUnsigned() &&                      // Only handle zero ext.
-            ConstantExpr::getCast(Mask, SrcTy)->isNullValue())
-          return true;
-        
-        // If this is a noop cast, recurse.
-        if ((SrcTy->isSigned() && SrcTy->getUnsignedVersion() == I->getType())||
-            SrcTy->getSignedVersion() == I->getType()) {
-          Constant *NewMask =
-          ConstantExpr::getCast(Mask, I->getOperand(0)->getType());
-          return MaskedValueIsZero(I->getOperand(0),
-                                   cast<ConstantIntegral>(NewMask), Depth+1);
-        }
-      }
+      // (cast <ty> X to int) & C2 == 0  iff <ty> could not have contained C2.
+      if (SrcTy->isUnsigned())                      // Only handle zero ext.
+        return MaskedValueIsZero(I->getOperand(0),
+                                 Mask & SrcTy->getIntegralTypeMask(), Depth+1);
+      
+      // If this is a noop or trunc cast, recurse.
+      if (SrcTy->getPrimitiveSizeInBits() >= 
+               I->getType()->getPrimitiveSizeInBits())
+        return MaskedValueIsZero(I->getOperand(0),
+                                 Mask & SrcTy->getIntegralTypeMask(), Depth+1);
       break;
     }
     case Instruction::Shl:
       // (shl X, C1) & C2 == 0   iff   (X & C2 >>u C1) == 0
       if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1)))
-        return MaskedValueIsZero(I->getOperand(0),
-                    cast<ConstantIntegral>(ConstantExpr::getUShr(Mask, SA)), 
+        return MaskedValueIsZero(I->getOperand(0), Mask >> SA->getValue(), 
                                  Depth+1);
       break;
     case Instruction::Shr:
       // (ushr X, C1) & C2 == 0   iff  (-1 >> C1) & C2 == 0
       if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1)))
         if (I->getType()->isUnsigned()) {
-          Constant *C1 = ConstantIntegral::getAllOnesValue(I->getType());
-          C1 = ConstantExpr::getShr(C1, SA);
-          C1 = ConstantExpr::getAnd(C1, Mask);
-          if (C1->isNullValue())
-            return true;
+          Mask <<= SA->getValue();
+          Mask &= I->getType()->getIntegralTypeMask();
+          return MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
         }
       break;
     }
@@ -877,10 +866,9 @@
           }
           if (Found) {
             // This is a sign extend if the top bits are known zero.
-            Constant *Mask = ConstantInt::getAllOnesValue(XorLHS->getType());
-            Mask = ConstantExpr::getShl(Mask, 
-                         ConstantInt::get(Type::UByteTy, 64-(TySizeBits-Size)));
-            if (!MaskedValueIsZero(XorLHS, cast<ConstantInt>(Mask)))
+            uint64_t Mask = XorLHS->getType()->getIntegralTypeMask();
+            Mask <<= 64-(TySizeBits-Size);
+            if (!MaskedValueIsZero(XorLHS, Mask))
               Size = 0;  // Not a sign ext, but can't be any others either.
             goto FoundSExt;
           }
@@ -1375,10 +1363,10 @@
       return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
 
   if (I.getType()->isSigned()) {
-    // If the top bits of both operands are zero (i.e. we can prove they are
+    // If the sign bits of both operands are zero (i.e. we can prove they are
     // unsigned inputs), turn this into a udiv.
-    ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType());
-    if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) {
+    uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
+    if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
       const Type *NTy = Op0->getType()->getUnsignedVersion();
       Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
       InsertNewInstBefore(LHS, I);
@@ -1430,8 +1418,8 @@
    
     // If the top bits of both operands are zero (i.e. we can prove they are
     // unsigned inputs), turn this into a urem.
-    ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType());
-    if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) {
+    uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
+    if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
       const Type *NTy = Op0->getType()->getUnsignedVersion();
       Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
       InsertNewInstBefore(LHS, I);
@@ -1888,11 +1876,9 @@
       // is all N is, ignore it.
       unsigned MB, ME;
       if (isRunOfOnes(Mask, MB, ME)) {  // begin/end bit of run, inclusive
-        Constant *Mask = ConstantInt::getAllOnesValue(RHS->getType());
-        Mask = ConstantExpr::getUShr(Mask,
-                                     ConstantInt::get(Type::UByteTy,
-                                                      (64-MB+1)));
-        if (MaskedValueIsZero(RHS, cast<ConstantIntegral>(Mask)))
+        uint64_t Mask = RHS->getType()->getIntegralTypeMask();
+        Mask >>= 64-MB+1;
+        if (MaskedValueIsZero(RHS, Mask))
           break;
       }
     }
@@ -1939,13 +1925,13 @@
         return BinaryOperator::createAnd(X, ConstantExpr::getAnd(C1, AndRHS));
     }
 
-    if (MaskedValueIsZero(Op0, AndRHS))        // LHS & RHS == 0
+    if (MaskedValueIsZero(Op0, AndRHS->getZExtValue()))      // LHS & RHS == 0
       return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
 
     // If the mask is not masking out any bits, there is no reason to do the
     // and in the first place.
-    ConstantIntegral *NotAndRHS =
-      cast<ConstantIntegral>(ConstantExpr::getNot(AndRHS));
+    uint64_t NotAndRHS =   // ~ANDRHS
+      AndRHS->getZExtValue()^Op0->getType()->getIntegralTypeMask();
     if (MaskedValueIsZero(Op0, NotAndRHS))
       return ReplaceInstUsesWith(I, Op0);
 
@@ -1964,9 +1950,9 @@
       case Instruction::Or:
         // (X ^ V) & C2 --> (X & C2) iff (V & C2) == 0
         // (X | V) & C2 --> (X & C2) iff (V & C2) == 0
-        if (MaskedValueIsZero(Op0LHS, AndRHS))
+        if (MaskedValueIsZero(Op0LHS, AndRHS->getZExtValue()))
           return BinaryOperator::createAnd(Op0RHS, AndRHS);
-        if (MaskedValueIsZero(Op0RHS, AndRHS))
+        if (MaskedValueIsZero(Op0RHS, AndRHS->getZExtValue()))
           return BinaryOperator::createAnd(Op0LHS, AndRHS);
 
         // If the mask is only needed on one incoming arm, push it up.
@@ -1979,7 +1965,7 @@
             return BinaryOperator::create(
                        cast<BinaryOperator>(Op0I)->getOpcode(), Op0LHS, NewRHS);
           }
-          if (!isa<Constant>(NotAndRHS) &&
+          if (!isa<Constant>(Op0RHS) &&
               MaskedValueIsZero(Op0RHS, NotAndRHS)) {
             // Not masking anything out for the RHS, move to LHS.
             Instruction *NewLHS = BinaryOperator::createAnd(Op0LHS, AndRHS,
@@ -1993,8 +1979,8 @@
         break;
       case Instruction::And:
         // (X & V) & C2 --> 0 iff (V & C2) == 0
-        if (MaskedValueIsZero(Op0LHS, AndRHS) ||
-            MaskedValueIsZero(Op0RHS, AndRHS))
+        if (MaskedValueIsZero(Op0LHS, AndRHS->getZExtValue()) ||
+            MaskedValueIsZero(Op0RHS, AndRHS->getZExtValue()))
           return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
         break;
       case Instruction::Add:
@@ -2239,8 +2225,8 @@
   if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
     // If X is known to only contain bits that already exist in RHS, just
     // replace this instruction with RHS directly.
-    if (MaskedValueIsZero(Op0,
-                          cast<ConstantIntegral>(ConstantExpr::getNot(RHS))))
+    if (MaskedValueIsZero(Op0, 
+                  RHS->getZExtValue()^RHS->getType()->getIntegralTypeMask()))
       return ReplaceInstUsesWith(I, RHS);
 
     ConstantInt *C1 = 0; Value *X = 0;
@@ -2282,7 +2268,7 @@
 
   // (X^C)|Y -> (X|Y)^C iff Y&C == 0
   if (Op0->hasOneUse() && match(Op0, m_Xor(m_Value(A), m_ConstantInt(C1))) &&
-      MaskedValueIsZero(Op1, C1)) {
+      MaskedValueIsZero(Op1, C1->getZExtValue())) {
     Instruction *NOr = BinaryOperator::createOr(A, Op1, Op0->getName());
     Op0->setName("");
     return BinaryOperator::createXor(InsertNewInstBefore(NOr, I), C1);
@@ -2290,7 +2276,7 @@
 
   // Y|(X^C) -> (X|Y)^C iff Y&C == 0
   if (Op1->hasOneUse() && match(Op1, m_Xor(m_Value(A), m_ConstantInt(C1))) &&
-      MaskedValueIsZero(Op0, C1)) {
+      MaskedValueIsZero(Op0, C1->getZExtValue())) {
     Instruction *NOr = BinaryOperator::createOr(A, Op0, Op1->getName());
     Op0->setName("");
     return BinaryOperator::createXor(InsertNewInstBefore(NOr, I), C1);
@@ -2312,18 +2298,18 @@
       if ((C2->getRawValue() & (C2->getRawValue()+1)) == 0 && // C2 == 0+1+
           match(A, m_Add(m_Value(V1), m_Value(V2)))) {
         // Add commutes, try both ways.
-        if (V1 == B && MaskedValueIsZero(V2, C2))
+        if (V1 == B && MaskedValueIsZero(V2, C2->getZExtValue()))
           return ReplaceInstUsesWith(I, A);
-        if (V2 == B && MaskedValueIsZero(V1, C2))
+        if (V2 == B && MaskedValueIsZero(V1, C2->getZExtValue()))
           return ReplaceInstUsesWith(I, A);
       }
       // Or commutes, try both ways.
       if ((C1->getRawValue() & (C1->getRawValue()+1)) == 0 &&
           match(B, m_Add(m_Value(V1), m_Value(V2)))) {
         // Add commutes, try both ways.
-        if (V1 == A && MaskedValueIsZero(V2, C1))
+        if (V1 == A && MaskedValueIsZero(V2, C1->getZExtValue()))
           return ReplaceInstUsesWith(I, B);
-        if (V2 == A && MaskedValueIsZero(V1, C1))
+        if (V2 == A && MaskedValueIsZero(V1, C1->getZExtValue()))
           return ReplaceInstUsesWith(I, B);
       }
     }
@@ -3599,7 +3585,8 @@
 
   // See if we can turn a signed shr into an unsigned shr.
   if (!isLeftShift && I.getType()->isSigned()) {
-    if (MaskedValueIsZero(Op0, ConstantInt::getMinValue(I.getType()))) {
+    if (MaskedValueIsZero(Op0,
+                          1ULL << (I.getType()->getPrimitiveSizeInBits()-1))) {
       Value *V = InsertCastBefore(Op0, I.getType()->getUnsignedVersion(), I);
       V = InsertNewInstBefore(new ShiftInst(Instruction::Shr, V, Op1,
                                             I.getName()), I);
@@ -4373,7 +4360,8 @@
             Constant *Not1 =
               ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
             // cast (X != 0) to int  --> X if X&~1 == 0
-            if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) {
+            if (MaskedValueIsZero(Op0, 
+                               cast<ConstantIntegral>(Not1)->getZExtValue())) {
               if (CI.getType() == Op0->getType())
                 return ReplaceInstUsesWith(CI, Op0);
               else
@@ -4415,7 +4403,8 @@
             if (Op1C->getRawValue() == 1) {
               Constant *Not1 =
                 ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
-              if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) {
+              if (MaskedValueIsZero(Op0, 
+                              cast<ConstantIntegral>(Not1)->getZExtValue())) {
                 if (CI.getType() == Op0->getType())
                   return ReplaceInstUsesWith(CI, Op0);
                 else






More information about the llvm-commits mailing list