Changed llvm_ostream et all to OStream. llvm_cerr, llvm_cout, llvm_null, are
[oota-llvm.git] / lib / VMCore / Constants.cpp
index 2c996f5301f4330f8adfcfc07e378a2e1d2a0624..f9271178a4d139a6a896d6a465db7e8e492d3f58 100644 (file)
 #include "llvm/SymbolTable.h"
 #include "llvm/Module.h"
 #include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MathExtras.h"
 #include <algorithm>
-#include <iostream>
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
@@ -42,9 +42,9 @@ void Constant::destroyConstantImpl() {
     Value *V = use_back();
 #ifndef NDEBUG      // Only in -g mode...
     if (!isa<Constant>(V))
-      std::cerr << "While deleting: " << *this
-                << "\n\nUse still stuck around after Def is destroyed: "
-                << *V << "\n\n";
+      DOUT << "While deleting: " << *this
+           << "\n\nUse still stuck around after Def is destroyed: "
+           << *V << "\n\n";
 #endif
     assert(isa<Constant>(V) && "References remain to Constant being destroyed");
     Constant *CV = cast<Constant>(V);
@@ -78,7 +78,9 @@ bool Constant::canTrap() const {
   case Instruction::UDiv:
   case Instruction::SDiv:
   case Instruction::FDiv:
-  case Instruction::Rem:
+  case Instruction::URem:
+  case Instruction::SRem:
+  case Instruction::FRem:
     // Div and rem can trap if the RHS is not known to be non-zero.
     if (!isa<ConstantInt>(getOperand(1)) || getOperand(1)->isNullValue())
       return true;
@@ -150,53 +152,6 @@ Constant *Constant::getNullValue(const Type *Ty) {
   }
 }
 
-// Static constructor to create the maximum constant of an integral type...
-ConstantIntegral *ConstantIntegral::getMaxValue(const Type *Ty) {
-  switch (Ty->getTypeID()) {
-  case Type::BoolTyID:   return ConstantBool::getTrue();
-  case Type::SByteTyID:
-  case Type::ShortTyID:
-  case Type::IntTyID:
-  case Type::LongTyID: {
-    // Calculate 011111111111111...
-    unsigned TypeBits = Ty->getPrimitiveSize()*8;
-    int64_t Val = INT64_MAX;             // All ones
-    Val >>= 64-TypeBits;                 // Shift out unwanted 1 bits...
-    return ConstantInt::get(Ty, Val);
-  }
-
-  case Type::UByteTyID:
-  case Type::UShortTyID:
-  case Type::UIntTyID:
-  case Type::ULongTyID:  return getAllOnesValue(Ty);
-
-  default: return 0;
-  }
-}
-
-// Static constructor to create the minimum constant for an integral type...
-ConstantIntegral *ConstantIntegral::getMinValue(const Type *Ty) {
-  switch (Ty->getTypeID()) {
-  case Type::BoolTyID:   return ConstantBool::getFalse();
-  case Type::SByteTyID:
-  case Type::ShortTyID:
-  case Type::IntTyID:
-  case Type::LongTyID: {
-     // Calculate 1111111111000000000000
-     unsigned TypeBits = Ty->getPrimitiveSize()*8;
-     int64_t Val = -1;                    // All ones
-     Val <<= TypeBits-1;                  // Shift over to the right spot
-     return ConstantInt::get(Ty, Val);
-  }
-
-  case Type::UByteTyID:
-  case Type::UShortTyID:
-  case Type::UIntTyID:
-  case Type::ULongTyID:  return ConstantInt::get(Ty, 0);
-
-  default: return 0;
-  }
-}
 
 // Static constructor to create an integral constant with all bits set
 ConstantIntegral *ConstantIntegral::getAllOnesValue(const Type *Ty) {
@@ -310,26 +265,27 @@ ConstantPacked::~ConstantPacked() {
   delete [] OperandList;
 }
 
+static bool isSetCC(unsigned Opcode) {
+  return Opcode == Instruction::SetEQ || Opcode == Instruction::SetNE ||
+         Opcode == Instruction::SetLT || Opcode == Instruction::SetGT ||
+         Opcode == Instruction::SetLE || Opcode == Instruction::SetGE;
+}
+
+// We declare several classes private to this file, so use an anonymous
+// namespace
+namespace {
+
 /// UnaryConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement unary constant exprs.
-namespace {
 class VISIBILITY_HIDDEN UnaryConstantExpr : public ConstantExpr {
   Use Op;
 public:
   UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty)
     : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) {}
 };
-}
-
-static bool isSetCC(unsigned Opcode) {
-  return Opcode == Instruction::SetEQ || Opcode == Instruction::SetNE ||
-         Opcode == Instruction::SetLT || Opcode == Instruction::SetGT ||
-         Opcode == Instruction::SetLE || Opcode == Instruction::SetGE;
-}
 
 /// BinaryConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement binary constant exprs.
-namespace {
 class VISIBILITY_HIDDEN BinaryConstantExpr : public ConstantExpr {
   Use Ops[2];
 public:
@@ -340,11 +296,9 @@ public:
     Ops[1].init(C2, this);
   }
 };
-}
 
 /// SelectConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement select constant exprs.
