[llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp ConstantFolding.cpp Constants.cpp Instructions.cpp Type.cpp Verifier.cpp

Reid Spencer reid at x10sys.com
Thu Jan 11 23:06:02 PST 2007



Changes in directory llvm/lib/VMCore:

AsmWriter.cpp updated: 1.249 -> 1.250
ConstantFolding.cpp updated: 1.129 -> 1.130
Constants.cpp updated: 1.197 -> 1.198
Instructions.cpp updated: 1.60 -> 1.61
Type.cpp updated: 1.157 -> 1.158
Verifier.cpp updated: 1.183 -> 1.184
---
Log message:

For PR1064: http://llvm.org/PR1064 :
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8, 
16, 32, and 64 bit integers.  

This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
   bits in an integer. The Type classes SubclassData field is used to
   store the number of bits. This allows 2^23 bits in an integer type. 
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
   64-bit integers. These are replaced with just IntegerType which is not
   a primitive any more. 
3. Adjust the rest of LLVM to account for this change.

Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with 
them in any significant way. Most optimization passes, for example, will 
still only deal with the byte-width integer types.  Future increments
will rectify this situation.



---
Diffs of the changes:  (+199 -128)

 AsmWriter.cpp       |   18 +++++-
 ConstantFolding.cpp |   16 -----
 Constants.cpp       |   95 +++++++++++++++++----------------
 Instructions.cpp    |    8 +-
 Type.cpp            |  149 +++++++++++++++++++++++++++++++++-------------------
 Verifier.cpp        |   41 +++++++++++---
 6 files changed, 199 insertions(+), 128 deletions(-)


Index: llvm/lib/VMCore/AsmWriter.cpp
diff -u llvm/lib/VMCore/AsmWriter.cpp:1.249 llvm/lib/VMCore/AsmWriter.cpp:1.250
--- llvm/lib/VMCore/AsmWriter.cpp:1.249	Thu Jan 11 22:24:46 2007
+++ llvm/lib/VMCore/AsmWriter.cpp	Fri Jan 12 01:05:14 2007
@@ -222,6 +222,7 @@
     const Type *Ty = cast<Type>(TI->second);
     if (!isa<PointerType>(Ty) ||
         !cast<PointerType>(Ty)->getElementType()->isPrimitiveType() ||
+        !cast<PointerType>(Ty)->getElementType()->isIntegral() ||
         isa<OpaqueType>(cast<PointerType>(Ty)->getElementType()))
       TypeNames.insert(std::make_pair(Ty, getLLVMName(TI->first)));
   }
@@ -233,7 +234,7 @@
                          std::vector<const Type *> &TypeStack,
                          std::map<const Type *, std::string> &TypeNames,
                          std::string & Result){
-  if (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty)) {
+  if (Ty->isIntegral() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))) {
     Result += Ty->getDescription();  // Base case
     return;
   }
@@ -265,6 +266,15 @@
   TypeStack.push_back(Ty);    // Recursive case: Add us to the stack..
 
   switch (Ty->getTypeID()) {
+  case Type::IntegerTyID: {
+    unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+    if (BitWidth == 1)
+      Result += "bool";
+    else {
+      Result += "i" + utostr(BitWidth);
+    }
+    break;
+  }
   case Type::FunctionTyID: {
     const FunctionType *FTy = cast<FunctionType>(Ty);
     calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result);
@@ -347,7 +357,7 @@
   // Primitive types always print out their description, regardless of whether
   // they have been named or not.
   //
-  if (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))
+  if (Ty->isIntegral() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty)))
     return Out << Ty->getDescription();
 
   // Check to see if the type is named.
@@ -706,7 +716,9 @@
 /// without considering any symbolic types that we may have equal to it.
 ///
 std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
-  if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
+  if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty))
+    Out << "i" << utostr(ITy->getBitWidth());
+  else if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
     printType(FTy->getReturnType());
     Out << " (";
     unsigned Idx = 1;


Index: llvm/lib/VMCore/ConstantFolding.cpp
diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.129 llvm/lib/VMCore/ConstantFolding.cpp:1.130
--- llvm/lib/VMCore/ConstantFolding.cpp:1.129	Thu Jan 11 22:24:46 2007
+++ llvm/lib/VMCore/ConstantFolding.cpp	Fri Jan 12 01:05:14 2007
@@ -1364,22 +1364,6 @@
       assert(Ty != 0 && "Invalid indices for GEP!");
       return ConstantPointerNull::get(PointerType::get(Ty));
     }
