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

Chris Lattner lattner at cs.uiuc.edu
Sat Apr 23 23:59:22 PDT 2005



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.326 -> 1.327
---
Log message:

Use getPrimitiveSizeInBits() instead of getPrimitiveSize()*8

Completely rework the 'setcc (cast x to larger), y' code.  This code has
the advantage of implementing setcc.ll:test19 (being more general than
the previous code) and being correct in all cases.

This allows us to unxfail 2004-11-27-SetCCForCastLargerAndConstant.ll,
and close PR454: http://llvm.cs.uiuc.edu/PR454 .


---
Diffs of the changes:  (+162 -172)

 InstructionCombining.cpp |  334 ++++++++++++++++++++++-------------------------
 1 files changed, 162 insertions(+), 172 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.326 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.327
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.326	Sat Apr 23 16:38:35 2005
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Sun Apr 24 01:59:08 2005
@@ -112,10 +112,9 @@
     Instruction *visitAnd(BinaryOperator &I);
     Instruction *visitOr (BinaryOperator &I);
     Instruction *visitXor(BinaryOperator &I);
-    Instruction *visitSetCondInst(BinaryOperator &I);
-    Instruction *visitSetCondInstWithCastAndConstant(BinaryOperator&I,
-                                                     CastInst*LHSI,
-                                                     ConstantInt* CI);
+    Instruction *visitSetCondInst(SetCondInst &I);
+    Instruction *visitSetCondInstWithCastAndCast(SetCondInst &SCI);
+
     Instruction *FoldGEPSetCC(User *GEPLHS, Value *RHS,
                               Instruction::BinaryOps Cond, Instruction &I);
     Instruction *visitShiftInst(ShiftInst &I);