-namespace {
 class VISIBILITY_HIDDEN SelectConstantExpr : public ConstantExpr {
   Use Ops[3];
 public:
@@ -355,12 +309,10 @@ public:
     Ops[2].init(C3, this);
   }
 };
-}
 
 /// ExtractElementConstantExpr - This class is private to
 /// Constants.cpp, and is used behind the scenes to implement
 /// extractelement constant exprs.
-namespace {
 class VISIBILITY_HIDDEN ExtractElementConstantExpr : public ConstantExpr {
   Use Ops[2];
 public:
@@ -371,12 +323,10 @@ public:
     Ops[1].init(C2, this);
   }
 };
-}
 
 /// InsertElementConstantExpr - This class is private to
 /// Constants.cpp, and is used behind the scenes to implement
 /// insertelement constant exprs.
-namespace {
 class VISIBILITY_HIDDEN InsertElementConstantExpr : public ConstantExpr {
   Use Ops[3];
 public:
@@ -388,12 +338,10 @@ public:
     Ops[2].init(C3, this);
   }
 };
-}
 
 /// ShuffleVectorConstantExpr - This class is private to
 /// Constants.cpp, and is used behind the scenes to implement
 /// shufflevector constant exprs.
-namespace {
 class VISIBILITY_HIDDEN ShuffleVectorConstantExpr : public ConstantExpr {
   Use Ops[3];
 public:
@@ -405,11 +353,9 @@ public:
     Ops[2].init(C3, this);
   }
 };
-}
 
 /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
 /// used behind the scenes to implement getelementpr constant exprs.
-namespace {
 struct VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr {
   GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
                             const Type *DestTy)
@@ -423,6 +369,34 @@ struct VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr {
     delete [] OperandList;
   }
 };
+
+// CompareConstantExpr - This class is private to Constants.cpp, and is used
+// behind the scenes to implement ICmp and FCmp constant expressions. This is
+// needed in order to store the predicate value for these instructions.
+struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr {
+  unsigned short predicate;
+  Use Ops[2];
+  CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred, 
+                      Constant* LHS, Constant* RHS)
+    : ConstantExpr(Type::BoolTy, Instruction::OtherOps(opc), Ops, 2),
+      predicate(pred) {
+    OperandList[0].init(LHS, this);
+    OperandList[1].init(RHS, this);
+  }
+};
+
+} // end anonymous namespace
+
+
+// Utility function for determining if a ConstantExpr is a CastOp or not. This
+// can't be inline because we don't want to #include Instruction.h into
+// Constant.h
+bool ConstantExpr::isCast() const {
+  return Instruction::isCast(getOpcode());
+}
+
+bool ConstantExpr::isCompare() const {
+  return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp;
 }
 
 /// ConstantExpr::get* - Return some common constants without having to
@@ -457,8 +431,14 @@ Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2) {
 Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) {
   return get(Instruction::FDiv, C1, C2);
 }