-
-    if (IdxList.size() == 1) {
-      const Type *ElTy = cast<PointerType>(C->getType())->getElementType();
-      if (uint32_t ElSize = ElTy->getPrimitiveSize()) {
-        // gep null, C is equal to C*sizeof(nullty).  If nullty is a known llvm
-        // type, we can statically fold this.
-        Constant *R = ConstantInt::get(Type::Int32Ty, ElSize);
-        // We know R is unsigned, Idx0 is signed because it must be an index
-        // through a sequential type (gep pointer operand) which is always
-        // signed.
-        R = ConstantExpr::getSExtOrBitCast(R, Idx0->getType());
-        R = ConstantExpr::getMul(R, Idx0); // signed multiply
-        // R is a signed integer, C is the GEP pointer so -> IntToPtr
-        return ConstantExpr::getIntToPtr(R, C->getType());
-      }
-    }
   }
 
   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(const_cast<Constant*>(C))) {


Index: llvm/lib/VMCore/Constants.cpp
diff -u llvm/lib/VMCore/Constants.cpp:1.197 llvm/lib/VMCore/Constants.cpp:1.198
--- llvm/lib/VMCore/Constants.cpp:1.197	Thu Jan 11 22:24:46 2007
+++ llvm/lib/VMCore/Constants.cpp	Fri Jan 12 01:05:14 2007
@@ -92,25 +92,32 @@
 // Static constructor to create a '0' constant of arbitrary type...
 Constant *Constant::getNullValue(const Type *Ty) {
   switch (Ty->getTypeID()) {
-  case Type::Int1TyID: {
-    static Constant *NullBool = ConstantInt::get(Type::Int1Ty, false);
-    return NullBool;
-  }
-  case Type::Int8TyID: {
-    static Constant *NullInt8 = ConstantInt::get(Type::Int8Ty, 0);
-    return NullInt8;
-  }
-  case Type::Int16TyID: {
-    static Constant *NullInt16 = ConstantInt::get(Type::Int16Ty, 0);
-    return NullInt16;
-  }
-  case Type::Int32TyID: {
-    static Constant *NullInt32 = ConstantInt::get(Type::Int32Ty, 0);
-    return NullInt32;
-  }
-  case Type::Int64TyID: {
-    static Constant *NullInt64 = ConstantInt::get(Type::Int64Ty, 0);
-    return NullInt64;
+  case Type::IntegerTyID: {
+    const IntegerType *ITy = dyn_cast<IntegerType>(Ty);
+    switch (ITy->getBitWidth()) {
+    case 1: {
+      static Constant *NullBool = ConstantInt::get(Ty, false);
+      return NullBool;
+    } 
+    case 8: {
+      static Constant *NullInt8 = ConstantInt::get(Ty, 0);
+      return NullInt8;
+    } 
+    case 16: {
+      static Constant *NullInt16 = ConstantInt::get(Ty, 0);
+      return NullInt16;
+    } 
+    case 32: {
+      static Constant *NullInt32 = ConstantInt::get(Ty, 0);
+      return NullInt32;
+    } 
+    case 64: {
+      static Constant *NullInt64 = ConstantInt::get(Ty, 0);
+      return NullInt64;
+    }
+    default:
+      return ConstantInt::get(Ty, 0);
+    }
   }
   case Type::FloatTyID: {
     static Constant *NullFloat = ConstantFP::get(Type::FloatTy, 0);
@@ -136,14 +143,12 @@
 
 // Static constructor to create an integral constant with all bits set
 ConstantInt *ConstantInt::getAllOnesValue(const Type *Ty) {
-  switch (Ty->getTypeID()) {
-  case Type::Int1TyID:   return ConstantInt::getTrue();
-  case Type::Int8TyID:
-  case Type::Int16TyID:
-  case Type::Int32TyID:
-  case Type::Int64TyID:   return ConstantInt::get(Ty, int64_t(-1));
-  default: return 0;
-  }
+  if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty))
+    if (ITy->getBitWidth() == 1)
+      return ConstantInt::getTrue();
+    else
+      return ConstantInt::get(Ty, int64_t(-1));
+  return 0;
 }
 
 /// @returns the value for an packed integer constant of the given type that
@@ -549,25 +554,26 @@
 //                      isValueValidForType implementations
 
 bool ConstantInt::isValueValidForType(const Type *Ty, uint64_t Val) {
-  switch (Ty->getTypeID()) {
-  default:              return false; // These can't be represented as integers!
-  case Type::Int1TyID:  return Val == 0 || Val == 1;
-  case Type::Int8TyID:  return Val <= UINT8_MAX;
-  case Type::Int16TyID: return Val <= UINT16_MAX;
-  case Type::Int32TyID: return Val <= UINT32_MAX;
-  case Type::Int64TyID: return true; // always true, has to fit in largest type
-  }
+  unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth(); // assert okay
+  assert(NumBits <= 64 && "Not implemented: integers > 64-bits");
+  if (Ty == Type::Int1Ty)
+    return Val == 0 || Val == 1;
+  if (NumBits == 64)
+    return true; // always true, has to fit in largest type
+  uint64_t Max = (1ll << NumBits) - 1;
+  return Val <= Max;
 }
 
 bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) {
-  switch (Ty->getTypeID()) {
-  default:              return false; // These can't be represented as integers!
-  case Type::Int1TyID:  return (Val == 0 || Val == 1);
-  case Type::Int8TyID:  return (Val >= INT8_MIN && Val <= INT8_MAX);
-  case Type::Int16TyID: return (Val >= INT16_MIN && Val <= UINT16_MAX);
-  case Type::Int32TyID: return (Val >= INT32_MIN && Val <= UINT32_MAX);
-  case Type::Int64TyID: return true; // always true, has to fit in largest type
-  }
+  unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth(); // assert okay
+  assert(NumBits <= 64 && "Not implemented: integers > 64-bits");
+  if (Ty == Type::Int1Ty)
+    return Val == 0 || Val == 1;
+  if (NumBits == 64)
+    return true; // always true, has to fit in largest type
+  int64_t Min = -(1ll << (NumBits-1));
+  int64_t Max = (1ll << (NumBits-1)) - 1;
+  return (Val >= Min && Val <= Max);
 }
 
 bool ConstantFP::isValueValidForType(const Type *Ty, double Val) {
@@ -1441,8 +1447,7 @@
 
 Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
   assert(isa<PointerType>(S->getType()) && "Invalid cast");
-  assert((Ty->isIntegral() || Ty->getTypeID() == Type::PointerTyID) &&
-         "Invalid cast");
+  assert((Ty->isIntegral() || isa<PointerType>(Ty)) && "Invalid cast");
 
   if (Ty->isIntegral())
     return getCast(Instruction::PtrToInt, S, Ty);


Index: llvm/lib/VMCore/Instructions.cpp
diff -u llvm/lib/VMCore/Instructions.cpp:1.60 llvm/lib/VMCore/Instructions.cpp:1.61
--- llvm/lib/VMCore/Instructions.cpp:1.60	Thu Jan 11 12:21:29 2007
+++ llvm/lib/VMCore/Instructions.cpp	Fri Jan 12 01:05:14 2007
@@ -1528,7 +1528,7 @@
                                       const std::string &Name,
                                       BasicBlock *InsertAtEnd) {
   assert(isa<PointerType>(S->getType()) && "Invalid cast");
-  assert((Ty->isIntegral() || Ty->getTypeID() == Type::PointerTyID) &&
+  assert((Ty->isIntegral() || isa<PointerType>(Ty)) &&
          "Invalid cast");
 
   if (Ty->isIntegral())
@@ -1541,7 +1541,7 @@
                                       const std::string &Name, 
                                       Instruction *InsertBefore) {
   assert(isa<PointerType>(S->getType()) && "Invalid cast");
-  assert((Ty->isIntegral() || Ty->getTypeID() == Type::PointerTyID) &&
+  assert((Ty->isIntegral() || isa<PointerType>(Ty)) &&
          "Invalid cast");
 
   if (Ty->isIntegral())
@@ -1913,7 +1913,7 @@
     assert(Op0Ty == Op1Ty &&
            "Both operands to ICmp instruction are not of the same type!");
     // Check that the operands are the right type
-    assert(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID ||
+    assert(Op0Ty->isIntegral() || isa<PointerType>(Op0Ty) ||
            (isa<PackedType>(Op0Ty) && 
             cast<PackedType>(Op0Ty)->getElementType()->isIntegral()) &&
            "Invalid operand types for ICmp instruction");
@@ -1948,7 +1948,7 @@
     assert(Op0Ty == Op1Ty &&
           "Both operands to ICmp instruction are not of the same type!");
     // Check that the operands are the right type
-    assert(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID ||
+    assert(Op0Ty->isIntegral() || isa<PointerType>(Op0Ty) ||
            (isa<PackedType>(Op0Ty) && 
             cast<PackedType>(Op0Ty)->getElementType()->isIntegral()) &&
            "Invalid operand types for ICmp instruction");


Index: llvm/lib/VMCore/Type.cpp
diff -u llvm/lib/VMCore/Type.cpp:1.157 llvm/lib/VMCore/Type.cpp:1.158
--- llvm/lib/VMCore/Type.cpp:1.157	Thu Jan 11 12:21:29 2007
+++ llvm/lib/VMCore/Type.cpp	Fri Jan 12 01:05:14 2007
@@ -64,7 +64,7 @@
                               std::string> > AbstractTypeDescriptions;
 
 Type::Type(const char *Name, TypeID id)
-  : ID(id), Abstract(false),  RefCount(0), ForwardType(0) {
+  : ID(id), Abstract(false),  SubclassData(0), RefCount(0), ForwardType(0) {
   assert(Name && Name[0] && "Should use other ctor if no name!");
   (*ConcreteTypeDescriptions)[this] = Name;
 }
@@ -73,11 +73,6 @@
 const Type *Type::getPrimitiveType(TypeID IDNumber) {
   switch (IDNumber) {
   case VoidTyID  : return VoidTy;
-  case Int1TyID  : return Int1Ty;
-  case Int8TyID  : return Int8Ty; 
-  case Int16TyID : return Int16Ty; 
-  case Int32TyID : return Int32Ty;
-  case Int64TyID : return Int64Ty;
   case FloatTyID : return FloatTy;
   case DoubleTyID: return DoubleTy;
   case LabelTyID : return LabelTy;
@@ -116,41 +111,17 @@
   // At this point we have only various mismatches of the first class types
   // remaining and ptr->ptr. Just select the lossless conversions. Everything
   // else is not lossless.
-  if (getTypeID() == Type::PointerTyID)
+  if (isa<PointerType>(this))
     return isa<PointerType>(Ty);
   return false;  // Other types have no identity values
 }
 
-// getPrimitiveSize - Return the basic size of this type if it is a primitive
-// type.  These are fixed by LLVM and are not target dependent.  This will
-// return zero if the type does not have a size or is not a primitive type.
-//
-unsigned Type::getPrimitiveSize() const {
-  switch (getTypeID()) {
-  case Type::Int1TyID:
-  case Type::Int8TyID:  return 1;
-  case Type::Int16TyID: return 2;
-  case Type::FloatTyID:
-  case Type::Int32TyID: return 4;
-  case Type::Int64TyID:
-  case Type::DoubleTyID: return 8;
-  default: return 0;
-  }
-}
-
 unsigned Type::getPrimitiveSizeInBits() const {
   switch (getTypeID()) {
-  case Type::Int1TyID:  return 1;
-  case Type::Int8TyID:  return 8;
-  case Type::Int16TyID: return 16;
-  case Type::FloatTyID:
-  case Type::Int32TyID:return 32;
-  case Type::Int64TyID:
+  case Type::FloatTyID: return 32;
   case Type::DoubleTyID: return 64;
-  case Type::PackedTyID: {
-    const PackedType *PTy = cast<PackedType>(this);
-    return PTy->getBitWidth();
-  }
+  case Type::IntegerTyID: return cast<IntegerType>(this)->getBitWidth();
+  case Type::PackedTyID:  return cast<PackedType>(this)->getBitWidth();
   default: return 0;
   }
 }
@@ -165,11 +136,13 @@
   if (const PackedType *PTy = dyn_cast<PackedType>(this))
     return PTy->getElementType()->isSized();
 
-  if (!isa<StructType>(this)) return false;
+  if (!isa<StructType>(this)) 
+    return false;
 
   // Okay, our struct is sized if all of the elements are...
   for (subtype_iterator I = subtype_begin(), E = subtype_end(); I != E; ++I)
-    if (!(*I)->isSized()) return false;
+    if (!(*I)->isSized()) 
+      return false;
 
   return true;
 }
@@ -243,6 +216,14 @@
   TypeStack.push_back(Ty);    // Add us to the stack..
 
   switch (Ty->getTypeID()) {
+  case Type::IntegerTyID: {
+    const IntegerType *ITy = cast<IntegerType>(Ty);
+    if (ITy->getBitWidth() == 1)
+      Result = "bool"; // FIXME: eventually this becomes i1
+    else
+      Result = "i" + utostr(ITy->getBitWidth());
+    break;
+  }
   case Type::FunctionTyID: {
     const FunctionType *FTy = cast<FunctionType>(Ty);
     if (!Result.empty())
@@ -267,6 +248,7 @@
     }
     break;
   }
+  case Type::PackedStructTyID:
   case Type::StructTyID: {
     const StructType *STy = cast<StructType>(Ty);
     if (STy->isPacked())
@@ -353,7 +335,6 @@
   return ContainedTys[Idx];
 }
 
-
 //===----------------------------------------------------------------------===//
 //                          Primitive 'Type' data
 //===----------------------------------------------------------------------===//
@@ -365,17 +346,26 @@
     };                                                 \
   }                                                    \
   static ManagedStatic<TY##Type> The##TY##Ty;          \
-  Type *Type::TY##Ty = &*The##TY##Ty
+  const Type *Type::TY##Ty = &*The##TY##Ty
+
+#define DeclareIntegerType(TY, BitWidth)                     \
+  namespace {                                                \
+    struct VISIBILITY_HIDDEN TY##Type : public IntegerType { \
+      TY##Type() : IntegerType(BitWidth) {}                  \
+    };                                                       \
+  }                                                          \
+  static ManagedStatic<TY##Type> The##TY##Ty;                \
+  const Type *Type::TY##Ty = &*The##TY##Ty
 
 DeclarePrimType(Void,   "void");
-DeclarePrimType(Int1,   "bool");
-DeclarePrimType(Int8,   "i8");
-DeclarePrimType(Int16,  "i16");
-DeclarePrimType(Int32,  "i32");
-DeclarePrimType(Int64,  "i64");
 DeclarePrimType(Float,  "float");
 DeclarePrimType(Double, "double");
 DeclarePrimType(Label,  "label");
+DeclareIntegerType(Int1,    1);
+DeclareIntegerType(Int8,    8);
+DeclareIntegerType(Int16,  16);
+DeclareIntegerType(Int32,  32);
+DeclareIntegerType(Int64,  64);
 #undef DeclarePrimType
 
 
@@ -584,7 +574,10 @@
   // algorithm is the fact that arraytypes have sizes that differentiates types,
   // and that function types can be varargs or not.  Consider this now.
   //
-  if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
+  if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty)) {
+    const IntegerType *ITy2 = cast<IntegerType>(Ty2);
+    return ITy->getBitWidth() == ITy2->getBitWidth();
+  } else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
     return TypesEqual(PTy->getElementType(),
                       cast<PointerType>(Ty2)->getElementType(), EqTypes);
   } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
@@ -695,6 +688,9 @@
     switch (SubTy->getTypeID()) {
     default: break;
     case Type::OpaqueTyID: return 0;    // Opaque -> hash = 0 no matter what.
+    case Type::IntegerTyID:
+      HashVal ^= (cast<IntegerType>(SubTy)->getBitWidth() << 3);
+      break;
     case Type::FunctionTyID:
       HashVal ^= cast<FunctionType>(SubTy)->getNumParams()*2 + 
                  cast<FunctionType>(SubTy)->isVarArg();
@@ -928,6 +924,60 @@
 // Function Type Factory and Value Class...
 //
 
+//===----------------------------------------------------------------------===//
+// Integer Type Factory...
+//
+namespace llvm {
+class IntegerValType {
+  uint16_t bits;
+public:
+  IntegerValType(uint16_t numbits) : bits(numbits) {}
+
+  static IntegerValType get(const IntegerType *Ty) {
+    return IntegerValType(Ty->getBitWidth());
+  }
+
+  static unsigned hashTypeStructure(const IntegerType *Ty) {
+    return (unsigned)Ty->getBitWidth();
+  }
+
+  inline bool operator<(const IntegerValType &IVT) const {
+    return bits < IVT.bits;
+  }
+};
+}
+
+static ManagedStatic<TypeMap<IntegerValType, IntegerType> > IntegerTypes;
+
+const IntegerType *IntegerType::get(unsigned NumBits) {
+  assert(NumBits >= MIN_INT_BITS && "bitwidth too small");
+  assert(NumBits <= MAX_INT_BITS && "bitwidth too large");
+
+  // Check for the built-in integer types
+  switch (NumBits) {
+    case  1: return cast<IntegerType>(Type::Int1Ty);
+    case  8: return cast<IntegerType>(Type::Int8Ty);
+    case 16: return cast<IntegerType>(Type::Int16Ty);
+    case 32: return cast<IntegerType>(Type::Int32Ty);
+    case 64: return cast<IntegerType>(Type::Int64Ty);
+    default: 
+      break;
+  }
+
+  IntegerValType IVT(NumBits);
+  IntegerType *ITy = IntegerTypes->get(IVT);
+  if (ITy) return ITy;           // Found a match, return it!
+
+  // Value not found.  Derive a new type!
+  ITy = new IntegerType(NumBits);
+  IntegerTypes->add(IVT, ITy);
+
+#ifdef DEBUG_MERGE_TYPES
+  DOUT << "Derived new type: " << *ITy << "\n";
+#endif
+  return ITy;
+}
+
 // FunctionValType - Define a class to hold the key that goes into the TypeMap
 //
 namespace llvm {
@@ -1440,14 +1490,9 @@
 }
 
 bool SequentialType::indexValid(const Value *V) const {
-  const Type *Ty = V->getType();
-  switch (Ty->getTypeID()) {
-  case Type::Int32TyID:
-  case Type::Int64TyID:
-    return true;
-  default:
-    return false;
-  }
+  if (const IntegerType *IT = dyn_cast<IntegerType>(V->getType())) 
+    return IT->getBitWidth() == 32 || IT->getBitWidth() == 64;
+  return false;
 }
 
 namespace llvm {


Index: llvm/lib/VMCore/Verifier.cpp
diff -u llvm/lib/VMCore/Verifier.cpp:1.183 llvm/lib/VMCore/Verifier.cpp:1.184
--- llvm/lib/VMCore/Verifier.cpp:1.183	Thu Jan 11 12:21:29 2007
+++ llvm/lib/VMCore/Verifier.cpp	Fri Jan 12 01:05:14 2007
@@ -743,7 +743,7 @@
   Assert1(Op0Ty == Op1Ty,
           "Both operands to ICmp instruction are not of the same type!", &IC);
   // Check that the operands are the right type
-  Assert1(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID,
+  Assert1(Op0Ty->isIntegral() || isa<PointerType>(Op0Ty),
           "Invalid operand types for ICmp instruction", &IC);
   visitInstruction(IC);
 }
@@ -1005,7 +1005,7 @@
     else
       Ty = FTy->getParamType(ArgNo-1);
     
-    if (Ty->getTypeID() != TypeID) {
+    if (TypeID != Ty->getTypeID()) {
       if (ArgNo == 0)
         CheckFailed("Intrinsic prototype has incorrect result type!", F);
       else
@@ -1013,18 +1013,43 @@
       break;
     }
 
-    // If this is a packed argument, verify the number and type of elements.
-    if (TypeID == Type::PackedTyID) {
+    if (TypeID == Type::IntegerTyID) {
+      unsigned GotBits = (unsigned) va_arg(VA, int);
+      unsigned ExpectBits = cast<IntegerType>(Ty)->getBitWidth();
+      if (GotBits != ExpectBits) {
+        std::string bitmsg = " Expecting " + utostr(ExpectBits) + " but got " +
+                             utostr(GotBits) + " bits.";
+        if (ArgNo == 0)
+          CheckFailed("Intrinsic prototype has incorrect integer result width!"
+                      + bitmsg, F);
+        else
+          CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " has "
+                      "incorrect integer width!" + bitmsg, F);
+        break;
+      }
+    } else if (TypeID == Type::PackedTyID) {
+      // If this is a packed argument, verify the number and type of elements.
       const PackedType *PTy = cast<PackedType>(Ty);
-      if (va_arg(VA, int) != PTy->getElementType()->getTypeID()) {
-        CheckFailed("Intrinsic prototype has incorrect vector element type!",F);
+      int ElemTy = va_arg(VA, int);
+      if (ElemTy != PTy->getElementType()->getTypeID()) {
+        CheckFailed("Intrinsic prototype has incorrect vector element type!",
+                    F);
         break;
       }
-
+      if (ElemTy == Type::IntegerTyID) {
+        unsigned NumBits = (unsigned)va_arg(VA, int);
+        unsigned ExpectedBits = 
+          cast<IntegerType>(PTy->getElementType())->getBitWidth();
+        if (NumBits != ExpectedBits) {
+          CheckFailed("Intrinsic prototype has incorrect vector element type!",
+                      F);
+          break;
+        }
+      }
       if ((unsigned)va_arg(VA, int) != PTy->getNumElements()) {
         CheckFailed("Intrinsic prototype has incorrect number of "
                     "vector elements!",F);
-        break;
+          break;
       }
     }
   }






More information about the llvm-commits mailing list