@@ -618,7 +617,7 @@
 
     // X + (signbit) --> X ^ signbit
     if (ConstantInt *CI = dyn_cast<ConstantInt>(RHSC)) {
-      unsigned NumBits = CI->getType()->getPrimitiveSize()*8;
+      unsigned NumBits = CI->getType()->getPrimitiveSizeInBits();
       uint64_t Val = CI->getRawValue() & (1ULL << NumBits)-1;
       if (Val == (1ULL << (NumBits-1)))
         return BinaryOperator::createXor(LHS, RHS);
@@ -692,7 +691,7 @@
 
         // Form a mask of all bits from the lowest bit added through the top.
         uint64_t AddRHSHighBits = ~((AddRHSV & -AddRHSV)-1);
-        AddRHSHighBits &= (1ULL << C2->getType()->getPrimitiveSize()*8)-1;
+        AddRHSHighBits &= (1ULL << C2->getType()->getPrimitiveSizeInBits())-1;
 
         // See if the and mask includes all of these bits.
         uint64_t AddRHSHighBitsAnd = AddRHSHighBits & C2->getRawValue();
@@ -718,14 +717,10 @@
 // isSignBit - Return true if the value represented by the constant only has the
 // highest order bit set.
 static bool isSignBit(ConstantInt *CI) {
-  unsigned NumBits = CI->getType()->getPrimitiveSize()*8;
+  unsigned NumBits = CI->getType()->getPrimitiveSizeInBits();
   return (CI->getRawValue() & ~(-1LL << NumBits)) == (1ULL << (NumBits-1));
 }
 
-static unsigned getTypeSizeInBits(const Type *Ty) {
-  return Ty == Type::BoolTy ? 1 : Ty->getPrimitiveSize()*8;
-}
-
 /// RemoveNoopCast - Strip off nonconverting casts from the value.
 ///
 static Value *RemoveNoopCast(Value *V) {
@@ -733,7 +728,7 @@
     const Type *CTy = CI->getType();
     const Type *OpTy = CI->getOperand(0)->getType();
     if (CTy->isInteger() && OpTy->isInteger()) {
-      if (CTy->getPrimitiveSize() == OpTy->getPrimitiveSize())
+      if (CTy->getPrimitiveSizeInBits() == OpTy->getPrimitiveSizeInBits())
         return RemoveNoopCast(CI->getOperand(0));
     } else if (isa<PointerType>(CTy) && isa<PointerType>(OpTy))
       return RemoveNoopCast(CI->getOperand(0));
@@ -779,7 +774,7 @@
             else
               NewTy = SI->getType()->getSignedVersion();
             // Check to see if we are shifting out everything but the sign bit.
-            if (CU->getValue() == SI->getType()->getPrimitiveSize()*8-1) {
+            if (CU->getValue() == SI->getType()->getPrimitiveSizeInBits()-1) {
               // Ok, the transformation is safe.  Insert a cast of the incoming
               // value, then the new shift, then the new cast.
               Instruction *FirstCast = new CastInst(SI->getOperand(0), NewTy,
@@ -904,10 +899,11 @@
     // True if source is LHS > 127 or LHS >= 128, where the constants depend on
     // the size of the integer type.
     if (Opcode == Instruction::SetGE)
-      return RHSC->getValue() == 1ULL<<(RHS->getType()->getPrimitiveSize()*8-1);
+      return RHSC->getValue() ==
+        1ULL << (RHS->getType()->getPrimitiveSizeInBits()-1);
     if (Opcode == Instruction::SetGT)
       return RHSC->getValue() ==
-        (1ULL << (RHS->getType()->getPrimitiveSize()*8-1))-1;
+        (1ULL << (RHS->getType()->getPrimitiveSizeInBits()-1))-1;
   }
   return false;
 }
@@ -988,7 +984,7 @@
           isSignBitCheck(SCI->getOpcode(), SCIOp0, cast<ConstantInt>(SCIOp1))) {
         // Shift the X value right to turn it into "all signbits".
         Constant *Amt = ConstantUInt::get(Type::UByteTy,
-                                          SCOpTy->getPrimitiveSize()*8-1);
+                                          SCOpTy->getPrimitiveSizeInBits()-1);
         if (SCIOp0->getType()->isUnsigned()) {
           const Type *NewTy = SCIOp0->getType()->getSignedVersion();
           SCIOp0 = InsertNewInstBefore(new CastInst(SCIOp0, NewTy,
@@ -1175,7 +1171,7 @@
 static bool isMaxValueMinusOne(const ConstantInt *C) {
   if (const ConstantUInt *CU = dyn_cast<ConstantUInt>(C)) {
     // Calculate -1 casted to the right type...
-    unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
+    unsigned TypeBits = C->getType()->getPrimitiveSizeInBits();
     uint64_t Val = ~0ULL;                // All ones
     Val >>= 64-TypeBits;                 // Shift out unwanted 1 bits...
     return CU->getValue() == Val-1;
@@ -1184,7 +1180,7 @@
   const ConstantSInt *CS = cast<ConstantSInt>(C);
 
   // Calculate 0111111111..11111
-  unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
+  unsigned TypeBits = C->getType()->getPrimitiveSizeInBits();
   int64_t Val = INT64_MAX;             // All ones
   Val >>= 64-TypeBits;                 // Shift out unwanted 1 bits...
   return CS->getValue() == Val-1;
@@ -1198,7 +1194,7 @@
   const ConstantSInt *CS = cast<ConstantSInt>(C);
 
   // Calculate 1111111111000000000000
-  unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
+  unsigned TypeBits = C->getType()->getPrimitiveSizeInBits();
   int64_t Val = -1;                    // All ones
   Val <<= TypeBits-1;                  // Shift over to the right spot
   return CS->getValue() == Val+1;
@@ -1431,7 +1427,7 @@
       uint64_t AndRHSV = cast<ConstantInt>(AndRHS)->getRawValue();
 
       // Clear bits that are not part of the constant.
-      AndRHSV &= (1ULL << AndRHS->getType()->getPrimitiveSize()*8)-1;
+      AndRHSV &= (1ULL << AndRHS->getType()->getPrimitiveSizeInBits())-1;
 
       // If there is only one bit set...
       if (isOneBitSet(cast<ConstantInt>(AndRHS))) {
@@ -1647,7 +1643,8 @@
 
       // If this is an integer sign or zero extension instruction.
       if (SrcTy->isIntegral() &&
-          SrcTy->getPrimitiveSize() < CI->getType()->getPrimitiveSize()) {
+          SrcTy->getPrimitiveSizeInBits() <
+          CI->getType()->getPrimitiveSizeInBits()) {
 
         if (SrcTy->isUnsigned()) {
           // See if this and is clearing out bits that are known to be zero
@@ -2312,8 +2309,8 @@
       unsigned DiffOperand = 0;     // The operand that differs.
       for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
         if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) {
-          if (GEPLHS->getOperand(i)->getType()->getPrimitiveSize() !=
-                     GEPRHS->getOperand(i)->getType()->getPrimitiveSize()) {
+          if (GEPLHS->getOperand(i)->getType()->getPrimitiveSizeInBits() !=
+                   GEPRHS->getOperand(i)->getType()->getPrimitiveSizeInBits()) {
             // Irreconcilable differences.
             NumDifferences = 2;
             break;
@@ -2350,7 +2347,7 @@
 }
 
 
-Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
+Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
   bool Changed = SimplifyCommutative(I);
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
   const Type *Ty = Op0->getType();
@@ -2473,7 +2470,7 @@
               // To test for the bad case of the signed shr, see if any
               // of the bits shifted in could be tested after the mask.
               Constant *OShAmt = ConstantUInt::get(Type::UByteTy,
-                                   Ty->getPrimitiveSize()*8-ShAmt->getValue());
+                               Ty->getPrimitiveSizeInBits()-ShAmt->getValue());
               Constant *ShVal =
                 ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), OShAmt);
               if (ConstantExpr::getAnd(ShVal, AndCST)->isNullValue())
@@ -2515,13 +2512,6 @@
         }
         break;
 
-      // (setcc (cast X to larger), CI)
-      case Instruction::Cast:
-        if (Instruction *R =
-                visitSetCondInstWithCastAndConstant(I,cast<CastInst>(LHSI),CI))
-          return R;
-        break;
-
       case Instruction::Shl:         // (setcc (shl X, ShAmt), CI)
         if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
           switch (I.getOpcode()) {
@@ -2541,7 +2531,7 @@
             if (LHSI->hasOneUse()) {
               // Otherwise strength reduce the shift into an and.
               unsigned ShAmtVal = (unsigned)ShAmt->getValue();
-              unsigned TypeBits = CI->getType()->getPrimitiveSize()*8;
+              unsigned TypeBits = CI->getType()->getPrimitiveSizeInBits();
               uint64_t Val = (1ULL << (TypeBits-ShAmtVal))-1;
 
               Constant *Mask;
@@ -2591,7 +2581,7 @@
 
               Constant *Mask;
               if (CI->getType()->isUnsigned()) {
-                unsigned TypeBits = CI->getType()->getPrimitiveSize()*8;
+                unsigned TypeBits = CI->getType()->getPrimitiveSizeInBits();
                 if (TypeBits != 64)
                   Val &= (1ULL << TypeBits)-1;
                 Mask = ConstantUInt::get(CI->getType(), Val);
@@ -2831,9 +2821,9 @@
       if (CastInst *Cast = dyn_cast<CastInst>(Op0)) {
         Value *CastOp = Cast->getOperand(0);
         const Type *SrcTy = CastOp->getType();
-        unsigned SrcTySize = SrcTy->getPrimitiveSize();
+        unsigned SrcTySize = SrcTy->getPrimitiveSizeInBits();
         if (SrcTy != Cast->getType() && SrcTy->isInteger() &&
-            SrcTySize == Cast->getType()->getPrimitiveSize()) {
+            SrcTySize == Cast->getType()->getPrimitiveSizeInBits()) {
           assert((SrcTy->isSigned() ^ Cast->getType()->isSigned()) &&
                  "Source and destination signednesses should differ!");
           if (Cast->getType()->isSigned()) {
@@ -2842,21 +2832,21 @@
             if (I.getOpcode() == Instruction::SetLT && CI->isNullValue())
               // X < 0  => x > 127
               return BinaryOperator::createSetGT(CastOp,
-                         ConstantUInt::get(SrcTy, (1ULL << (SrcTySize*8-1))-1));
+                         ConstantUInt::get(SrcTy, (1ULL << (SrcTySize-1))-1));
             else if (I.getOpcode() == Instruction::SetGT &&
                      cast<ConstantSInt>(CI)->getValue() == -1)
               // X > -1  => x < 128
               return BinaryOperator::createSetLT(CastOp,
-                         ConstantUInt::get(SrcTy, 1ULL << (SrcTySize*8-1)));
+                         ConstantUInt::get(SrcTy, 1ULL << (SrcTySize-1)));
           } else {
             ConstantUInt *CUI = cast<ConstantUInt>(CI);
             if (I.getOpcode() == Instruction::SetLT &&
-                CUI->getValue() == 1ULL << (SrcTySize*8-1))
+                CUI->getValue() == 1ULL << (SrcTySize-1))
               // X < 128 => X > -1
               return BinaryOperator::createSetGT(CastOp,
                                                  ConstantSInt::get(SrcTy, -1));
             else if (I.getOpcode() == Instruction::SetGT &&
-                     CUI->getValue() == (1ULL << (SrcTySize*8-1))-1)
+                     CUI->getValue() == (1ULL << (SrcTySize-1))-1)
               // X > 127 => X < 0
               return BinaryOperator::createSetLT(CastOp,
                                                  Constant::getNullValue(SrcTy));
@@ -2948,131 +2938,129 @@
     //   int X = A < B;
     //   if (X) ...
     // For generality, we handle any zero-extension of any operand comparison
-    // with a constant.
-    if (ConstantInt *ConstantRHS = dyn_cast<ConstantInt>(Op1)) {
-      const Type *SrcTy = CastOp0->getType();
-      const Type *DestTy = Op0->getType();
-      if (SrcTy->getPrimitiveSize() < DestTy->getPrimitiveSize() &&
-          (SrcTy->isUnsigned() || SrcTy == Type::BoolTy)) {
-        // Ok, we have an expansion of operand 0 into a new type.  Get the
-        // constant value, masink off bits which are not set in the RHS.  These
-        // could be set if the destination value is signed.
-        uint64_t ConstVal = ConstantRHS->getRawValue();
-        ConstVal &= (1ULL << DestTy->getPrimitiveSize()*8)-1;
-
-        // If the constant we are comparing it with has high bits set, which
-        // don't exist in the original value, the values could never be equal,
-        // because the source would be zero extended.
-        unsigned SrcBits =
-          SrcTy == Type::BoolTy ? 1 : SrcTy->getPrimitiveSize()*8;
-        bool HasSignBit = ConstVal & (1ULL << (DestTy->getPrimitiveSize()*8-1));
-        if (ConstVal & ~((1ULL << SrcBits)-1)) {
-          switch (I.getOpcode()) {
-          default: assert(0 && "Unknown comparison type!");
-          case Instruction::SetEQ:
-            return ReplaceInstUsesWith(I, ConstantBool::False);
-          case Instruction::SetNE:
-            return ReplaceInstUsesWith(I, ConstantBool::True);
-          case Instruction::SetLT:
-          case Instruction::SetLE:
-            if (DestTy->isSigned() && HasSignBit)
-              return ReplaceInstUsesWith(I, ConstantBool::False);
-            return ReplaceInstUsesWith(I, ConstantBool::True);
-          case Instruction::SetGT:
-          case Instruction::SetGE:
-            if (DestTy->isSigned() && HasSignBit)
-              return ReplaceInstUsesWith(I, ConstantBool::True);
-            return ReplaceInstUsesWith(I, ConstantBool::False);
-          }
-        }
-
-        // Otherwise, we can replace the setcc with a setcc of the smaller
-        // operand value.
-        Op1 = ConstantExpr::getCast(cast<Constant>(Op1), SrcTy);
-        return BinaryOperator::create(I.getOpcode(), CastOp0, Op1);
-      }
-    }
+    // with a constant or another cast from the same type.
+    if (isa<ConstantInt>(Op1) || isa<CastInst>(Op1))
+      if (Instruction *R = visitSetCondInstWithCastAndCast(I))
+        return R;
   }
   return Changed ? &I : 0;
 }
 
-// visitSetCondInstWithCastAndConstant - this method is part of the
-// visitSetCondInst method. It handles the situation where we have:
-//   (setcc (cast X to larger), CI)
-// It tries to remove the cast and even the setcc if the CI value
-// and range of the cast allow it.
-Instruction *
-InstCombiner::visitSetCondInstWithCastAndConstant(BinaryOperator&I,
-                                                  CastInst* LHSI,
-                                                  ConstantInt* CI) {
-  const Type *SrcTy = LHSI->getOperand(0)->getType();
-  const Type *DestTy = LHSI->getType();
-  if (!SrcTy->isIntegral() || !DestTy->isIntegral())
+// visitSetCondInstWithCastAndCast - Handle setcond (cast x to y), (cast/cst).
+// We only handle extending casts so far.
+//
+Instruction *InstCombiner::visitSetCondInstWithCastAndCast(SetCondInst &SCI) {
+  Value *LHSCIOp = cast<CastInst>(SCI.getOperand(0))->getOperand(0);
+  const Type *SrcTy = LHSCIOp->getType();
+  const Type *DestTy = SCI.getOperand(0)->getType();
+  Value *RHSCIOp;
+
+  if (!DestTy->isIntegral() || !SrcTy->isIntegral())
     return 0;
 
-  unsigned SrcBits = SrcTy->getPrimitiveSize()*8;
-  unsigned DestBits = DestTy->getPrimitiveSize()*8;
-  if (SrcTy == Type::BoolTy)
-    SrcBits = 1;
-  if (DestTy == Type::BoolTy)
-    DestBits = 1;
-  if (SrcBits < DestBits) {
-    // There are fewer bits in the source of the cast than in the result
-    // of the cast. Any other case doesn't matter because the constant
-    // value won't have changed due to sign extension.
-    Constant *NewCst = ConstantExpr::getCast(CI, SrcTy);
-    if (ConstantExpr::getCast(NewCst, DestTy) == CI) {
-      // The constant value operand of the setCC before and after a
-      // cast to the source type of the cast instruction is the same
-      // value, so we just replace with the same setcc opcode, but
-      // using the source value compared to the constant casted to the
-      // source type.
-      if (SrcTy->isSigned() && DestTy->isUnsigned()) {
-        CastInst* Cst = new CastInst(LHSI->getOperand(0),
-                                     SrcTy->getUnsignedVersion(),
-                                     LHSI->getName());
-        InsertNewInstBefore(Cst,I);
-        return new SetCondInst(I.getOpcode(), Cst,
-                               ConstantExpr::getCast(CI,
-                                                 SrcTy->getUnsignedVersion()));
-      }
-      return new SetCondInst(I.getOpcode(), LHSI->getOperand(0),NewCst);
-    }
-
-    // The constant value before and after a cast to the source type
-    // is different, so various cases are possible depending on the
-    // opcode and the signs of the types involved in the cast.
-    switch (I.getOpcode()) {
-    case Instruction::SetLT: {
-      return 0;
-      Constant* Max = ConstantIntegral::getMaxValue(SrcTy);
-      Max = ConstantExpr::getCast(Max, DestTy);
-      return ReplaceInstUsesWith(I, ConstantExpr::getSetLT(Max, CI));
-    }
-    case Instruction::SetGT: {
-      return 0; // FIXME! RENABLE.  This breaks for (cast sbyte to uint) > 255
-      Constant* Min = ConstantIntegral::getMinValue(SrcTy);
-      Min = ConstantExpr::getCast(Min, DestTy);
-      return ReplaceInstUsesWith(I, ConstantExpr::getSetGT(Min, CI));
-    }
-    case Instruction::SetEQ:
-      // We're looking for equality, and we know the values are not
-      // equal so replace with constant False.
-      return ReplaceInstUsesWith(I, ConstantBool::False);
-    case Instruction::SetNE:
-      // We're testing for inequality, and we know the values are not
-      // equal so replace with constant True.
-      return ReplaceInstUsesWith(I, ConstantBool::True);
-    case Instruction::SetLE:
-    case Instruction::SetGE:
-      assert(0 && "SetLE and SetGE should be handled elsewhere");
-    default:
-      assert(0 && "unknown integer comparison");
+  unsigned SrcBits  = SrcTy->getPrimitiveSizeInBits();
+  unsigned DestBits = DestTy->getPrimitiveSizeInBits();
+  if (SrcBits >= DestBits) return 0;  // Only handle extending cast.
+
+  // Is this a sign or zero extension?
+  bool isSignSrc  = SrcTy->isSigned();
+  bool isSignDest = DestTy->isSigned();
+
+  if (CastInst *CI = dyn_cast<CastInst>(SCI.getOperand(1))) {
+    // Not an extension from the same type?
+    RHSCIOp = CI->getOperand(0);
+    if (RHSCIOp->getType() != LHSCIOp->getType()) return 0;
+  } else if (ConstantInt *CI = dyn_cast<ConstantInt>(SCI.getOperand(1))) {
+    // Compute the constant that would happen if we truncated to SrcTy then
+    // reextended to DestTy.
+    Constant *Res = ConstantExpr::getCast(CI, SrcTy);
+
+    if (ConstantExpr::getCast(Res, DestTy) == CI) {
+      RHSCIOp = Res;
+    } else {
+      // If the value cannot be represented in the shorter type, we cannot emit
+      // a simple comparison.
+      if (SCI.getOpcode() == Instruction::SetEQ)
+        return ReplaceInstUsesWith(SCI, ConstantBool::False);
+      if (SCI.getOpcode() == Instruction::SetNE)
+        return ReplaceInstUsesWith(SCI, ConstantBool::True);
+
+      // SignBitSet - True if the top bit of the compared constant value is set.
+      bool SignBitSet = CI->getRawValue() & 1ULL << (DestBits-1);
+
+      // Evaluate the comparison for LT.
+      Value *Result;
+      if (DestTy->isSigned()) {
+        // We're performing a signed comparison.
+        if (isSignSrc) {
+          // Signed extend and signed comparison.
+          if (cast<ConstantSInt>(CI)->getValue() < 0) // X < (small) --> false
+            Result = ConstantBool::False;
+          else
+            Result = ConstantBool::True;              // X < (large) --> true
+        } else {
+          // Unsigned extend and signed comparison.
+          if (cast<ConstantSInt>(CI)->getValue() < 0)
+            Result = ConstantBool::False;
+          else
+            Result = ConstantBool::True;
+        }
+      } else {
+        // We're performing an unsigned comparison.
+        if (!isSignSrc) {
+          // Unsigned extend & compare -> always true.
+          Result = ConstantBool::True;
+        } else {
+          // We're performing an unsigned comp with a sign extended value.
+          // This is true if the input is >= 0. [aka >s -1]
+          Constant *NegOne = ConstantIntegral::getAllOnesValue(SrcTy);
+          Result = InsertNewInstBefore(BinaryOperator::createSetGT(LHSCIOp,
+                                                  NegOne, SCI.getName()), SCI);
+        }
+      }
+
+      // Finally, return the value computed.    
+      if (SCI.getOpcode() == Instruction::SetLT) {
+        return ReplaceInstUsesWith(SCI, Result);
+      } else {
+        assert(SCI.getOpcode()==Instruction::SetGT &&"SetCC should be folded!");
+        if (Constant *CI = dyn_cast<Constant>(Result))
+          return ReplaceInstUsesWith(SCI, ConstantExpr::getNot(CI));
+        else
+          return BinaryOperator::createNot(Result);
+      }
     }
+  } else {
+    return 0;
+  }
+
+  // Okay, we have the two reduced sized operands.  If we are doing a <,>
+  // comparison, make sure we perform the compare with the same signedness as
+  // the DestTy.  We don't have to do this if the comparison is !=/== or if the
+  // source is a bool.
+  if (isSignSrc != isSignDest && SrcTy != Type::BoolTy &&
+      SCI.getOpcode() != Instruction::SetEQ &&
+      SCI.getOpcode() != Instruction::SetNE) {
+    // Insert noop casts of the two operands to change the sign of the
+    // comparison.
+    const Type *NewSrcTy;
+    if (isSignDest)
+      NewSrcTy = SrcTy->getSignedVersion();
+    else 
+      NewSrcTy = SrcTy->getUnsignedVersion();
+    
+    // Insert the new casts.
+    LHSCIOp = InsertNewInstBefore(new CastInst(LHSCIOp, NewSrcTy,
+                                               LHSCIOp->getName()), SCI);
+    if (Constant *RHSC = dyn_cast<Constant>(RHSCIOp))
+      RHSCIOp = ConstantExpr::getCast(RHSC, NewSrcTy);
+    else
+      RHSCIOp = InsertNewInstBefore(new CastInst(RHSCIOp, NewSrcTy,
+                                                 RHSCIOp->getName()), SCI);
   }
-  return 0;
-}
 
+  return BinaryOperator::create(SCI.getOpcode(), LHSCIOp, RHSCIOp);
+}
 
 Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
   assert(I.getOperand(1)->getType() == Type::UByteTy);
@@ -3114,7 +3102,7 @@
     // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr
     // of a signed value.
     //
-    unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8;
+    unsigned TypeBits = Op0->getType()->getPrimitiveSizeInBits();
     if (CUI->getValue() >= TypeBits) {
       if (!Op0->getType()->isSigned() || isLeftShift)
         return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
@@ -3145,7 +3133,8 @@
       if (CastInst *CI = dyn_cast<CastInst>(Op0)) {
         const Type *SrcTy = CI->getOperand(0)->getType();
         if (isLeftShift && SrcTy->isInteger() && SrcTy->isSigned() &&
-            SrcTy->getPrimitiveSize() < CI->getType()->getPrimitiveSize()) {
+            SrcTy->getPrimitiveSizeInBits() <
+                   CI->getType()->getPrimitiveSizeInBits()) {
           // We can change it to a zero extension if we are shifting out all of
           // the sign extended bits.  To check this, form a mask of all of the
           // sign extend bits, then shift them left and see if we have anything
@@ -3230,8 +3219,8 @@
         // Check for (A << c1) << c2   and   (A >> c1) >> c2
         if (I.getOpcode() == Op0SI->getOpcode()) {
           unsigned Amt = ShiftAmt1+ShiftAmt2;   // Fold into one big shift...
-          if (Op0->getType()->getPrimitiveSize()*8 < Amt)
-            Amt = Op0->getType()->getPrimitiveSize()*8;
+          if (Op0->getType()->getPrimitiveSizeInBits() < Amt)
+            Amt = Op0->getType()->getPrimitiveSizeInBits();
           return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0),
                                ConstantUInt::get(Type::UByteTy, Amt));
         }
@@ -3281,10 +3270,8 @@
 static CastType getCastType(const Type *Src, const Type *Dest) {
   assert(Src->isIntegral() && Dest->isIntegral() &&
          "Only works on integral types!");
-  unsigned SrcSize = Src->getPrimitiveSize()*8;
-  if (Src == Type::BoolTy) SrcSize = 1;
-  unsigned DestSize = Dest->getPrimitiveSize()*8;
-  if (Dest == Type::BoolTy) DestSize = 1;
+  unsigned SrcSize = Src->getPrimitiveSizeInBits();
+  unsigned DestSize = Dest->getPrimitiveSizeInBits();
 
   if (SrcSize == DestSize) return Noop;
   if (SrcSize > DestSize)  return Truncate;
@@ -3412,11 +3399,13 @@
     if (A->getType()->isInteger() &&
         CI.getType()->isInteger() && CSrc->getType()->isInteger() &&
         CSrc->getType()->isUnsigned() &&   // B->A cast must zero extend
-        CSrc->getType()->getPrimitiveSize() < CI.getType()->getPrimitiveSize()&&
-        A->getType()->getPrimitiveSize() == CI.getType()->getPrimitiveSize()) {
+        CSrc->getType()->getPrimitiveSizeInBits() <
+                    CI.getType()->getPrimitiveSizeInBits()&&
+        A->getType()->getPrimitiveSizeInBits() ==
+              CI.getType()->getPrimitiveSizeInBits()) {
       assert(CSrc->getType() != Type::ULongTy &&
              "Cannot have type bigger than ulong!");
-      uint64_t AndValue = (1ULL << CSrc->getType()->getPrimitiveSize()*8)-1;
+      uint64_t AndValue = (1ULL << CSrc->getType()->getPrimitiveSizeInBits())-1;
       Constant *AndOp = ConstantUInt::get(A->getType()->getUnsignedVersion(),
                                           AndValue);
       AndOp = ConstantExpr::getCast(AndOp, A->getType());
@@ -3495,8 +3484,8 @@
     if (SrcI->hasOneUse() && Src->getType()->isIntegral() &&
         CI.getType()->isInteger()) {  // Don't mess with casts to bool here
       const Type *DestTy = CI.getType();
-      unsigned SrcBitSize = getTypeSizeInBits(Src->getType());
-      unsigned DestBitSize = getTypeSizeInBits(DestTy);
+      unsigned SrcBitSize = Src->getType()->getPrimitiveSizeInBits();
+      unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
 
       Value *Op0 = SrcI->getNumOperands() > 0 ? SrcI->getOperand(0) : 0;
       Value *Op1 = SrcI->getNumOperands() > 1 ? SrcI->getOperand(1) : 0;
@@ -4347,11 +4336,12 @@
         const Type *SrcTy = Src->getType();
         const Type *DestTy = CI->getType();
         if (Src->getType()->isInteger()) {
-          if (SrcTy->getPrimitiveSize() == DestTy->getPrimitiveSize()) {
+          if (SrcTy->getPrimitiveSizeInBits() ==
+                       DestTy->getPrimitiveSizeInBits()) {
             // We can always eliminate a cast from ulong or long to the other.
             // We can always eliminate a cast from uint to int or the other on
             // 32-bit pointer platforms.
-            if (DestTy->getPrimitiveSize() >= TD->getPointerSize()) {
+            if (DestTy->getPrimitiveSizeInBits() >= TD->getPointerSizeInBits()){
               MadeChange = true;
               GEP.setOperand(i, Src);
             }
@@ -4361,7 +4351,7 @@
             // eliminate a cast from uint to [u]long iff the target is a 32-bit
             // pointer target.
             if (SrcTy->isSigned() ||
-                SrcTy->getPrimitiveSize() >= TD->getPointerSize()) {
+                SrcTy->getPrimitiveSizeInBits() >= TD->getPointerSizeInBits()) {
               MadeChange = true;
               GEP.setOperand(i, Src);
             }






More information about the llvm-commits mailing list