-Constant *ConstantExpr::getRem(Constant *C1, Constant *C2) {
-  return get(Instruction::Rem, C1, C2);
+Constant *ConstantExpr::getURem(Constant *C1, Constant *C2) {
+  return get(Instruction::URem, C1, C2);
+}
+Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2) {
+  return get(Instruction::SRem, C1, C2);
+}
+Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2) {
+  return get(Instruction::FRem, C1, C2);
 }
 Constant *ConstantExpr::getAnd(Constant *C1, Constant *C2) {
   return get(Instruction::And, C1, C2);
@@ -487,29 +467,24 @@ Constant *ConstantExpr::getSetLE(Constant *C1, Constant *C2) {
 Constant *ConstantExpr::getSetGE(Constant *C1, Constant *C2) {
   return get(Instruction::SetGE, C1, C2);
 }
+unsigned ConstantExpr::getPredicate() const {
+  assert(getOpcode() == Instruction::FCmp || getOpcode() == Instruction::ICmp);
+  return dynamic_cast<const CompareConstantExpr*>(this)->predicate;
+}
 Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) {
   return get(Instruction::Shl, C1, C2);
 }
-Constant *ConstantExpr::getShr(Constant *C1, Constant *C2) {
-  return get(Instruction::Shr, C1, C2);
+Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2) {
+  return get(Instruction::LShr, C1, C2);
 }
-
-Constant *ConstantExpr::getUShr(Constant *C1, Constant *C2) {
-  if (C1->getType()->isUnsigned()) return getShr(C1, C2);
-  return getCast(getShr(getCast(C1,
-                    C1->getType()->getUnsignedVersion()), C2), C1->getType());
-}
-
-Constant *ConstantExpr::getSShr(Constant *C1, Constant *C2) {
-  if (C1->getType()->isSigned()) return getShr(C1, C2);
-  return getCast(getShr(getCast(C1,
-                        C1->getType()->getSignedVersion()), C2), C1->getType());
+Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2) {
+  return get(Instruction::AShr, C1, C2);
 }
 
 /// getWithOperandReplaced - Return a constant expression identical to this
 /// one, but with the specified operand set to the specified value.
-Constant *ConstantExpr::getWithOperandReplaced(unsigned OpNo,
-                                               Constant *Op) const {
+Constant *
+ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
   assert(OpNo < getNumOperands() && "Operand num is out of range!");
   assert(Op->getType() == getOperand(OpNo)->getType() &&
          "Replacing operand with value of different type!");
@@ -518,8 +493,19 @@ Constant *ConstantExpr::getWithOperandReplaced(unsigned OpNo,
   
   Constant *Op0, *Op1, *Op2;
   switch (getOpcode()) {
-  case Instruction::Cast:
-    return ConstantExpr::getCast(Op, getType());
+  case Instruction::Trunc:
+  case Instruction::ZExt:
+  case Instruction::SExt:
+  case Instruction::FPTrunc:
+  case Instruction::FPExt:
+  case Instruction::UIToFP:
+  case Instruction::SIToFP:
+  case Instruction::FPToUI:
+  case Instruction::FPToSI:
+  case Instruction::PtrToInt:
+  case Instruction::IntToPtr:
+  case Instruction::BitCast:
+    return ConstantExpr::getCast(getOpcode(), Op, getType());
   case Instruction::Select:
     Op0 = (OpNo == 0) ? Op : getOperand(0);
     Op1 = (OpNo == 1) ? Op : getOperand(1);
@@ -572,8 +558,19 @@ getWithOperands(const std::vector<Constant*> &Ops) const {
     return const_cast<ConstantExpr*>(this);
 
   switch (getOpcode()) {
-  case Instruction::Cast:
-    return ConstantExpr::getCast(Ops[0], getType());
+  case Instruction::Trunc:
+  case Instruction::ZExt:
+  case Instruction::SExt:
+  case Instruction::FPTrunc:
+  case Instruction::FPExt:
+  case Instruction::UIToFP:
+  case Instruction::SIToFP:
+  case Instruction::FPToUI:
+  case Instruction::FPToSI:
+  case Instruction::PtrToInt:
+  case Instruction::IntToPtr:
+  case Instruction::BitCast:
+    return ConstantExpr::getCast(getOpcode(), Ops[0], getType());
   case Instruction::Select:
     return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]);
   case Instruction::InsertElement:
@@ -871,7 +868,7 @@ public:
     }
 
     void dump() const {
-      std::cerr << "Constant.cpp: ValueMap\n";
+      DOUT << "Constant.cpp: ValueMap\n";
     }
   };
 }
@@ -900,9 +897,12 @@ static ManagedStatic<ValueMap<uint64_t, Type, ConstantInt> > IntConstants;
 // just return the stored value while getSExtValue has to convert back to sign
 // extended. getZExtValue is more common in LLVM than getSExtValue().
 ConstantInt *ConstantInt::get(const Type *Ty, int64_t V) {
-  unsigned Size = Ty->getPrimitiveSizeInBits();
-  uint64_t ZeroExtendedCanonicalization = V & (~uint64_t(0UL) >> (64-Size));
-  return IntConstants->getOrCreate(Ty, ZeroExtendedCanonicalization );
+  return IntConstants->getOrCreate(Ty, V & Ty->getIntegralTypeMask());
+}
+
+ConstantIntegral *ConstantIntegral::get(const Type *Ty, int64_t V) {
+  if (Ty == Type::BoolTy) return ConstantBool::get(V&1);
+  return IntConstants->getOrCreate(Ty, V & Ty->getIntegralTypeMask());
 }
 
 //---- ConstantFP::get() implementation...
@@ -1073,6 +1073,29 @@ bool ConstantArray::isString() const {
   return true;
 }
 
+/// isCString - This method returns true if the array is a string (see
+/// isString) and it ends in a null byte \0 and does not contains any other
+/// null bytes except its terminator.
+bool ConstantArray::isCString() const {
+  // Check the element type for sbyte or ubyte...
+  if (getType()->getElementType() != Type::UByteTy &&
+      getType()->getElementType() != Type::SByteTy)
+    return false;
+  Constant *Zero = Constant::getNullValue(getOperand(0)->getType());
+  // Last element must be a null.
+  if (getOperand(getNumOperands()-1) != Zero)
+    return false;
+  // Other elements must be non-null integers.
+  for (unsigned i = 0, e = getNumOperands()-1; i != e; ++i) {
+    if (!isa<ConstantInt>(getOperand(i)))
+      return false;
+    if (getOperand(i) == Zero)
+      return false;
+  }
+  return true;
+}
+
+
 // getAsString - If the sub-element type of this array is either sbyte or ubyte,
 // then this method converts the array to an std::string and returns it.
 // Otherwise, it asserts out.
@@ -1285,37 +1308,70 @@ void UndefValue::destroyConstant() {
 }
 
 
-
-
 //---- ConstantExpr::get() implementations...
 //
-typedef std::pair<unsigned, std::vector<Constant*> > ExprMapKeyType;
+struct ExprMapKeyType {
+  explicit ExprMapKeyType(unsigned opc, std::vector<Constant*> ops,
+      unsigned short pred = 0) : opcode(opc), predicate(pred), operands(ops) { }
+  uint16_t opcode;
+  uint16_t predicate;
+  std::vector<Constant*> operands;
+  bool operator==(const ExprMapKeyType& that) const {
+    return this->opcode == that.opcode &&
+           this->predicate == that.predicate &&
+           this->operands == that.operands;
+  }
+  bool operator<(const ExprMapKeyType & that) const {
+    return this->opcode < that.opcode ||
+      (this->opcode == that.opcode && this->predicate < that.predicate) ||
+      (this->opcode == that.opcode && this->predicate == that.predicate &&
+       this->operands < that.operands);
+  }
+
+  bool operator!=(const ExprMapKeyType& that) const {
+    return !(*this == that);
+  }
+};
 
 namespace llvm {
   template<>
   struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
-    static ConstantExpr *create(const Type *Ty, const ExprMapKeyType &V) {
-      if (V.first == Instruction::Cast)
-        return new UnaryConstantExpr(Instruction::Cast, V.second[0], Ty);
-      if ((V.first >= Instruction::BinaryOpsBegin &&
-           V.first < Instruction::BinaryOpsEnd) ||
-          V.first == Instruction::Shl || V.first == Instruction::Shr)
-        return new BinaryConstantExpr(V.first, V.second[0], V.second[1]);
-      if (V.first == Instruction::Select)
-        return new SelectConstantExpr(V.second[0], V.second[1], V.second[2]);
-      if (V.first == Instruction::ExtractElement)
-        return new ExtractElementConstantExpr(V.second[0], V.second[1]);
-      if (V.first == Instruction::InsertElement)
-        return new InsertElementConstantExpr(V.second[0], V.second[1],
-                                             V.second[2]);
-      if (V.first == Instruction::ShuffleVector)
-        return new ShuffleVectorConstantExpr(V.second[0], V.second[1],
-                                             V.second[2]);
-      
-      assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!");
+    static ConstantExpr *create(const Type *Ty, const ExprMapKeyType &V,
+        unsigned short pred = 0) {
+      if (Instruction::isCast(V.opcode))
+        return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
+      if ((V.opcode >= Instruction::BinaryOpsBegin &&
+           V.opcode < Instruction::BinaryOpsEnd) ||
+          V.opcode == Instruction::Shl           || 
+          V.opcode == Instruction::LShr          ||
+          V.opcode == Instruction::AShr)
+        return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1]);
+      if (V.opcode == Instruction::Select)
+        return new SelectConstantExpr(V.operands[0], V.operands[1], 
+                                      V.operands[2]);
+      if (V.opcode == Instruction::ExtractElement)
+        return new ExtractElementConstantExpr(V.operands[0], V.operands[1]);
+      if (V.opcode == Instruction::InsertElement)
+        return new InsertElementConstantExpr(V.operands[0], V.operands[1],
+                                             V.operands[2]);
+      if (V.opcode == Instruction::ShuffleVector)
+        return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
+                                             V.operands[2]);
+      if (V.opcode == Instruction::GetElementPtr) {
+        std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
+        return new GetElementPtrConstantExpr(V.operands[0], IdxList, Ty);
+      }
 
-      std::vector<Constant*> IdxList(V.second.begin()+1, V.second.end());
-      return new GetElementPtrConstantExpr(V.second[0], IdxList, Ty);
+      // The compare instructions are weird. We have to encode the predicate
+      // value and it is combined with the instruction opcode by multiplying
+      // the opcode by one hundred. We must decode this to get the predicate.
+      if (V.opcode == Instruction::ICmp)
+        return new CompareConstantExpr(Instruction::ICmp, V.predicate, 
+                                       V.operands[0], V.operands[1]);
+      if (V.opcode == Instruction::FCmp) 
+        return new CompareConstantExpr(Instruction::FCmp, V.predicate, 
+                                       V.operands[0], V.operands[1]);
+      assert(0 && "Invalid ConstantExpr!");
     }
   };
 
