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

Reid Spencer reid at x10sys.com
Mon Mar 12 10:26:19 PDT 2007



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.655 -> 1.656
---
Log message:

Add an APInt version of SimplifyDemandedBits.

Patch by Zhou Sheng.


---
Diffs of the changes:  (+524 -1)

 InstructionCombining.cpp |  525 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 524 insertions(+), 1 deletion(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.655 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.656
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.655	Mon Mar 12 12:15:10 2007
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Mon Mar 12 12:25:59 2007
@@ -319,10 +319,14 @@
     /// most-complex to least-complex order.
     bool SimplifyCompare(CmpInst &I);
 
-    bool SimplifyDemandedBits(Value *V, uint64_t Mask, 
+    bool SimplifyDemandedBits(Value *V, uint64_t DemandedMask, 
                               uint64_t &KnownZero, uint64_t &KnownOne,
                               unsigned Depth = 0);
 
+    bool SimplifyDemandedBits(Value *V, APInt DemandedMask, 
+                              APInt& KnownZero, APInt& KnownOne,
+                              unsigned Depth = 0);
+
     Value *SimplifyDemandedVectorElts(Value *V, uint64_t DemandedElts,
                                       uint64_t &UndefElts, unsigned Depth = 0);
       
@@ -1545,6 +1549,525 @@
   return false;
 }  
 
+/// SimplifyDemandedBits - This function attempts to replace V with a simpler
+/// value based on the demanded bits. When this function is called, it is known
+/// that only the bits set in DemandedMask of the result of V are ever used
+/// downstream. Consequently, depending on the mask and V, it may be possible
+/// to replace V with a constant or one of its operands. In such cases, this
+/// function does the replacement and returns true. In all other cases, it
+/// returns false after analyzing the expression and setting KnownOne and known
+/// to be one in the expression. KnownZero contains all the bits that are known
+/// to be zero in the expression. These are provided to potentially allow the
+/// caller (which might recursively be SimplifyDemandedBits itself) to simplify
+/// the expression. KnownOne and KnownZero always follow the invariant that 
+/// KnownOne & KnownZero == 0. That is, a bit can't be both 1 and 0. Note that
+/// the bits in KnownOne and KnownZero may only be accurate for those bits set
+/// in DemandedMask. Note also that the bitwidth of V, DemandedMask, KnownZero
+/// and KnownOne must all be the same.
+bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
+                                        APInt& KnownZero, APInt& KnownOne,
+                                        unsigned Depth) {
+  assert(V != 0 && "Null pointer of Value???");
+  assert(Depth <= 6 && "Limit Search Depth");
+  uint32_t BitWidth = DemandedMask.getBitWidth();
+  const IntegerType *VTy = cast<IntegerType>(V->getType());
+  assert(VTy->getBitWidth() == BitWidth && 
+         KnownZero.getBitWidth() == BitWidth && 
+         KnownOne.getBitWidth() == BitWidth &&
+         "Value *V, DemandedMask, KnownZero and KnownOne \
+          must have same BitWidth");
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+    // We know all of the bits for a constant!
+    KnownOne = CI->getValue() & DemandedMask;
+    KnownZero = ~KnownOne & DemandedMask;
+    return false;
+  }
+  
+  //KnownZero.clear(); 
+  //KnownOne.clear();
+  if (!V->hasOneUse()) {    // Other users may use these bits.
+    if (Depth != 0) {       // Not at the root.
+      // Just compute the KnownZero/KnownOne bits to simplify things downstream.
+      ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth);
+      return false;
+    }
+    // If this is the root being simplified, allow it to have multiple uses,
+    // just set the DemandedMask to all bits.
+    DemandedMask = APInt::getAllOnesValue(BitWidth);
+  } else if (DemandedMask == 0) {   // Not demanding any bits from V.
+    if (V != UndefValue::get(VTy))
+      return UpdateValueUsesWith(V, UndefValue::get(VTy));
+    return false;
+  } else if (Depth == 6) {        // Limit search depth.
+    return false;
+  }
+  
+  Instruction *I = dyn_cast<Instruction>(V);
+  if (!I) return false;        // Only analyze instructions.
+
+  DemandedMask &= APInt::getAllOnesValue(BitWidth);
+  
+  APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
+  APInt &RHSKnownZero = KnownZero, &RHSKnownOne = KnownOne;
+  switch (I->getOpcode()) {
+  default: break;
+  case Instruction::And:
+    // If either the LHS or the RHS are Zero, the result is zero.
+    if (SimplifyDemandedBits(I->getOperand(1), DemandedMask,
+                             RHSKnownZero, RHSKnownOne, Depth+1))
+      return true;
+    assert((RHSKnownZero & RHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+
+    // If something is known zero on the RHS, the bits aren't demanded on the
+    // LHS.
+    if (SimplifyDemandedBits(I->getOperand(0), DemandedMask & ~RHSKnownZero,
+                             LHSKnownZero, LHSKnownOne, Depth+1))
+      return true;
+    assert((LHSKnownZero & LHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+
+    // If all of the demanded bits are known 1 on one side, return the other.
+    // These bits cannot contribute to the result of the 'and'.
+    if ((DemandedMask & ~LHSKnownZero & RHSKnownOne) == 
+        (DemandedMask & ~LHSKnownZero))
+      return UpdateValueUsesWith(I, I->getOperand(0));
+    if ((DemandedMask & ~RHSKnownZero & LHSKnownOne) == 
+        (DemandedMask & ~RHSKnownZero))
+      return UpdateValueUsesWith(I, I->getOperand(1));
+    
+    // If all of the demanded bits in the inputs are known zeros, return zero.
+    if ((DemandedMask & (RHSKnownZero|LHSKnownZero)) == DemandedMask)
+      return UpdateValueUsesWith(I, Constant::getNullValue(VTy));
+      
+    // If the RHS is a constant, see if we can simplify it.
+    if (ShrinkDemandedConstant(I, 1, DemandedMask & ~LHSKnownZero))
+      return UpdateValueUsesWith(I, I);
+      
+    // Output known-1 bits are only known if set in both the LHS & RHS.
+    RHSKnownOne &= LHSKnownOne;
+    // Output known-0 are known to be clear if zero in either the LHS | RHS.
+    RHSKnownZero |= LHSKnownZero;
+    break;
+  case Instruction::Or:
+    // If either the LHS or the RHS are One, the result is One.
+    if (SimplifyDemandedBits(I->getOperand(1), DemandedMask, 
+                             RHSKnownZero, RHSKnownOne, Depth+1))
+      return true;
+    assert((RHSKnownZero & RHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+    // If something is known one on the RHS, the bits aren't demanded on the
+    // LHS.
+    if (SimplifyDemandedBits(I->getOperand(0), DemandedMask & ~RHSKnownOne, 
+                             LHSKnownZero, LHSKnownOne, Depth+1))
+      return true;
+    assert((LHSKnownZero & LHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+    
+    // If all of the demanded bits are known zero on one side, return the other.
+    // These bits cannot contribute to the result of the 'or'.
+    if ((DemandedMask & ~LHSKnownOne & RHSKnownZero) == 
+        (DemandedMask & ~LHSKnownOne))
+      return UpdateValueUsesWith(I, I->getOperand(0));
+    if ((DemandedMask & ~RHSKnownOne & LHSKnownZero) == 
+        (DemandedMask & ~RHSKnownOne))
+      return UpdateValueUsesWith(I, I->getOperand(1));
+
+    // If all of the potentially set bits on one side are known to be set on
+    // the other side, just use the 'other' side.
+    if ((DemandedMask & (~RHSKnownZero) & LHSKnownOne) == 
+        (DemandedMask & (~RHSKnownZero)))
+      return UpdateValueUsesWith(I, I->getOperand(0));
+    if ((DemandedMask & (~LHSKnownZero) & RHSKnownOne) == 
+        (DemandedMask & (~LHSKnownZero)))
+      return UpdateValueUsesWith(I, I->getOperand(1));
+        
+    // If the RHS is a constant, see if we can simplify it.
+    if (ShrinkDemandedConstant(I, 1, DemandedMask))
+      return UpdateValueUsesWith(I, I);
+          
+    // Output known-0 bits are only known if clear in both the LHS & RHS.
+    RHSKnownZero &= LHSKnownZero;
+    // Output known-1 are known to be set if set in either the LHS | RHS.
+    RHSKnownOne |= LHSKnownOne;
+    break;
+  case Instruction::Xor: {
+    if (SimplifyDemandedBits(I->getOperand(1), DemandedMask,
+                             RHSKnownZero, RHSKnownOne, Depth+1))
+      return true;
+    assert((RHSKnownZero & RHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+    if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, 
+                             LHSKnownZero, LHSKnownOne, Depth+1))
+      return true;
+    assert((LHSKnownZero & LHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+    
+    // If all of the demanded bits are known zero on one side, return the other.
+    // These bits cannot contribute to the result of the 'xor'.
+    if ((DemandedMask & RHSKnownZero) == DemandedMask)
+      return UpdateValueUsesWith(I, I->getOperand(0));
+    if ((DemandedMask & LHSKnownZero) == DemandedMask)
+      return UpdateValueUsesWith(I, I->getOperand(1));
+    
+    // Output known-0 bits are known if clear or set in both the LHS & RHS.
+    APInt KnownZeroOut = (RHSKnownZero & LHSKnownZero) | 
+                         (RHSKnownOne & LHSKnownOne);
+    // Output known-1 are known to be set if set in only one of the LHS, RHS.
+    APInt KnownOneOut = (RHSKnownZero & LHSKnownOne) | 
+                        (RHSKnownOne & LHSKnownZero);
+    
+    // If all of the demanded bits are known to be zero on one side or the
+    // other, turn this into an *inclusive* or.
+    //    e.g. (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
+    if ((DemandedMask & ~RHSKnownZero & ~LHSKnownZero) == 0) {
+      Instruction *Or =
+        BinaryOperator::createOr(I->getOperand(0), I->getOperand(1),
+                                 I->getName());
+      InsertNewInstBefore(Or, *I);
+      return UpdateValueUsesWith(I, Or);
+    }
+    
+    // If all of the demanded bits on one side are known, and all of the set
+    // bits on that side are also known to be set on the other side, turn this
+    // into an AND, as we know the bits will be cleared.
+    //    e.g. (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
+    if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask) { 
+      // all known
+      if ((RHSKnownOne & LHSKnownOne) == RHSKnownOne) {
+        Constant *AndC = ConstantInt::get(~RHSKnownOne & DemandedMask);
+        Instruction *And = 
+          BinaryOperator::createAnd(I->getOperand(0), AndC, "tmp");
+        InsertNewInstBefore(And, *I);
+        return UpdateValueUsesWith(I, And);
+      }
+    }
+    
+    // If the RHS is a constant, see if we can simplify it.
+    // FIXME: for XOR, we prefer to force bits to 1 if they will make a -1.
+    if (ShrinkDemandedConstant(I, 1, DemandedMask))
+      return UpdateValueUsesWith(I, I);
+    
+    RHSKnownZero = KnownZeroOut;
+    RHSKnownOne  = KnownOneOut;
+    break;
+  }
+  case Instruction::Select:
+    if (SimplifyDemandedBits(I->getOperand(2), DemandedMask,
+                             RHSKnownZero, RHSKnownOne, Depth+1))
+      return true;
+    if (SimplifyDemandedBits(I->getOperand(1), DemandedMask, 
+                             LHSKnownZero, LHSKnownOne, Depth+1))
+      return true;
+    assert((RHSKnownZero & RHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+    assert((LHSKnownZero & LHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+    
+    // If the operands are constants, see if we can simplify them.
+    if (ShrinkDemandedConstant(I, 1, DemandedMask))
+      return UpdateValueUsesWith(I, I);
+    if (ShrinkDemandedConstant(I, 2, DemandedMask))
+      return UpdateValueUsesWith(I, I);
+    
+    // Only known if known in both the LHS and RHS.
+    RHSKnownOne &= LHSKnownOne;
+    RHSKnownZero &= LHSKnownZero;
+    break;
+  case Instruction::Trunc: {
+    uint32_t truncBf = 
+      cast<IntegerType>(I->getOperand(0)->getType())->getBitWidth();
+    if (SimplifyDemandedBits(I->getOperand(0), DemandedMask.zext(truncBf),
+        RHSKnownZero.zext(truncBf), RHSKnownOne.zext(truncBf), Depth+1))
+      return true;
+    DemandedMask.trunc(BitWidth);
+    RHSKnownZero.trunc(BitWidth);
+    RHSKnownOne.trunc(BitWidth);
+    assert((RHSKnownZero & RHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+    break;
+  }
+  case Instruction::BitCast:
+    if (!I->getOperand(0)->getType()->isInteger())
+      return false;
+      
+    if (SimplifyDemandedBits(I->getOperand(0), DemandedMask,
+                             RHSKnownZero, RHSKnownOne, Depth+1))
+      return true;
+    assert((RHSKnownZero & RHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+    break;
+  case Instruction::ZExt: {
+    // Compute the bits in the result that are not present in the input.
+    const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType());
+    APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy->getBitWidth()));
+    
+    DemandedMask &= SrcTy->getMask().zext(BitWidth);
+    uint32_t zextBf = SrcTy->getBitWidth();
+    if (SimplifyDemandedBits(I->getOperand(0), DemandedMask.trunc(zextBf),
+          RHSKnownZero.trunc(zextBf), RHSKnownOne.trunc(zextBf), Depth+1))
+      return true;
+    DemandedMask.zext(BitWidth);
+    RHSKnownZero.zext(BitWidth);
+    RHSKnownOne.zext(BitWidth);
+    assert((RHSKnownZero & RHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+    // The top bits are known to be zero.
+    RHSKnownZero |= NewBits;
+    break;
+  }
+  case Instruction::SExt: {
+    // Compute the bits in the result that are not present in the input.
+    const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType());
+    APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy->getBitWidth()));
+    
+    // Get the sign bit for the source type
+    APInt InSignBit(APInt::getSignBit(SrcTy->getPrimitiveSizeInBits()));
+    InSignBit.zext(BitWidth);
+    APInt InputDemandedBits = DemandedMask & 
+                              SrcTy->getMask().zext(BitWidth);
+
+    // If any of the sign extended bits are demanded, we know that the sign
+    // bit is demanded.
+    if ((NewBits & DemandedMask) != 0)
+      InputDemandedBits |= InSignBit;
+      
+    uint32_t sextBf = SrcTy->getBitWidth();
+    if (SimplifyDemandedBits(I->getOperand(0), InputDemandedBits.trunc(sextBf),
+          RHSKnownZero.trunc(sextBf), RHSKnownOne.trunc(sextBf), Depth+1))
+      return true;
+    InputDemandedBits.zext(BitWidth);
+    RHSKnownZero.zext(BitWidth);
+    RHSKnownOne.zext(BitWidth);
+    assert((RHSKnownZero & RHSKnownOne) == 0 && 
+           "Bits known to be one AND zero?"); 
+      
+    // If the sign bit of the input is known set or clear, then we know the
+    // top bits of the result.
+
+    // If the input sign bit is known zero, or if the NewBits are not demanded
+    // convert this into a zero extension.
+    if ((RHSKnownZero & InSignBit) != 0 || (NewBits & ~DemandedMask) == NewBits)
+    {
+      // Convert to ZExt cast
+      CastInst *NewCast = new ZExtInst(I->getOperand(0), VTy, I->getName(), I);
+      return UpdateValueUsesWith(I, NewCast);
+    } else if ((RHSKnownOne & InSignBit) != 0) {    // Input sign bit known set
+      RHSKnownOne |= NewBits;
+      RHSKnownZero &= ~NewBits;
+    } else {                              // Input sign bit unknown
+      RHSKnownZero &= ~NewBits;
+      RHSKnownOne &= ~NewBits;
+    }
+    break;
+  }
+  case Instruction::Add: {
+    // Figure out what the input bits are.  If the top bits of the and result
+    // are not demanded, then the add doesn't demand them from its input
+    // either.
+    unsigned NLZ = DemandedMask.countLeadingZeros();
+      
+    // If there is a constant on the RHS, there are a variety of xformations
+    // we can do.
+    if (ConstantInt *RHS = dyn_cast<ConstantInt>(I->getOperand(1))) {
+      // If null, this should be simplified elsewhere.  Some of the xforms here
+      // won't work if the RHS is zero.
+      if (RHS->isZero())
+        break;
+      
+      // If the top bit of the output is demanded, demand everything from the
+      // input.  Otherwise, we demand all the input bits except NLZ top bits.
+      APInt InDemandedBits(APInt::getAllOnesValue(BitWidth).lshr(NLZ));
+
+      // Find information about known zero/one bits in the input.
+      if (SimplifyDemandedBits(I->getOperand(0), InDemandedBits, 
+                               LHSKnownZero, LHSKnownOne, Depth+1))
+        return true;
+
+      // If the RHS of the add has bits set that can't affect the input, reduce
+      // the constant.
+      if (ShrinkDemandedConstant(I, 1, InDemandedBits))
+        return UpdateValueUsesWith(I, I);
+      
+      // Avoid excess work.
+      if (LHSKnownZero == 0 && LHSKnownOne == 0)
+        break;
+      
+      // Turn it into OR if input bits are zero.
+      if ((LHSKnownZero & RHS->getValue()) == RHS->getValue()) {
+        Instruction *Or =
+          BinaryOperator::createOr(I->getOperand(0), I->getOperand(1),
+                                   I->getName());
+        InsertNewInstBefore(Or, *I);
+        return UpdateValueUsesWith(I, Or);
+      }
+      
+      // We can say something about the output known-zero and known-one bits,
+      // depending on potential carries from the input constant and the
+      // unknowns.  For example if the LHS is known to have at most the 0x0F0F0
+      // bits set and the RHS constant is 0x01001, then we know we have a known
+      // one mask of 0x00001 and a known zero mask of 0xE0F0E.
+      
+      // To compute this, we first compute the potential carry bits.  These are
+      // the bits which may be modified.  I'm not aware of a better way to do
+      // this scan.
+      APInt RHSVal(RHS->getValue());
+      
+      bool CarryIn = false;
+      APInt CarryBits(BitWidth, 0);
+      const uint64_t *LHSKnownZeroRawVal = LHSKnownZero.getRawData(),
+                     *RHSRawVal = RHSVal.getRawData();
+      for (uint32_t i = 0; i != RHSVal.getNumWords(); ++i) {
+        uint64_t AddVal = ~LHSKnownZeroRawVal[i] + RHSRawVal[i],
+                 XorVal = ~LHSKnownZeroRawVal[i] ^ RHSRawVal[i];
+        uint64_t WordCarryBits = AddVal ^ XorVal + CarryIn;
+        if (AddVal < RHSRawVal[i])
+          CarryIn = true;
+        else
+          CarryIn = false;
+        CarryBits.setWordToValue(i, WordCarryBits);
+      }
+      
+      // Now that we know which bits have carries, compute the known-1/0 sets.
+      
+      // Bits are known one if they are known zero in one operand and one in the
+      // other, and there is no input carry.
+      RHSKnownOne = ((LHSKnownZero & RHSVal) | 
+                     (LHSKnownOne & ~RHSVal)) & ~CarryBits;
+      
+      // Bits are known zero if they are known zero in both operands and there
+      // is no input carry.
+      RHSKnownZero = LHSKnownZero & ~RHSVal & ~CarryBits;
+    } else {
+      // If the high-bits of this ADD are not demanded, then it does not demand
+      // the high bits of its LHS or RHS.
+      if ((DemandedMask & APInt::getSignBit(BitWidth)) == 0) {
+        // Right fill the mask of bits for this ADD to demand the most
+        // significant bit and all those below it.
+        APInt DemandedFromOps = APInt::getAllOnesValue(BitWidth).lshr(NLZ);
+        if (SimplifyDemandedBits(I->getOperand(0), DemandedFromOps,
+                                 LHSKnownZero, LHSKnownOne, Depth+1))
+          return true;
+        if (SimplifyDemandedBits(I->getOperand(1), DemandedFromOps,
+                                 LHSKnownZero, LHSKnownOne, Depth+1))
+          return true;
+      }
+    }
+    break;
+  }
+  case Instruction::Sub:
+    // If the high-bits of this SUB are not demanded, then it does not demand
+    // the high bits of its LHS or RHS.
+    if ((DemandedMask & APInt::getSignBit(BitWidth)) == 0) {
+      // Right fill the mask of bits for this SUB to demand the most
+      // significant bit and all those below it.
+      unsigned NLZ = DemandedMask.countLeadingZeros();
+      APInt DemandedFromOps(APInt::getAllOnesValue(BitWidth).lshr(NLZ));
+      if (SimplifyDemandedBits(I->getOperand(0), DemandedFromOps,
+                               LHSKnownZero, LHSKnownOne, Depth+1))
+        return true;
+      if (SimplifyDemandedBits(I->getOperand(1), DemandedFromOps,
+                               LHSKnownZero, LHSKnownOne, Depth+1))
+        return true;
+    }
+    break;
+  case Instruction::Shl:
+    if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
+      uint64_t ShiftAmt = SA->getZExtValue();
+      if (SimplifyDemandedBits(I->getOperand(0), DemandedMask.lshr(ShiftAmt), 
+                               RHSKnownZero, RHSKnownOne, Depth+1))
+        return true;
+      assert((RHSKnownZero & RHSKnownOne) == 0 && 
+             "Bits known to be one AND zero?"); 
+      RHSKnownZero <<= ShiftAmt;
+      RHSKnownOne  <<= ShiftAmt;
+      // low bits known zero.
+      RHSKnownZero |= APInt::getAllOnesValue(ShiftAmt).zext(BitWidth);
+    }
+    break;
+  case Instruction::LShr:
+    // For a logical shift right
+    if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
+      unsigned ShiftAmt = SA->getZExtValue();
+      
+      APInt TypeMask(APInt::getAllOnesValue(BitWidth));
+      // Unsigned shift right.
+      if (SimplifyDemandedBits(I->getOperand(0),
+                              (DemandedMask.shl(ShiftAmt)) & TypeMask,
+                               RHSKnownZero, RHSKnownOne, Depth+1))
+        return true;
+      assert((RHSKnownZero & RHSKnownOne) == 0 && 
+             "Bits known to be one AND zero?"); 
+      // Compute the new bits that are at the top now.
+      APInt HighBits(APInt::getAllOnesValue(ShiftAmt).zext(BitWidth).shl(
+              BitWidth - ShiftAmt));
+      RHSKnownZero &= TypeMask;
+      RHSKnownOne  &= TypeMask;
+      RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt);
+      RHSKnownOne  = APIntOps::lshr(RHSKnownOne, ShiftAmt);
+      RHSKnownZero |= HighBits;  // high bits known zero.
+    }
+    break;
+  case Instruction::AShr:
+    // If this is an arithmetic shift right and only the low-bit is set, we can
+    // always convert this into a logical shr, even if the shift amount is
+    // variable.  The low bit of the shift cannot be an input sign bit unless
+    // the shift amount is >= the size of the datatype, which is undefined.
+    if (DemandedMask == 1) {
+      // Perform the logical shift right.
+      Value *NewVal = BinaryOperator::createLShr(
+                        I->getOperand(0), I->getOperand(1), I->getName());
+      InsertNewInstBefore(cast<Instruction>(NewVal), *I);
+      return UpdateValueUsesWith(I, NewVal);
+    }    
+    
+    if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
+      unsigned ShiftAmt = SA->getZExtValue();
+      
+      APInt TypeMask(APInt::getAllOnesValue(BitWidth));
+      // Signed shift right.
+      if (SimplifyDemandedBits(I->getOperand(0),
+                               (DemandedMask.shl(ShiftAmt)) & TypeMask,
+                               RHSKnownZero, RHSKnownOne, Depth+1))
+        return true;
+      assert((RHSKnownZero & RHSKnownOne) == 0 && 
+             "Bits known to be one AND zero?"); 
+      // Compute the new bits that are at the top now.
+      APInt HighBits(APInt::getAllOnesValue(ShiftAmt).zext(BitWidth).shl(
+              BitWidth - ShiftAmt));
+      RHSKnownZero &= TypeMask;
+      RHSKnownOne  &= TypeMask;
+      RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt);
+      RHSKnownOne  = APIntOps::lshr(RHSKnownOne, ShiftAmt);
+        
+      // Handle the sign bits.
+      APInt SignBit(APInt::getSignBit(BitWidth));
+      // Adjust to where it is now in the mask.
+      SignBit = APIntOps::lshr(SignBit, ShiftAmt);  
+        
+      // If the input sign bit is known to be zero, or if none of the top bits
+      // are demanded, turn this into an unsigned shift right.
+      if ((RHSKnownZero & SignBit) != 0 || 
+          (HighBits & ~DemandedMask) == HighBits) {
+        // Perform the logical shift right.
+        Value *NewVal = BinaryOperator::createLShr(
+                          I->getOperand(0), SA, I->getName());
+        InsertNewInstBefore(cast<Instruction>(NewVal), *I);
+        return UpdateValueUsesWith(I, NewVal);
+      } else if ((RHSKnownOne & SignBit) != 0) { // New bits are known one.
+        RHSKnownOne |= HighBits;
+      }
+    }
+    break;
+  }
+  
+  // If the client is only demanding bits that we know, return the known
+  // constant.
+  if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask)
+    return UpdateValueUsesWith(I, ConstantInt::get(RHSKnownOne));
+  return false;
+}
+
 
 /// SimplifyDemandedVectorElts - The specified value producecs a vector with
 /// 64 or fewer elements.  DemandedElts contains the set of elements that are






More information about the llvm-commits mailing list