@@ -1324,8 +1380,20 @@ namespace llvm {
     static void convert(ConstantExpr *OldC, const Type *NewTy) {
       Constant *New;
       switch (OldC->getOpcode()) {
-      case Instruction::Cast:
-        New = ConstantExpr::getCast(OldC->getOperand(0), NewTy);
+      case Instruction::Trunc:
+      case Instruction::ZExt:
+      case Instruction::SExt:
+      case Instruction::FPTrunc:
+      case Instruction::FPExt:
+      case Instruction::UIToFP:
+      case Instruction::SIToFP:
+      case Instruction::FPToUI:
+      case Instruction::FPToSI:
+      case Instruction::PtrToInt:
+      case Instruction::IntToPtr:
+      case Instruction::BitCast:
+        New = ConstantExpr::getCast(
+            OldC->getOpcode(), OldC->getOperand(0), NewTy);
         break;
       case Instruction::Select:
         New = ConstantExpr::getSelectTy(NewTy, OldC->getOperand(0),
@@ -1333,13 +1401,14 @@ namespace llvm {
                                         OldC->getOperand(2));
         break;
       case Instruction::Shl:
-      case Instruction::Shr:
+      case Instruction::LShr:
+      case Instruction::AShr:
         New = ConstantExpr::getShiftTy(NewTy, OldC->getOpcode(),
                                      OldC->getOperand(0), OldC->getOperand(1));
         break;
       default:
         assert(OldC->getOpcode() >= Instruction::BinaryOpsBegin &&
-               OldC->getOpcode() < Instruction::BinaryOpsEnd);
+               OldC->getOpcode() <  Instruction::BinaryOpsEnd);
         New = ConstantExpr::getTy(NewTy, OldC->getOpcode(), OldC->getOperand(0),
                                   OldC->getOperand(1));
         break;
@@ -1363,54 +1432,187 @@ static ExprMapKeyType getValType(ConstantExpr *CE) {
   Operands.reserve(CE->getNumOperands());
   for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
     Operands.push_back(cast<Constant>(CE->getOperand(i)));
-  return ExprMapKeyType(CE->getOpcode(), Operands);
+  return ExprMapKeyType(CE->getOpcode(), Operands, 
+      CE->isCompare() ? CE->getPredicate() : 0);
 }
 
 static ManagedStatic<ValueMap<ExprMapKeyType, Type,
                               ConstantExpr> > ExprConstants;
 
-Constant *ConstantExpr::getCast(Constant *C, const Type *Ty) {
+/// This is a utility function to handle folding of casts and lookup of the
+/// cast in the ExprConstants map. It is usedby the various get* methods below.
+static inline Constant *getFoldedCast(
+  Instruction::CastOps opc, Constant *C, const Type *Ty) {
   assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!");
-
-  if (Constant *FC = ConstantFoldCastInstruction(C, Ty))
-    return FC;          // Fold a few common cases...
+  // Fold a few common cases
+  if (Constant *FC = ConstantFoldCastInstruction(opc, C, Ty))
+    return FC;
 
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> argVec(1, C);
-  ExprMapKeyType Key = std::make_pair(Instruction::Cast, argVec);
+  ExprMapKeyType Key(opc, argVec);
   return ExprConstants->getOrCreate(Ty, Key);
 }
+Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) {
+  Instruction::CastOps opc = Instruction::CastOps(oc);
+  assert(Instruction::isCast(opc) && "opcode out of range");
+  assert(C && Ty && "Null arguments to getCast");
+  assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!");
 
-Constant *ConstantExpr::getSignExtend(Constant *C, const Type *Ty) {
-  assert(C->getType()->isIntegral() && Ty->isIntegral() &&
-         C->getType()->getPrimitiveSize() <= Ty->getPrimitiveSize() &&
-         "This is an illegal sign extension!");
-  if (C->getType() != Type::BoolTy) {
-    C = ConstantExpr::getCast(C, C->getType()->getSignedVersion());
-    return ConstantExpr::getCast(C, Ty);
-  } else {
-    if (C == ConstantBool::getTrue())
-      return ConstantIntegral::getAllOnesValue(Ty);
-    else
-      return ConstantIntegral::getNullValue(Ty);
+  switch (opc) {
+    default:
+      assert(0 && "Invalid cast opcode");
+      break;
+    case Instruction::Trunc:    return getTrunc(C, Ty);
+    case Instruction::ZExt:     return getZeroExtend(C, Ty);
+    case Instruction::SExt:     return getSignExtend(C, Ty);
+    case Instruction::FPTrunc:  return getFPTrunc(C, Ty);
+    case Instruction::FPExt:    return getFPExtend(C, Ty);
+    case Instruction::UIToFP:   return getUIToFP(C, Ty);
+    case Instruction::SIToFP:   return getSIToFP(C, Ty);
+    case Instruction::FPToUI:   return getFPToUI(C, Ty);
+    case Instruction::FPToSI:   return getFPToSI(C, Ty);
+    case Instruction::PtrToInt: return getPtrToInt(C, Ty);
+    case Instruction::IntToPtr: return getIntToPtr(C, Ty);
+    case Instruction::BitCast:  return getBitCast(C, Ty);
   }
+  return 0;
+} 
+
+Constant *ConstantExpr::getCast(Constant *C, const Type *Ty) {
+  // Note: we can't inline this because it requires the Instructions.h header
+  return getCast(CastInst::getCastOpcode(
+        C, C->getType()->isSigned(), Ty, Ty->isSigned()), C, Ty);
+}
+
+
+Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty) {
+  if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+    return getCast(Instruction::BitCast, C, Ty);
+  return getCast(Instruction::ZExt, C, Ty);
+}
+
+Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty) {
+  if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+    return getCast(Instruction::BitCast, C, Ty);
+  return getCast(Instruction::SExt, C, Ty);
+}
+
+Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
+  if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+    return getCast(Instruction::BitCast, C, Ty);
+  return getCast(Instruction::Trunc, C, Ty);
+}
+
+Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
+  assert(isa<PointerType>(S->getType()) && "Invalid cast");
+  assert((Ty->isIntegral() || Ty->getTypeID() == Type::PointerTyID) &&
+         "Invalid cast");
+
+  if (Ty->isIntegral())
+    return getCast(Instruction::PtrToInt, S, Ty);
+  return getCast(Instruction::BitCast, S, Ty);
+}
+
+Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) {
+  assert(C->getType()->isInteger() && "Trunc operand must be integer");
+  assert(Ty->isIntegral() && "Trunc produces only integral");
+  assert(C->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()&&
+         "SrcTy must be larger than DestTy for Trunc!");
+
+  return getFoldedCast(Instruction::Trunc, C, Ty);
+}
+
+Constant *ConstantExpr::getSignExtend(Constant *C, const Type *Ty) {
+  assert(C->getType()->isIntegral() && "SEXt operand must be integral");
+  assert(Ty->isInteger() && "SExt produces only integer");
+  assert(C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&&
+         "SrcTy must be smaller than DestTy for SExt!");
+
+  return getFoldedCast(Instruction::SExt, C, Ty);
 }
 
 Constant *ConstantExpr::getZeroExtend(Constant *C, const Type *Ty) {
-  assert(C->getType()->isIntegral() && Ty->isIntegral() &&
-         C->getType()->getPrimitiveSize() <= Ty->getPrimitiveSize() &&
-         "This is an illegal zero extension!");
-  if (C->getType() != Type::BoolTy)
-    C = ConstantExpr::getCast(C, C->getType()->getUnsignedVersion());
-  return ConstantExpr::getCast(C, Ty);
+  assert(C->getType()->isIntegral() && "ZEXt operand must be integral");
+  assert(Ty->isInteger() && "ZExt produces only integer");
+  assert(C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&&
+         "SrcTy must be smaller than DestTy for ZExt!");
+
+  return getFoldedCast(Instruction::ZExt, C, Ty);
+}
+
+Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty) {
+  assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
+         C->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()&&
+         "This is an illegal floating point truncation!");
+  return getFoldedCast(Instruction::FPTrunc, C, Ty);
+}
+
+Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) {
+  assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
+         C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&&
+         "This is an illegal floating point extension!");
+  return getFoldedCast(Instruction::FPExt, C, Ty);
+}
+
+Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) {
+  assert(C->getType()->isIntegral() && Ty->isFloatingPoint() &&
+         "This is an illegal uint to floating point cast!");
+  return getFoldedCast(Instruction::UIToFP, C, Ty);
+}
+
+Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) {
+  assert(C->getType()->isIntegral() && Ty->isFloatingPoint() &&
+         "This is an illegal sint to floating point cast!");
+  return getFoldedCast(Instruction::SIToFP, C, Ty);
+}
+
+Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) {
+  assert(C->getType()->isFloatingPoint() && Ty->isIntegral() &&
+         "This is an illegal floating point to uint cast!");
+  return getFoldedCast(Instruction::FPToUI, C, Ty);
+}
+
+Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty) {
+  assert(C->getType()->isFloatingPoint() && Ty->isIntegral() &&
+         "This is an illegal floating point to sint cast!");
+  return getFoldedCast(Instruction::FPToSI, C, Ty);
+}
+
+Constant *ConstantExpr::getPtrToInt(Constant *C, const Type *DstTy) {
+  assert(isa<PointerType>(C->getType()) && "PtrToInt source must be pointer");
+  assert(DstTy->isIntegral() && "PtrToInt destination must be integral");
+  return getFoldedCast(Instruction::PtrToInt, C, DstTy);
+}
+
+Constant *ConstantExpr::getIntToPtr(Constant *C, const Type *DstTy) {
+  assert(C->getType()->isIntegral() && "IntToPtr source must be integral");
+  assert(isa<PointerType>(DstTy) && "IntToPtr destination must be a pointer");
+  return getFoldedCast(Instruction::IntToPtr, C, DstTy);
+}
+
+Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
+  // BitCast implies a no-op cast of type only. No bits change.  However, you 
+  // can't cast pointers to anything but pointers.
+  const Type *SrcTy = C->getType();
+  assert((isa<PointerType>(SrcTy) == isa<PointerType>(DstTy)) &&
+         "BitCast cannot cast pointer to non-pointer and vice versa");
+
+  // Now we know we're not dealing with mismatched pointer casts (ptr->nonptr
+  // or nonptr->ptr). For all the other types, the cast is okay if source and 
+  // destination bit widths are identical.
+  unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
+  unsigned DstBitSize = DstTy->getPrimitiveSizeInBits();
+  assert(SrcBitSize == DstBitSize && "BitCast requies types of same width");
+  return getFoldedCast(Instruction::BitCast, C, DstTy);
 }
 
 Constant *ConstantExpr::getSizeOf(const Type *Ty) {
   // sizeof is implemented as: (ulong) gep (Ty*)null, 1
-  return getCast(
-    getGetElementPtr(getNullValue(PointerType::get(Ty)),
-                 std::vector<Constant*>(1, ConstantInt::get(Type::UIntTy, 1))),
-    Type::ULongTy);
+  return getCast(Instruction::PtrToInt, getGetElementPtr(getNullValue(
+    PointerType::get(Ty)), std::vector<Constant*>(1, 
+    ConstantInt::get(Type::UIntTy, 1))), Type::ULongTy);
 }
 
 Constant *ConstantExpr::getPtrPtrFromArrayPtr(Constant *C) {
@@ -1422,11 +1624,13 @@ Constant *ConstantExpr::getPtrPtrFromArrayPtr(Constant *C) {
 
 Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
                               Constant *C1, Constant *C2) {
-  if (Opcode == Instruction::Shl || Opcode == Instruction::Shr)
+  if (Opcode == Instruction::Shl || Opcode == Instruction::LShr ||
+      Opcode == Instruction::AShr)
     return getShiftTy(ReqTy, Opcode, C1, C2);
+
   // Check the operands for consistency first
-  assert((Opcode >= Instruction::BinaryOpsBegin &&
-          Opcode < Instruction::BinaryOpsEnd) &&
+  assert(Opcode >= Instruction::BinaryOpsBegin &&
+         Opcode <  Instruction::BinaryOpsEnd   &&
          "Invalid opcode in binary constant expression");
   assert(C1->getType() == C2->getType() &&
          "Operand types in binary constant expression should match");
@@ -1437,22 +1641,28 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
       return FC;          // Fold a few common cases...
 
   std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
-  ExprMapKeyType Key = std::make_pair(Opcode, argVec);
+  ExprMapKeyType Key(Opcode, argVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
+Constant *ConstantExpr::getCompareTy(unsigned Opcode, unsigned short predicate,
+                                     Constant *C1, Constant *C2) {
+  if (Opcode == Instruction::ICmp)
+    return getICmp(predicate, C1, C2);
+  return getFCmp(predicate, C1, C2);
+}
+
 Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
 #ifndef NDEBUG
   switch (Opcode) {
-  case Instruction::Add: case Instruction::Sub:
+  case Instruction::Add: 
+  case Instruction::Sub:
   case Instruction::Mul: 
-  case Instruction::Rem:
     assert(C1->getType() == C2->getType() && "Op types should be identical!");
     assert((C1->getType()->isInteger() || C1->getType()->isFloatingPoint() ||
             isa<PackedType>(C1->getType())) &&
            "Tried to create an arithmetic operation on a non-arithmetic type!");
     break;
-
   case Instruction::UDiv: 
   case Instruction::SDiv: 
     assert(C1->getType() == C2->getType() && "Op types should be identical!");
@@ -1466,6 +1676,19 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
       && cast<PackedType>(C1->getType())->getElementType()->isFloatingPoint())) 
       && "Tried to create an arithmetic operation on a non-arithmetic type!");
     break;
+  case Instruction::URem: 
+  case Instruction::SRem: 
+    assert(C1->getType() == C2->getType() && "Op types should be identical!");
+    assert((C1->getType()->isInteger() || (isa<PackedType>(C1->getType()) &&
+      cast<PackedType>(C1->getType())->getElementType()->isInteger())) &&
+           "Tried to create an arithmetic operation on a non-arithmetic type!");
+    break;
+  case Instruction::FRem:
+    assert(C1->getType() == C2->getType() && "Op types should be identical!");
+    assert((C1->getType()->isFloatingPoint() || (isa<PackedType>(C1->getType())
+      && cast<PackedType>(C1->getType())->getElementType()->isFloatingPoint())) 
+      && "Tried to create an arithmetic operation on a non-arithmetic type!");
+    break;
   case Instruction::And:
   case Instruction::Or:
   case Instruction::Xor:
@@ -1478,9 +1701,10 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
     assert(C1->getType() == C2->getType() && "Op types should be identical!");
     break;
   case Instruction::Shl:
-  case Instruction::Shr:
+  case Instruction::LShr:
+  case Instruction::AShr:
     assert(C2->getType() == Type::UByteTy && "Shift should be by ubyte!");
-    assert((C1->getType()->isInteger() || isa<PackedType>(C1->getType())) &&
+    assert(C1->getType()->isInteger() &&
            "Tried to create a shift operation on a non-integer type!");
     break;
   default:
@@ -1488,10 +1712,13 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
   }
 #endif
 
-  if (Instruction::isComparison(Opcode))
-    return getTy(Type::BoolTy, Opcode, C1, C2);
-  else
-    return getTy(C1->getType(), Opcode, C1, C2);
+  return getTy(C1->getType(), Opcode, C1, C2);
+}
+
+Constant *ConstantExpr::getCompare(unsigned Opcode, unsigned short pred, 
+                            Constant *C1, Constant *C2) {
+  assert(C1->getType() == C2->getType() && "Op types should be identical!");
+  return getCompareTy(Opcode, pred, C1, C2);
 }
 
 Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
@@ -1507,7 +1734,7 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
   std::vector<Constant*> argVec(3, C);
   argVec[1] = V1;
   argVec[2] = V2;
-  ExprMapKeyType Key = std::make_pair(Instruction::Select, argVec);
+  ExprMapKeyType Key(Instruction::Select, argVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -1515,8 +1742,9 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
 Constant *ConstantExpr::getShiftTy(const Type *ReqTy, unsigned Opcode,
                                    Constant *C1, Constant *C2) {
   // Check the operands for consistency first
-  assert((Opcode == Instruction::Shl ||
-          Opcode == Instruction::Shr) &&
+  assert((Opcode == Instruction::Shl   ||
+          Opcode == Instruction::LShr  ||
+          Opcode == Instruction::AShr) &&
          "Invalid opcode in binary constant expression");
   assert(C1->getType()->isIntegral() && C2->getType() == Type::UByteTy &&
          "Invalid operand types for Shift constant expr!");
@@ -1526,11 +1754,10 @@ Constant *ConstantExpr::getShiftTy(const Type *ReqTy, unsigned Opcode,
 
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
-  ExprMapKeyType Key = std::make_pair(Opcode, argVec);
+  ExprMapKeyType Key(Opcode, argVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
-
 Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
                                            const std::vector<Value*> &IdxList) {
   assert(GetElementPtrInst::getIndexedType(C->getType(), IdxList, true) &&
@@ -1547,7 +1774,7 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
   ArgVec.push_back(C);
   for (unsigned i = 0, e = IdxList.size(); i != e; ++i)
     ArgVec.push_back(cast<Constant>(IdxList[i]));
-  const ExprMapKeyType &Key = std::make_pair(Instruction::GetElementPtr,ArgVec);
+  const ExprMapKeyType Key(Instruction::GetElementPtr,ArgVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -1571,6 +1798,41 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C,
   return getGetElementPtrTy(PointerType::get(Ty), C, IdxList);
 }
 
+Constant *
+ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+  assert(LHS->getType() == RHS->getType());
+  assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE && 
+         pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate");
+
+  if (Constant *FC = ConstantFoldCompare(Instruction::ICmp, LHS, RHS, pred))
+    return FC;          // Fold a few common cases...
+
+  // Look up the constant in the table first to ensure uniqueness
+  std::vector<Constant*> ArgVec;
+  ArgVec.push_back(LHS);
+  ArgVec.push_back(RHS);
+  // Fake up an opcode value that encodes both the opcode and predicate
+  const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred);
+  return ExprConstants->getOrCreate(Type::BoolTy, Key);
+}
+
+Constant *
+ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+  assert(LHS->getType() == RHS->getType());
+  assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate");
+
+  if (Constant *FC = ConstantFoldCompare(Instruction::FCmp, LHS, RHS, pred))
+    return FC;          // Fold a few common cases...
+
+  // Look up the constant in the table first to ensure uniqueness
+  std::vector<Constant*> ArgVec;
+  ArgVec.push_back(LHS);
+  ArgVec.push_back(RHS);
+  // Fake up an opcode value that encodes both the opcode and predicate
+  const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred);
+  return ExprConstants->getOrCreate(Type::BoolTy, Key);
+}
+
 Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
                                             Constant *Idx) {
   if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
@@ -1578,7 +1840,7 @@ Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> ArgVec(1, Val);
   ArgVec.push_back(Idx);
-  const ExprMapKeyType &Key = std::make_pair(Instruction::ExtractElement,ArgVec);
+  const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -1599,7 +1861,7 @@ Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val,
   std::vector<Constant*> ArgVec(1, Val);
   ArgVec.push_back(Elt);
   ArgVec.push_back(Idx);
-  const ExprMapKeyType &Key = std::make_pair(Instruction::InsertElement,ArgVec);
+  const ExprMapKeyType Key(Instruction::InsertElement,ArgVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -1623,7 +1885,7 @@ Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1,
   std::vector<Constant*> ArgVec(1, V1);
   ArgVec.push_back(V2);
   ArgVec.push_back(Mask);
-  const ExprMapKeyType &Key = std::make_pair(Instruction::ShuffleVector,ArgVec);
+  const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec);
   return ExprConstants->getOrCreate(ReqTy, Key);
 }
 
@@ -1634,7 +1896,6 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
   return getShuffleVectorTy(V1->getType(), V1, V2, Mask);
 }
 
-
 // destroyConstant - Remove the constant from the constant table...
 //
 void ConstantExpr::destroyConstant() {
@@ -1818,9 +2079,9 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
       Indices.push_back(Val);
     }
     Replacement = ConstantExpr::getGetElementPtr(Pointer, Indices);
-  } else if (getOpcode() == Instruction::Cast) {
+  } else if (isCast()) {
     assert(getOperand(0) == From && "Cast only has one use!");
-    Replacement = ConstantExpr::getCast(To, getType());
+    Replacement = ConstantExpr::getCast(getOpcode(), To, getType());
   } else if (getOpcode() == Instruction::Select) {
     Constant *C1 = getOperand(0);
     Constant *C2 = getOperand(1);
@@ -1851,6 +2112,15 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
     if (C2 == From) C2 = To;
     if (C3 == From) C3 = To;
     Replacement = ConstantExpr::getShuffleVector(C1, C2, C3);
+  } else if (isCompare()) {
+    Constant *C1 = getOperand(0);
+    Constant *C2 = getOperand(1);
+    if (C1 == From) C1 = To;
+    if (C2 == From) C2 = To;
+    if (getOpcode() == Instruction::ICmp)
+      Replacement = ConstantExpr::getICmp(getPredicate(), C1, C2);
+    else
+      Replacement = ConstantExpr::getFCmp(getPredicate(), C1, C2);
   } else if (getNumOperands() == 2) {
     Constant *C1 = getOperand(0);
     Constant *C2 = getOperand(1);