Index: include/llvm/Constants.h
===================================================================
--- include/llvm/Constants.h	(revision 126468)
+++ include/llvm/Constants.h	(working copy)
@@ -622,30 +622,36 @@
   // ConstantExprs in intermediate forms.
   static Constant *getTy(const Type *Ty, unsigned Opcode,
                          Constant *C1, Constant *C2,
-                         unsigned Flags = 0);
+                         unsigned Flags = 0, bool DoFold = true);
   static Constant *getCompareTy(unsigned short pred, Constant *C1,
-                                Constant *C2);
+                                Constant *C2, bool DoFold = true);
   static Constant *getSelectTy(const Type *Ty,
-                               Constant *C1, Constant *C2, Constant *C3);
+                               Constant *C1, Constant *C2, Constant *C3,
+                               bool DoFold = true);
   template<typename IndexTy>
   static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
                                       IndexTy const *Idxs, unsigned NumIdxs,
-                                      bool InBounds);
+                                      bool InBounds, bool DoFold = true);
   static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
-                                       Constant *Idx);
+                                       Constant *Idx, bool DoFold = true);
   static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
-                                      Constant *Elt, Constant *Idx);
+                                      Constant *Elt, Constant *Idx,
+                                      bool DoFold = true);
   static Constant *getShuffleVectorTy(const Type *Ty, Constant *V1,
-                                      Constant *V2, Constant *Mask);
+                                      Constant *V2, Constant *Mask,
+                                      bool DoFold = true);
   static Constant *getExtractValueTy(const Type *Ty, Constant *Agg,
-                                     const unsigned *Idxs, unsigned NumIdxs);
+                                     const unsigned *Idxs, unsigned NumIdxs,
+                                     bool DoFold = true);
   static Constant *getInsertValueTy(const Type *Ty, Constant *Agg,
                                     Constant *Val,
-                                    const unsigned *Idxs, unsigned NumIdxs);
+                                    const unsigned *Idxs, unsigned NumIdxs,
+                                    bool DoFold = true);
   template<typename IndexTy>
   static Constant *getGetElementPtrImpl(Constant *C,
                                         IndexTy const *IdxList,
-                                        unsigned NumIdx, bool InBounds);
+                                        unsigned NumIdx, bool InBounds,
+                                        bool DoFold = true);
 
 public:
   // Static methods to construct a ConstantExpr of different kinds.  Note that
@@ -655,61 +661,72 @@
 
   /// getAlignOf constant expr - computes the alignment of a type in a target
   /// independent way (Note: the return type is an i64).
-  static Constant *getAlignOf(const Type *Ty);
+  static Constant *getAlignOf(const Type *Ty, bool DoFold = true);
   
   /// getSizeOf constant expr - computes the (alloc) size of a type (in
   /// address-units, not bits) in a target independent way (Note: the return
   /// type is an i64).
   ///
-  static Constant *getSizeOf(const Type *Ty);
+  static Constant *getSizeOf(const Type *Ty, bool DoFold = true);
 
   /// getOffsetOf constant expr - computes the offset of a struct field in a 
   /// target independent way (Note: the return type is an i64).
   ///
-  static Constant *getOffsetOf(const StructType *STy, unsigned FieldNo);
+  static Constant *getOffsetOf(const StructType *STy, unsigned FieldNo,
+                               bool DoFold = true);
 
   /// getOffsetOf constant expr - This is a generalized form of getOffsetOf,
   /// which supports any aggregate type, and any Constant index.
   ///
-  static Constant *getOffsetOf(const Type *Ty, Constant *FieldNo);
+  static Constant *getOffsetOf(const Type *Ty, Constant *FieldNo,
+                               bool DoFold = true);
   
-  static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false);
-  static Constant *getFNeg(Constant *C);
-  static Constant *getNot(Constant *C);
+  static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false,
+                          bool DoFold = true);
+  static Constant *getFNeg(Constant *C, bool DoFold = true);
+  static Constant *getNot(Constant *C, bool DoFold = true);
   static Constant *getAdd(Constant *C1, Constant *C2,
-                          bool HasNUW = false, bool HasNSW = false);
-  static Constant *getFAdd(Constant *C1, Constant *C2);
+                          bool HasNUW = false, bool HasNSW = false,
+                          bool DoFold = true);
+  static Constant *getFAdd(Constant *C1, Constant *C2, bool DoFold = true);
   static Constant *getSub(Constant *C1, Constant *C2,
-                          bool HasNUW = false, bool HasNSW = false);
-  static Constant *getFSub(Constant *C1, Constant *C2);
+                          bool HasNUW = false, bool HasNSW = false,
+                          bool DoFold = true);
+  static Constant *getFSub(Constant *C1, Constant *C2, bool DoFold = true);
   static Constant *getMul(Constant *C1, Constant *C2,
-                          bool HasNUW = false, bool HasNSW = false);
-  static Constant *getFMul(Constant *C1, Constant *C2);
-  static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false);
-  static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false);
-  static Constant *getFDiv(Constant *C1, Constant *C2);
-  static Constant *getURem(Constant *C1, Constant *C2);
-  static Constant *getSRem(Constant *C1, Constant *C2);
-  static Constant *getFRem(Constant *C1, Constant *C2);
-  static Constant *getAnd(Constant *C1, Constant *C2);
-  static Constant *getOr(Constant *C1, Constant *C2);
-  static Constant *getXor(Constant *C1, Constant *C2);
+                          bool HasNUW = false, bool HasNSW = false,
+                          bool DoFold = true);
+  static Constant *getFMul(Constant *C1, Constant *C2, bool DoFold = true);
+  static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false,
+                           bool DoFold = true);
+  static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false,
+                           bool DoFold = true);
+  static Constant *getFDiv(Constant *C1, Constant *C2, bool DoFold = true);
+  static Constant *getURem(Constant *C1, Constant *C2, bool DoFold = true);
+  static Constant *getSRem(Constant *C1, Constant *C2, bool DoFold = true);
+  static Constant *getFRem(Constant *C1, Constant *C2, bool DoFold = true);
+  static Constant *getAnd(Constant *C1, Constant *C2, bool DoFold = true);
+  static Constant *getOr(Constant *C1, Constant *C2, bool DoFold = true);
+  static Constant *getXor(Constant *C1, Constant *C2, bool DoFold = true);
   static Constant *getShl(Constant *C1, Constant *C2,
-                          bool HasNUW = false, bool HasNSW = false);
-  static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false);
-  static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false);
-  static Constant *getTrunc   (Constant *C, const Type *Ty);
-  static Constant *getSExt    (Constant *C, const Type *Ty);
-  static Constant *getZExt    (Constant *C, const Type *Ty);
-  static Constant *getFPTrunc (Constant *C, const Type *Ty);
-  static Constant *getFPExtend(Constant *C, const Type *Ty);
-  static Constant *getUIToFP  (Constant *C, const Type *Ty);
-  static Constant *getSIToFP  (Constant *C, const Type *Ty);
-  static Constant *getFPToUI  (Constant *C, const Type *Ty);
-  static Constant *getFPToSI  (Constant *C, const Type *Ty);
-  static Constant *getPtrToInt(Constant *C, const Type *Ty);
-  static Constant *getIntToPtr(Constant *C, const Type *Ty);
-  static Constant *getBitCast (Constant *C, const Type *Ty);
+                          bool HasNUW = false, bool HasNSW = false,
+                          bool DoFold = true);
+  static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false,
+                           bool DoFold = true);
+  static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false,
+                           bool DoFold = true);
+  static Constant *getTrunc   (Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getSExt    (Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getZExt    (Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getFPTrunc (Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getFPExtend(Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getUIToFP  (Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getSIToFP  (Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getFPToUI  (Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getFPToSI  (Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getPtrToInt(Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getIntToPtr(Constant *C, const Type *Ty, bool DoFold = true);
+  static Constant *getBitCast (Constant *C, const Type *Ty, bool DoFold = true);
 
   static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
   static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
@@ -758,44 +775,51 @@
   static Constant *getCast(
     unsigned ops,  ///< The opcode for the conversion
     Constant *C,   ///< The constant to be converted
-    const Type *Ty ///< The type to which the constant is converted
+    const Type *Ty, ///< The type to which the constant is converted
+    bool DoFold = true
   );
 
   // @brief Create a ZExt or BitCast cast constant expression
   static Constant *getZExtOrBitCast(
     Constant *C,   ///< The constant to zext or bitcast
-    const Type *Ty ///< The type to zext or bitcast C to
+    const Type *Ty, ///< The type to zext or bitcast C to
+    bool DoFold = true
   );
 
   // @brief Create a SExt or BitCast cast constant expression 
   static Constant *getSExtOrBitCast(
     Constant *C,   ///< The constant to sext or bitcast
-    const Type *Ty ///< The type to sext or bitcast C to
+    const Type *Ty, ///< The type to sext or bitcast C to
+    bool DoFold = true
   );
 
   // @brief Create a Trunc or BitCast cast constant expression
   static Constant *getTruncOrBitCast(
     Constant *C,   ///< The constant to trunc or bitcast
-    const Type *Ty ///< The type to trunc or bitcast C to
+    const Type *Ty, ///< The type to trunc or bitcast C to
+    bool DoFold = true
   );
 
   /// @brief Create a BitCast or a PtrToInt cast constant expression
   static Constant *getPointerCast(
     Constant *C,   ///< The pointer value to be casted (operand 0)
-    const Type *Ty ///< The type to which cast should be made
+    const Type *Ty, ///< The type to which cast should be made
+    bool DoFold = true
   );
 
   /// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts
   static Constant *getIntegerCast(
     Constant *C,    ///< The integer constant to be casted 
     const Type *Ty, ///< The integer type to cast to
-    bool isSigned   ///< Whether C should be treated as signed or not
+    bool isSigned,   ///< Whether C should be treated as signed or not
+    bool DoFold = true
   );
 
   /// @brief Create a FPExt, Bitcast or FPTrunc for fp -> fp casts
   static Constant *getFPCast(
     Constant *C,    ///< The integer constant to be casted 
-    const Type *Ty ///< The integer type to cast to
+    const Type *Ty, ///< The integer type to cast to
+    bool DoFold = true
   );
 
   /// @brief Return true if this is a convert constant expression
@@ -817,55 +841,64 @@
 
   /// Select constant expr
   ///
-  static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) {
-    return getSelectTy(V1->getType(), C, V1, V2);
+  static Constant *getSelect(Constant *C, Constant *V1, Constant *V2,
+                             bool DoFold = true) {
+    return getSelectTy(V1->getType(), C, V1, V2, DoFold);
   }
 
   /// get - Return a binary or shift operator constant expression,
   /// folding if possible.
   ///
   static Constant *get(unsigned Opcode, Constant *C1, Constant *C2,
-                       unsigned Flags = 0);
+                       unsigned Flags = 0, bool DoFold = true);
 
   /// @brief Return an ICmp or FCmp comparison operator constant expression.
-  static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
+  static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2,
+                              bool DoFold = true);
 
   /// get* - Return some common constants without having to
   /// specify the full Instruction::OPCODE identifier.
   ///
-  static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS);
-  static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
+  static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS,
+                           bool DoFold = true);
+  static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS,
+                           bool DoFold = true);
 
   /// Getelementptr form.  std::vector<Value*> is only accepted for convenience:
   /// all elements must be Constant's.
   ///
   static Constant *getGetElementPtr(Constant *C,
                                     Constant *const *IdxList, unsigned NumIdx,
-                                    bool InBounds = false);
+                                    bool InBounds = false, bool DoFold = true);
   static Constant *getGetElementPtr(Constant *C,
                                     Value *const *IdxList, unsigned NumIdx,
-                                    bool InBounds = false);
+                                    bool InBounds = false, bool DoFold = true);
 
   /// Create an "inbounds" getelementptr. See the documentation for the
   /// "inbounds" flag in LangRef.html for details.
   static Constant *getInBoundsGetElementPtr(Constant *C,
                                             Constant *const *IdxList,
-                                            unsigned NumIdx) {
-    return getGetElementPtr(C, IdxList, NumIdx, true);
+                                            unsigned NumIdx, bool DoFold=true){
+    return getGetElementPtr(C, IdxList, NumIdx, true, DoFold);
   }
   static Constant *getInBoundsGetElementPtr(Constant *C,
                                             Value* const *IdxList,
-                                            unsigned NumIdx) {
-    return getGetElementPtr(C, IdxList, NumIdx, true);
+                                            unsigned NumIdx, bool DoFold=true){
+    return getGetElementPtr(C, IdxList, NumIdx, true, DoFold);
   }
 
-  static Constant *getExtractElement(Constant *Vec, Constant *Idx);
-  static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
-  static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
+  static Constant *getExtractElement(Constant *Vec, Constant *Idx,
+                                     bool DoFold = true);
+  static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx,
+                                    bool DoFold = true);
+  static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask,
+                                    bool DoFold = true);
   static Constant *getExtractValue(Constant *Agg,
-                                   const unsigned *IdxList, unsigned NumIdx);
+                                   const unsigned *IdxList, unsigned NumIdx,
+                                   bool DoFold = true);
   static Constant *getInsertValue(Constant *Agg, Constant *Val,
-                                  const unsigned *IdxList, unsigned NumIdx);
+                                  const unsigned *IdxList, unsigned NumIdx,
+                                  bool DoFold = true);
 
   /// isNullValue - Return true if this is the value that would be returned by
   /// getNullValue.
Index: include/llvm/Support/NoFolder.h
===================================================================
--- include/llvm/Support/NoFolder.h	(revision 126468)
+++ include/llvm/Support/NoFolder.h	(working copy)
@@ -23,7 +23,7 @@
 #define LLVM_SUPPORT_NOFOLDER_H
 
 #include "llvm/Constants.h"
-#include "llvm/Instructions.h"
+#include "llvm/InstrTypes.h"
 
 namespace llvm {
 
@@ -38,109 +38,88 @@
   // Binary Operators
   //===--------------------------------------------------------------------===//
 
-  Instruction *CreateAdd(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateAdd(LHS, RHS);
+  Constant *CreateAdd(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW, false);
   }
-  Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateNSWAdd(LHS, RHS);
+  Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getFAdd(LHS, RHS, false);
   }
-  Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateNUWAdd(LHS, RHS);
+  Constant *CreateSub(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW, false);
   }
-  Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateFAdd(LHS, RHS);
+  Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getFSub(LHS, RHS, false);
   }
-  Instruction *CreateSub(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateSub(LHS, RHS);
+  Constant *CreateMul(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW, false);
   }
-  Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateNSWSub(LHS, RHS);
+  Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getFMul(LHS, RHS, false);
   }
-  Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateNUWSub(LHS, RHS);
+  Constant *CreateUDiv(Constant *LHS, Constant *RHS,
+                       bool isExact = false) const {
+    return ConstantExpr::getUDiv(LHS, RHS, isExact, false);
   }
-  Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateFSub(LHS, RHS);
+  Constant *CreateSDiv(Constant *LHS, Constant *RHS,
+                       bool isExact = false) const {
+    return ConstantExpr::getSDiv(LHS, RHS, isExact, false);
   }
-  Instruction *CreateMul(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateMul(LHS, RHS);
+  Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getFDiv(LHS, RHS, false);
   }
-  Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateNSWMul(LHS, RHS);
+  Constant *CreateURem(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getURem(LHS, RHS, false);
   }
-  Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateNUWMul(LHS, RHS);
+  Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getSRem(LHS, RHS, false);
   }
-  Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateFMul(LHS, RHS);
+  Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getFRem(LHS, RHS, false);
   }
-  Instruction *CreateUDiv(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateUDiv(LHS, RHS);
+  Constant *CreateShl(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW, false);
   }
-  Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateExactUDiv(LHS, RHS);
+  Constant *CreateLShr(Constant *LHS, Constant *RHS,
+                       bool isExact = false) const {
+    return ConstantExpr::getLShr(LHS, RHS, isExact, false);
   }
-  Instruction *CreateSDiv(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateSDiv(LHS, RHS);
+  Constant *CreateAShr(Constant *LHS, Constant *RHS,
+                       bool isExact = false) const {
+    return ConstantExpr::getAShr(LHS, RHS, isExact, false);
   }
-  Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateExactSDiv(LHS, RHS);
+  Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getAnd(LHS, RHS, false);
   }
-  Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateFDiv(LHS, RHS);
+  Constant *CreateOr(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getOr(LHS, RHS, false);
   }
-  Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateURem(LHS, RHS);
+  Constant *CreateXor(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getXor(LHS, RHS, false);
   }
-  Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateSRem(LHS, RHS);
-  }
-  Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateFRem(LHS, RHS);
-  }
-  Instruction *CreateShl(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateShl(LHS, RHS);
-  }
-  Instruction *CreateLShr(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateLShr(LHS, RHS);
-  }
-  Instruction *CreateAShr(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateAShr(LHS, RHS);
-  }
-  Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateAnd(LHS, RHS);
-  }
-  Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateOr(LHS, RHS);
-  }
-  Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::CreateXor(LHS, RHS);
-  }
 
-  Instruction *CreateBinOp(Instruction::BinaryOps Opc,
-                           Constant *LHS, Constant *RHS) const {
-    return BinaryOperator::Create(Opc, LHS, RHS);
+  Constant *CreateBinOp(Instruction::BinaryOps Opc,
+                        Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::get(Opc, LHS, RHS, false);
   }
 
   //===--------------------------------------------------------------------===//
   // Unary Operators
   //===--------------------------------------------------------------------===//
 
-  Instruction *CreateNeg(Constant *C) const {
-    return BinaryOperator::CreateNeg(C);
+  Constant *CreateNeg(Constant *C,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return ConstantExpr::getNeg(C, HasNUW, HasNSW, false);
   }
-  Instruction *CreateNSWNeg(Constant *C) const {
-    return BinaryOperator::CreateNSWNeg(C);
+  Constant *CreateFNeg(Constant *C) const {
+    return ConstantExpr::getFNeg(C, false);
   }
-  Instruction *CreateNUWNeg(Constant *C) const {
-    return BinaryOperator::CreateNUWNeg(C);
+  Constant *CreateNot(Constant *C) const {
+    return ConstantExpr::getNot(C, false);
   }
-  Instruction *CreateFNeg(Constant *C) const {
-    return BinaryOperator::CreateFNeg(C);
-  }
-  Instruction *CreateNot(Constant *C) const {
-    return BinaryOperator::CreateNot(C);
-  }
 
   //===--------------------------------------------------------------------===//
   // Memory Instructions
@@ -148,106 +127,104 @@
 
   Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList,
                                 unsigned NumIdx) const {
-    return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx);
+    return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx, false);
   }
-  Instruction *CreateGetElementPtr(Constant *C, Value* const *IdxList,
-                                   unsigned NumIdx) const {
-    return GetElementPtrInst::Create(C, IdxList, IdxList+NumIdx);
+  Constant *CreateGetElementPtr(Constant *C, Value* const *IdxList,
+                                unsigned NumIdx) const {
+    return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx, false);
   }
 
   Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList,
                                         unsigned NumIdx) const {
-    return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx);
+    return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx, false);
   }
-  Instruction *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
-                                           unsigned NumIdx) const {
-    return GetElementPtrInst::CreateInBounds(C, IdxList, IdxList+NumIdx);
+  Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
+                                        unsigned NumIdx) const {
+    return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx, false);
   }
 
   //===--------------------------------------------------------------------===//
   // Cast/Conversion Operators
   //===--------------------------------------------------------------------===//
 
-  Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
-                    const Type *DestTy) const {
-    return CastInst::Create(Op, C, DestTy);
+  Constant *CreateCast(Instruction::CastOps Op, Constant *C,
+                       const Type *DestTy) const {
+    return ConstantExpr::getCast(Op, C, DestTy, true);
   }
-  Instruction *CreatePointerCast(Constant *C, const Type *DestTy) const {
-    return CastInst::CreatePointerCast(C, DestTy);
+  Constant *CreatePointerCast(Constant *C, const Type *DestTy) const {
+    return ConstantExpr::getPointerCast(C, DestTy, false);
   }
-  Instruction *CreateIntCast(Constant *C, const Type *DestTy,
-                       bool isSigned) const {
-    return CastInst::CreateIntegerCast(C, DestTy, isSigned);
+  Constant *CreateIntCast(Constant *C, const Type *DestTy,
+                          bool isSigned) const {
+    return ConstantExpr::getIntegerCast(C, DestTy, isSigned, false);
   }
-  Instruction *CreateFPCast(Constant *C, const Type *DestTy) const {
-    return CastInst::CreateFPCast(C, DestTy);
+  Constant *CreateFPCast(Constant *C, const Type *DestTy) const {
+    return ConstantExpr::getFPCast(C, DestTy, false);
   }
 
-  Instruction *CreateBitCast(Constant *C, const Type *DestTy) const {
+  Constant *CreateBitCast(Constant *C, const Type *DestTy) const {
     return CreateCast(Instruction::BitCast, C, DestTy);
   }
-  Instruction *CreateIntToPtr(Constant *C, const Type *DestTy) const {
+  Constant *CreateIntToPtr(Constant *C, const Type *DestTy) const {
     return CreateCast(Instruction::IntToPtr, C, DestTy);
   }
-  Instruction *CreatePtrToInt(Constant *C, const Type *DestTy) const {
+  Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const {
     return CreateCast(Instruction::PtrToInt, C, DestTy);
   }
-  Instruction *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const {
-    return CastInst::CreateZExtOrBitCast(C, DestTy);
+  Constant *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const {
+    return ConstantExpr::getZExtOrBitCast(C, DestTy, false);
   }
-  Instruction *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const {
-    return CastInst::CreateSExtOrBitCast(C, DestTy);
+  Constant *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const {
+    return ConstantExpr::getSExtOrBitCast(C, DestTy, false);
   }
 
-  Instruction *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const {
-    return CastInst::CreateTruncOrBitCast(C, DestTy);
+  Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const {
+    return ConstantExpr::getTruncOrBitCast(C, DestTy, false);
   }
 
   //===--------------------------------------------------------------------===//
   // Compare Instructions
   //===--------------------------------------------------------------------===//
 
-  Instruction *CreateICmp(CmpInst::Predicate P,
-                          Constant *LHS, Constant *RHS) const {
-    return new ICmpInst(P, LHS, RHS);
+  Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
+                       Constant *RHS) const {
+    return ConstantExpr::getCompare(P, LHS, RHS, false);
   }
-  Instruction *CreateFCmp(CmpInst::Predicate P,
-                          Constant *LHS, Constant *RHS) const {
-    return new FCmpInst(P, LHS, RHS);
+  Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
+                       Constant *RHS) const {
+    return ConstantExpr::getCompare(P, LHS, RHS, false);
   }
 
   //===--------------------------------------------------------------------===//
   // Other Instructions
   //===--------------------------------------------------------------------===//
 
-  Instruction *CreateSelect(Constant *C,
-                            Constant *True, Constant *False) const {
-    return SelectInst::Create(C, True, False);
+  Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+    return ConstantExpr::getSelect(C, True, False, false);
   }
 
-  Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
-    return ExtractElementInst::Create(Vec, Idx);
+  Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+    return ConstantExpr::getExtractElement(Vec, Idx, false);
   }
 
-  Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
-                                   Constant *Idx) const {
-    return InsertElementInst::Create(Vec, NewElt, Idx);
+  Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
+                                Constant *Idx) const {
+    return ConstantExpr::getInsertElement(Vec, NewElt, Idx, false);
   }
 
-  Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
-                                   Constant *Mask) const {
-    return new ShuffleVectorInst(V1, V2, Mask);
+  Constant *CreateShuffleVector(Constant *V1, Constant *V2,
+                                Constant *Mask) const {
+    return ConstantExpr::getShuffleVector(V1, V2, Mask, false);
   }
 
-  Instruction *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
-                                  unsigned NumIdx) const {
-    return ExtractValueInst::Create(Agg, IdxList, IdxList+NumIdx);
+  Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
+                               unsigned NumIdx) const {
+    return ConstantExpr::getExtractValue(Agg, IdxList, NumIdx, false);
   }
 
-  Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
-                                 const unsigned *IdxList,
-                                 unsigned NumIdx) const {
-    return InsertValueInst::Create(Agg, Val, IdxList, IdxList+NumIdx);
+  Constant *CreateInsertValue(Constant *Agg, Constant *Val,
+                              const unsigned *IdxList, unsigned NumIdx) const {
+    return ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx, false);
   }
 };
 
Index: lib/VMCore/Constants.cpp
===================================================================
--- lib/VMCore/Constants.cpp	(revision 126468)
+++ lib/VMCore/Constants.cpp	(working copy)
@@ -1173,7 +1173,20 @@
   return pImpl->ExprConstants.getOrCreate(Ty, Key);
 }
  
-Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) {
+static inline Constant *getNoFoldCast(
+  Instruction::CastOps opc, Constant *C, const Type *Ty) {
+  assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!");
+
+  LLVMContextImpl *pImpl = Ty->getContext().pImpl;
+
+  // Look up the constant in the table first to ensure uniqueness
+  std::vector<Constant*> argVec(1, C);
+  ExprMapKeyType Key(opc, argVec);
+  
+  return pImpl->ExprConstants.getOrCreate(Ty, Key);
+}
+
+Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty, bool DoFold) {
   Instruction::CastOps opc = Instruction::CastOps(oc);
   assert(Instruction::isCast(opc) && "opcode out of range");
   assert(C && Ty && "Null arguments to getCast");
@@ -1183,51 +1196,51 @@
   default:
     llvm_unreachable("Invalid cast opcode");
     break;
-  case Instruction::Trunc:    return getTrunc(C, Ty);
-  case Instruction::ZExt:     return getZExt(C, Ty);
-  case Instruction::SExt:     return getSExt(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);
+  case Instruction::Trunc:    return getTrunc(C, Ty, DoFold);
+  case Instruction::ZExt:     return getZExt(C, Ty, DoFold);
+  case Instruction::SExt:     return getSExt(C, Ty, DoFold);
+  case Instruction::FPTrunc:  return getFPTrunc(C, Ty, DoFold);
+  case Instruction::FPExt:    return getFPExtend(C, Ty, DoFold);
+  case Instruction::UIToFP:   return getUIToFP(C, Ty, DoFold);
+  case Instruction::SIToFP:   return getSIToFP(C, Ty, DoFold);
+  case Instruction::FPToUI:   return getFPToUI(C, Ty, DoFold);
+  case Instruction::FPToSI:   return getFPToSI(C, Ty, DoFold);
+  case Instruction::PtrToInt: return getPtrToInt(C, Ty, DoFold);
+  case Instruction::IntToPtr: return getIntToPtr(C, Ty, DoFold);
+  case Instruction::BitCast:  return getBitCast(C, Ty, DoFold);
   }
   return 0;
 } 
 
-Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty, bool DoFold) {
   if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
-    return getBitCast(C, Ty);
-  return getZExt(C, Ty);
+    return getBitCast(C, Ty, DoFold);
+  return getZExt(C, Ty, DoFold);
 }
 
-Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty, bool DoFold) {
   if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
-    return getBitCast(C, Ty);
-  return getSExt(C, Ty);
+    return getBitCast(C, Ty, DoFold);
+  return getSExt(C, Ty, DoFold);
 }
 
-Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty, bool DoFold) {
   if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
-    return getBitCast(C, Ty);
-  return getTrunc(C, Ty);
+    return getBitCast(C, Ty, DoFold);
+  return getTrunc(C, Ty, DoFold);
 }
 
-Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
+Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty, bool DoFold) {
   assert(S->getType()->isPointerTy() && "Invalid cast");
   assert((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast");
 
   if (Ty->isIntegerTy())
-    return getPtrToInt(S, Ty);
-  return getBitCast(S, Ty);
+    return getPtrToInt(S, Ty, DoFold);
+  return getBitCast(S, Ty, DoFold);
 }
 
 Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty, 
-                                       bool isSigned) {
+                                       bool isSigned, bool DoFold) {
   assert(C->getType()->isIntOrIntVectorTy() &&
          Ty->isIntOrIntVectorTy() && "Invalid cast");
   unsigned SrcBits = C->getType()->getScalarSizeInBits();
@@ -1236,10 +1249,10 @@
     (SrcBits == DstBits ? Instruction::BitCast :
      (SrcBits > DstBits ? Instruction::Trunc :
       (isSigned ? Instruction::SExt : Instruction::ZExt)));
-  return getCast(opcode, C, Ty);
+  return getCast(opcode, C, Ty, DoFold);
 }
 
-Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty, bool DoFold) {
   assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
          "Invalid cast");
   unsigned SrcBits = C->getType()->getScalarSizeInBits();
@@ -1248,10 +1261,10 @@
     return C; // Avoid a useless cast
   Instruction::CastOps opcode =
     (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt);
-  return getCast(opcode, C, Ty);
+  return getCast(opcode, C, Ty, DoFold);
 }
 
-Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty, bool DoFold) {
 #ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
@@ -1262,10 +1275,13 @@
   assert(C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
          "SrcTy must be larger than DestTy for Trunc!");
 
-  return getFoldedCast(Instruction::Trunc, C, Ty);
+  if (DoFold)
+    return getFoldedCast(Instruction::Trunc, C, Ty);
+  else
+    return getNoFoldCast(Instruction::Trunc, C, Ty);
 }
 
-Constant *ConstantExpr::getSExt(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getSExt(Constant *C, const Type *Ty, bool DoFold) {
 #ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
@@ -1276,10 +1292,13 @@
   assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
          "SrcTy must be smaller than DestTy for SExt!");
 
-  return getFoldedCast(Instruction::SExt, C, Ty);
+  if (DoFold)
+    return getFoldedCast(Instruction::SExt, C, Ty);
+  else
+    return getNoFoldCast(Instruction::SExt, C, Ty);
 }
 
-Constant *ConstantExpr::getZExt(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getZExt(Constant *C, const Type *Ty, bool DoFold) {
 #ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
@@ -1290,10 +1309,13 @@
   assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
          "SrcTy must be smaller than DestTy for ZExt!");
 
-  return getFoldedCast(Instruction::ZExt, C, Ty);
+  if (DoFold)
+    return getFoldedCast(Instruction::ZExt, C, Ty);
+  else
+    return getNoFoldCast(Instruction::ZExt, C, Ty);
 }
 
-Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty, bool DoFold) {
 #ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
@@ -1302,10 +1324,13 @@
   assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
          C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
          "This is an illegal floating point truncation!");
-  return getFoldedCast(Instruction::FPTrunc, C, Ty);
+  if (DoFold)
+    return getFoldedCast(Instruction::FPTrunc, C, Ty);
+  else
+    return getNoFoldCast(Instruction::FPTrunc, C, Ty);
 }
 
-Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty, bool DoFold) {
 #ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
@@ -1314,10 +1339,13 @@
   assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
          C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
          "This is an illegal floating point extension!");
-  return getFoldedCast(Instruction::FPExt, C, Ty);
+  if (DoFold)
+    return getFoldedCast(Instruction::FPExt, C, Ty);
+  else
+    return getNoFoldCast(Instruction::FPExt, C, Ty);
 }
 
-Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty, bool DoFold) {
 #ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
@@ -1325,10 +1353,13 @@
   assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
   assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() &&
          "This is an illegal uint to floating point cast!");
-  return getFoldedCast(Instruction::UIToFP, C, Ty);
+  if (DoFold)
+    return getFoldedCast(Instruction::UIToFP, C, Ty);
+  else
+    return getNoFoldCast(Instruction::UIToFP, C, Ty);
 }
 
-Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty, bool DoFold) {
 #ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
@@ -1336,10 +1367,13 @@
   assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
   assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() &&
          "This is an illegal sint to floating point cast!");
-  return getFoldedCast(Instruction::SIToFP, C, Ty);
+  if (DoFold)
+    return getFoldedCast(Instruction::SIToFP, C, Ty);
+  else
+    return getNoFoldCast(Instruction::SIToFP, C, Ty);
 }
 
-Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty, bool DoFold) {
 #ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
@@ -1347,10 +1381,13 @@
   assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
   assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() &&
          "This is an illegal floating point to uint cast!");
-  return getFoldedCast(Instruction::FPToUI, C, Ty);
+  if (DoFold)
+    return getFoldedCast(Instruction::FPToUI, C, Ty);
+  else
+    return getNoFoldCast(Instruction::FPToUI, C, Ty);
 }
 
-Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty) {
+Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty, bool DoFold) {
 #ifndef NDEBUG
   bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
   bool toVec = Ty->getTypeID() == Type::VectorTyID;
@@ -1358,22 +1395,31 @@
   assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
   assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() &&
          "This is an illegal floating point to sint cast!");
-  return getFoldedCast(Instruction::FPToSI, C, Ty);
+  if (DoFold)
+    return getFoldedCast(Instruction::FPToSI, C, Ty);
+  else
+    return getNoFoldCast(Instruction::FPToSI, C, Ty);
 }
 
-Constant *ConstantExpr::getPtrToInt(Constant *C, const Type *DstTy) {
+Constant *ConstantExpr::getPtrToInt(Constant *C, const Type *DstTy, bool DoFold) {
   assert(C->getType()->isPointerTy() && "PtrToInt source must be pointer");
   assert(DstTy->isIntegerTy() && "PtrToInt destination must be integral");
-  return getFoldedCast(Instruction::PtrToInt, C, DstTy);
+  if (DoFold)
+    return getFoldedCast(Instruction::PtrToInt, C, DstTy);
+  else
+    return getNoFoldCast(Instruction::PtrToInt, C, DstTy);
 }
 
-Constant *ConstantExpr::getIntToPtr(Constant *C, const Type *DstTy) {
+Constant *ConstantExpr::getIntToPtr(Constant *C, const Type *DstTy, bool DoFold) {
   assert(C->getType()->isIntegerTy() && "IntToPtr source must be integral");
   assert(DstTy->isPointerTy() && "IntToPtr destination must be a pointer");
-  return getFoldedCast(Instruction::IntToPtr, C, DstTy);
+  if (DoFold)
+    return getFoldedCast(Instruction::IntToPtr, C, DstTy);
+  else
+    return getNoFoldCast(Instruction::IntToPtr, C, DstTy);
 }
 
-Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
+Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy, bool DoFold) {
   assert(CastInst::castIsValid(Instruction::BitCast, C, DstTy) &&
          "Invalid constantexpr bitcast!");
   
@@ -1381,12 +1427,15 @@
   // speedily.
   if (C->getType() == DstTy) return C;
   
-  return getFoldedCast(Instruction::BitCast, C, DstTy);
+  if (DoFold)
+    return getFoldedCast(Instruction::BitCast, C, DstTy);
+  else
+    return getNoFoldCast(Instruction::BitCast, C, DstTy);
 }
 
 Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
                               Constant *C1, Constant *C2,
-                              unsigned Flags) {
+                              unsigned Flags, bool DoFold) {
   // Check the operands for consistency first
   assert(Opcode >= Instruction::BinaryOpsBegin &&
          Opcode <  Instruction::BinaryOpsEnd   &&
@@ -1394,9 +1443,10 @@
   assert(C1->getType() == C2->getType() &&
          "Operand types in binary constant expression should match");
 
-  if (ReqTy == C1->getType() || ReqTy == Type::getInt1Ty(ReqTy->getContext()))
-    if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2))
-      return FC;          // Fold a few common cases...
+  if (DoFold)
+    if (ReqTy == C1->getType() || ReqTy == Type::getInt1Ty(ReqTy->getContext()))
+      if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2))
+        return FC;          // Fold a few common cases...
 
   std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
   ExprMapKeyType Key(Opcode, argVec, 0, Flags);
@@ -1406,7 +1456,7 @@
 }
 
 Constant *ConstantExpr::getCompareTy(unsigned short predicate,
-                                     Constant *C1, Constant *C2) {
+                                     Constant *C1, Constant *C2, bool DoFold) {
   switch (predicate) {
     default: llvm_unreachable("Invalid CmpInst predicate");
     case CmpInst::FCMP_FALSE: case CmpInst::FCMP_OEQ: case CmpInst::FCMP_OGT:
@@ -1415,18 +1465,18 @@
     case CmpInst::FCMP_UEQ:   case CmpInst::FCMP_UGT: case CmpInst::FCMP_UGE:
     case CmpInst::FCMP_ULT:   case CmpInst::FCMP_ULE: case CmpInst::FCMP_UNE:
     case CmpInst::FCMP_TRUE:
-      return getFCmp(predicate, C1, C2);
+      return getFCmp(predicate, C1, C2, DoFold);
 
     case CmpInst::ICMP_EQ:  case CmpInst::ICMP_NE:  case CmpInst::ICMP_UGT:
     case CmpInst::ICMP_UGE: case CmpInst::ICMP_ULT: case CmpInst::ICMP_ULE:
     case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: case CmpInst::ICMP_SLT:
     case CmpInst::ICMP_SLE:
-      return getICmp(predicate, C1, C2);
+      return getICmp(predicate, C1, C2, DoFold);
   }
 }
 
 Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
-                            unsigned Flags) {
+                            unsigned Flags, bool DoFold) {
 #ifndef NDEBUG
   switch (Opcode) {
   case Instruction::Add:
@@ -1485,20 +1535,20 @@
   }
 #endif
 
-  return getTy(C1->getType(), Opcode, C1, C2, Flags);
+  return getTy(C1->getType(), Opcode, C1, C2, Flags, DoFold);
 }
 
-Constant *ConstantExpr::getSizeOf(const Type* Ty) {
+Constant *ConstantExpr::getSizeOf(const Type* Ty, bool DoFold) {
   // sizeof is implemented as: (i64) gep (Ty*)null, 1
   // Note that a non-inbounds gep is used, as null isn't within any object.
   Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
   Constant *GEP = getGetElementPtr(
                  Constant::getNullValue(PointerType::getUnqual(Ty)), &GEPIdx, 1);
   return getPtrToInt(GEP, 
-                     Type::getInt64Ty(Ty->getContext()));
+                     Type::getInt64Ty(Ty->getContext()), DoFold);
 }
 
-Constant *ConstantExpr::getAlignOf(const Type* Ty) {
+Constant *ConstantExpr::getAlignOf(const Type* Ty, bool DoFold) {
   // alignof is implemented as: (i64) gep ({i1,Ty}*)null, 0, 1
   // Note that a non-inbounds gep is used, as null isn't within any object.
   const Type *AligningTy = StructType::get(Ty->getContext(),
@@ -1509,15 +1559,15 @@
   Constant *Indices[2] = { Zero, One };
   Constant *GEP = getGetElementPtr(NullPtr, Indices, 2);
   return getPtrToInt(GEP,
-                     Type::getInt64Ty(Ty->getContext()));
+                     Type::getInt64Ty(Ty->getContext()), DoFold);
 }
 
-Constant *ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) {
+Constant *ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo, bool DoFold) {
   return getOffsetOf(STy, ConstantInt::get(Type::getInt32Ty(STy->getContext()),
-                                           FieldNo));
+                                           FieldNo), DoFold);
 }
 
-Constant *ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) {
+Constant *ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo, bool DoFold) {
   // offsetof is implemented as: (i64) gep (Ty*)null, 0, FieldNo
   // Note that a non-inbounds gep is used, as null isn't within any object.
   Constant *GEPIdx[] = {
@@ -1527,22 +1577,23 @@
   Constant *GEP = getGetElementPtr(
                 Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx, 2);
   return getPtrToInt(GEP,
-                     Type::getInt64Ty(Ty->getContext()));
+                     Type::getInt64Ty(Ty->getContext()), DoFold);
 }
 
 Constant *ConstantExpr::getCompare(unsigned short pred, 
-                            Constant *C1, Constant *C2) {
+                            Constant *C1, Constant *C2, bool DoFold) {
   assert(C1->getType() == C2->getType() && "Op types should be identical!");
-  return getCompareTy(pred, C1, C2);
+  return getCompareTy(pred, C1, C2, DoFold);
 }
 
 Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
-                                    Constant *V1, Constant *V2) {
+                                    Constant *V1, Constant *V2, bool DoFold) {
   assert(!SelectInst::areInvalidOperands(C, V1, V2)&&"Invalid select operands");
 
-  if (ReqTy == V1->getType())
-    if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2))
-      return SC;        // Fold common cases
+  if (DoFold)
+    if (ReqTy == V1->getType())
+      if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2))
+        return SC;        // Fold common cases
 
   std::vector<Constant*> argVec(3, C);
   argVec[1] = V1;
@@ -1556,14 +1607,15 @@
 template<typename IndexTy>
 Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
                                            IndexTy const *Idxs,
-                                           unsigned NumIdx, bool InBounds) {
+                                           unsigned NumIdx, bool InBounds, bool DoFold) {
   assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs,
                                            Idxs+NumIdx) ==
          cast<PointerType>(ReqTy)->getElementType() &&
          "GEP indices invalid!");
 
-  if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs, NumIdx))
-    return FC;          // Fold a few common cases.
+  if (DoFold)
+    if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs, NumIdx))
+      return FC;          // Fold a few common cases.
 
   assert(C->getType()->isPointerTy() &&
          "Non-pointer type for constant GetElementPtr expression");
@@ -1582,33 +1634,34 @@
 
 template<typename IndexTy>
 Constant *ConstantExpr::getGetElementPtrImpl(Constant *C, IndexTy const *Idxs,
-                                             unsigned NumIdx, bool InBounds) {
+                                             unsigned NumIdx, bool InBounds, bool DoFold) {
   // Get the result type of the getelementptr!
   const Type *Ty = 
     GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx);
   assert(Ty && "GEP indices invalid!");
   unsigned As = cast<PointerType>(C->getType())->getAddressSpace();
-  return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx,InBounds);
+  return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx, InBounds, DoFold);
 }
 
 Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
-                                         unsigned NumIdx, bool InBounds) {
-  return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds);
+                                         unsigned NumIdx, bool InBounds, bool DoFold) {
+  return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds, DoFold);
 }
 
 Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant *const *Idxs,
-                                         unsigned NumIdx, bool InBounds) {
-  return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds);
+                                         unsigned NumIdx, bool InBounds, bool DoFold) {
+  return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds, DoFold);
 }
 
 Constant *
-ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) {
+ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS, bool DoFold) {
   assert(LHS->getType() == RHS->getType());
   assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE && 
          pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate");
 
-  if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS))
-    return FC;          // Fold a few common cases...
+  if (DoFold)
+    if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS))
+      return FC;          // Fold a few common cases...
 
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> ArgVec;
@@ -1626,12 +1679,13 @@
 }
 
 Constant *
-ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) {
+ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS, bool DoFold) {
   assert(LHS->getType() == RHS->getType());
   assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate");
 
-  if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS))
-    return FC;          // Fold a few common cases...
+  if (DoFold)
+    if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS))
+      return FC;          // Fold a few common cases...
 
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> ArgVec;
@@ -1649,9 +1703,10 @@
 }
 
 Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
-                                            Constant *Idx) {
-  if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
-    return FC;          // Fold a few common cases.
+                                            Constant *Idx, bool DoFold) {
+  if (DoFold)
+    if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
+      return FC;          // Fold a few common cases.
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> ArgVec(1, Val);
   ArgVec.push_back(Idx);
@@ -1661,19 +1716,20 @@
   return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
 }
 
-Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) {
+Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx, bool DoFold) {
   assert(Val->getType()->isVectorTy() &&
          "Tried to create extractelement operation on non-vector type!");
   assert(Idx->getType()->isIntegerTy(32) &&
          "Extractelement index must be i32 type!");
   return getExtractElementTy(cast<VectorType>(Val->getType())->getElementType(),
-                             Val, Idx);
+                             Val, Idx, DoFold);
 }
 
 Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val,
-                                           Constant *Elt, Constant *Idx) {
-  if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx))
-    return FC;          // Fold a few common cases.
+                                           Constant *Elt, Constant *Idx, bool DoFold) {
+  if (DoFold)
+    if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx))
+      return FC;          // Fold a few common cases.
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> ArgVec(1, Val);
   ArgVec.push_back(Elt);
@@ -1685,20 +1741,21 @@
 }
 
 Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, 
-                                         Constant *Idx) {
+                                         Constant *Idx, bool DoFold) {
   assert(Val->getType()->isVectorTy() &&
          "Tried to create insertelement operation on non-vector type!");
   assert(Elt->getType() == cast<VectorType>(Val->getType())->getElementType()
          && "Insertelement types must match!");
   assert(Idx->getType()->isIntegerTy(32) &&
          "Insertelement index must be i32 type!");
-  return getInsertElementTy(Val->getType(), Val, Elt, Idx);
+  return getInsertElementTy(Val->getType(), Val, Elt, Idx, DoFold);
 }
 
 Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1,
-                                           Constant *V2, Constant *Mask) {
-  if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask))
-    return FC;          // Fold a few common cases...
+                                           Constant *V2, Constant *Mask, bool DoFold) {
+  if (DoFold)
+    if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask))
+      return FC;          // Fold a few common cases...
   // Look up the constant in the table first to ensure uniqueness
   std::vector<Constant*> ArgVec(1, V1);
   ArgVec.push_back(V2);
@@ -1710,19 +1767,19 @@
 }
 
 Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, 
-                                         Constant *Mask) {
+                                         Constant *Mask, bool DoFold) {
   assert(ShuffleVectorInst::isValidOperands(V1, V2, Mask) &&
          "Invalid shuffle vector constant expr operands!");
 
   unsigned NElts = cast<VectorType>(Mask->getType())->getNumElements();
   const Type *EltTy = cast<VectorType>(V1->getType())->getElementType();
   const Type *ShufTy = VectorType::get(EltTy, NElts);
-  return getShuffleVectorTy(ShufTy, V1, V2, Mask);
+  return getShuffleVectorTy(ShufTy, V1, V2, Mask, DoFold);
 }
 
 Constant *ConstantExpr::getInsertValueTy(const Type *ReqTy, Constant *Agg,
                                          Constant *Val,
-                                        const unsigned *Idxs, unsigned NumIdx) {
+                                        const unsigned *Idxs, unsigned NumIdx, bool DoFold) {
   assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs,
                                           Idxs+NumIdx) == Val->getType() &&
          "insertvalue indices invalid!");
@@ -1730,13 +1787,26 @@
          "insertvalue type invalid!");
   assert(Agg->getType()->isFirstClassType() &&
          "Non-first-class type for constant InsertValue expression");
-  Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx);
-  assert(FC && "InsertValue constant expr couldn't be folded!");
-  return FC;
+  if (DoFold){
+    Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx);
+    assert(FC && "InsertValue constant expr couldn't be folded!");
+    return FC;
+  }
+  else {
+    std::vector<Constant*> ArgVec(1, Agg);
+    ArgVec.push_back(Val);
+    SmallVector<unsigned, 4> IdxList;
+    for (unsigned i = 0; i < NumIdx; i++)
+      IdxList.push_back(Idxs[i]);
+    const ExprMapKeyType Key(Instruction::InsertValue, ArgVec, 0, 0, IdxList);
+
+    LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
+    return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
+  }
 }
 
 Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
-                                     const unsigned *IdxList, unsigned NumIdx) {
+                                     const unsigned *IdxList, unsigned NumIdx, bool DoFold) {
   assert(Agg->getType()->isFirstClassType() &&
          "Tried to create insertelement operation on non-first-class type!");
 
@@ -1746,137 +1816,149 @@
     ExtractValueInst::getIndexedType(Agg->getType(), IdxList, IdxList+NumIdx);
 #endif
   assert(ValTy == Val->getType() && "insertvalue indices invalid!");
-  return getInsertValueTy(ReqTy, Agg, Val, IdxList, NumIdx);
+  return getInsertValueTy(ReqTy, Agg, Val, IdxList, NumIdx, DoFold);
 }
 
 Constant *ConstantExpr::getExtractValueTy(const Type *ReqTy, Constant *Agg,
-                                        const unsigned *Idxs, unsigned NumIdx) {
+                                        const unsigned *Idxs, unsigned NumIdx, bool DoFold) {
   assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs,
                                           Idxs+NumIdx) == ReqTy &&
          "extractvalue indices invalid!");
   assert(Agg->getType()->isFirstClassType() &&
          "Non-first-class type for constant extractvalue expression");
-  Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx);
-  assert(FC && "ExtractValue constant expr couldn't be folded!");
-  return FC;
+  if (DoFold) {
+    Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx);
+    assert(FC && "ExtractValue constant expr couldn't be folded!");
+    return FC;
+  }
+  else {
+    std::vector<Constant*> ArgVec(1, Agg);
+    SmallVector<unsigned, 4> IdxList;
+    for (unsigned i = 0; i < NumIdx; i++)
+      IdxList.push_back(Idxs[i]);
+    const ExprMapKeyType Key(Instruction::InsertValue, ArgVec, 0, 0, IdxList);
+
+    LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
+    return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
+  }
 }
 
 Constant *ConstantExpr::getExtractValue(Constant *Agg,
-                                     const unsigned *IdxList, unsigned NumIdx) {
+                                     const unsigned *IdxList, unsigned NumIdx, bool DoFold) {
   assert(Agg->getType()->isFirstClassType() &&
          "Tried to create extractelement operation on non-first-class type!");
 
   const Type *ReqTy =
     ExtractValueInst::getIndexedType(Agg->getType(), IdxList, IdxList+NumIdx);
   assert(ReqTy && "extractvalue indices invalid!");
-  return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx);
+  return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx, DoFold);
 }
 
-Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) {
+Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW, bool DoFold) {
   assert(C->getType()->isIntOrIntVectorTy() &&
          "Cannot NEG a nonintegral value!");
   return getSub(ConstantFP::getZeroValueForNegation(C->getType()),
-                C, HasNUW, HasNSW);
+                C, HasNUW, HasNSW, DoFold);
 }
 
-Constant *ConstantExpr::getFNeg(Constant *C) {
+Constant *ConstantExpr::getFNeg(Constant *C, bool DoFold) {
   assert(C->getType()->isFPOrFPVectorTy() &&
          "Cannot FNEG a non-floating-point value!");
-  return getFSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
+  return getFSub(ConstantFP::getZeroValueForNegation(C->getType()), C, DoFold);
 }
 
-Constant *ConstantExpr::getNot(Constant *C) {
+Constant *ConstantExpr::getNot(Constant *C, bool DoFold) {
   assert(C->getType()->isIntOrIntVectorTy() &&
          "Cannot NOT a nonintegral value!");
-  return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType()));
+  return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType()), DoFold);
 }
 
 Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2,
-                               bool HasNUW, bool HasNSW) {
+                               bool HasNUW, bool HasNSW, bool DoFold) {
   unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
                    (HasNSW ? OverflowingBinaryOperator::NoSignedWrap   : 0);
-  return get(Instruction::Add, C1, C2, Flags);
+  return get(Instruction::Add, C1, C2, Flags, DoFold);
 }
 
-Constant *ConstantExpr::getFAdd(Constant *C1, Constant *C2) {
-  return get(Instruction::FAdd, C1, C2);
+Constant *ConstantExpr::getFAdd(Constant *C1, Constant *C2, bool DoFold) {
+  return get(Instruction::FAdd, C1, C2, DoFold);
 }
 
 Constant *ConstantExpr::getSub(Constant *C1, Constant *C2,
-                               bool HasNUW, bool HasNSW) {
+                               bool HasNUW, bool HasNSW, bool DoFold) {
   unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
                    (HasNSW ? OverflowingBinaryOperator::NoSignedWrap   : 0);
-  return get(Instruction::Sub, C1, C2, Flags);
+  return get(Instruction::Sub, C1, C2, Flags, DoFold);
 }
 
-Constant *ConstantExpr::getFSub(Constant *C1, Constant *C2) {
-  return get(Instruction::FSub, C1, C2);
+Constant *ConstantExpr::getFSub(Constant *C1, Constant *C2, bool DoFold) {
+  return get(Instruction::FSub, C1, C2, DoFold);
 }
 
 Constant *ConstantExpr::getMul(Constant *C1, Constant *C2,
-                               bool HasNUW, bool HasNSW) {
+                               bool HasNUW, bool HasNSW, bool DoFold) {
   unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
                    (HasNSW ? OverflowingBinaryOperator::NoSignedWrap   : 0);
-  return get(Instruction::Mul, C1, C2, Flags);
+  return get(Instruction::Mul, C1, C2, Flags, DoFold);
 }
 
-Constant *ConstantExpr::getFMul(Constant *C1, Constant *C2) {
-  return get(Instruction::FMul, C1, C2);
+Constant *ConstantExpr::getFMul(Constant *C1, Constant *C2, bool DoFold) {
+  return get(Instruction::FMul, C1, C2, DoFold);
 }
 
-Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2, bool isExact) {
+Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2, bool isExact, bool DoFold) {
   return get(Instruction::UDiv, C1, C2,
-             isExact ? PossiblyExactOperator::IsExact : 0);
+             isExact ? PossiblyExactOperator::IsExact : 0, DoFold);
 }
 
-Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2, bool isExact) {
+Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2, bool isExact, bool DoFold) {
   return get(Instruction::SDiv, C1, C2,
-             isExact ? PossiblyExactOperator::IsExact : 0);
+             isExact ? PossiblyExactOperator::IsExact : 0, DoFold);
 }
 
-Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) {
-  return get(Instruction::FDiv, C1, C2);
+Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2, bool DoFold) {
+  return get(Instruction::FDiv, C1, C2, DoFold);
 }
 
-Constant *ConstantExpr::getURem(Constant *C1, Constant *C2) {
-  return get(Instruction::URem, C1, C2);
+Constant *ConstantExpr::getURem(Constant *C1, Constant *C2, bool DoFold) {
+  return get(Instruction::URem, C1, C2, DoFold);
 }
 
-Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2) {
-  return get(Instruction::SRem, C1, C2);
+Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2, bool DoFold) {
+  return get(Instruction::SRem, C1, C2, DoFold);
 }
 
-Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2) {
-  return get(Instruction::FRem, C1, C2);
+Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2, bool DoFold) {
+  return get(Instruction::FRem, C1, C2, DoFold);
 }
 
-Constant *ConstantExpr::getAnd(Constant *C1, Constant *C2) {
-  return get(Instruction::And, C1, C2);
+Constant *ConstantExpr::getAnd(Constant *C1, Constant *C2, bool DoFold) {
+  return get(Instruction::And, C1, C2, DoFold);
 }
 
-Constant *ConstantExpr::getOr(Constant *C1, Constant *C2) {
-  return get(Instruction::Or, C1, C2);
+Constant *ConstantExpr::getOr(Constant *C1, Constant *C2, bool DoFold) {
+  return get(Instruction::Or, C1, C2, DoFold);
 }
 
-Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
-  return get(Instruction::Xor, C1, C2);
+Constant *ConstantExpr::getXor(Constant *C1, Constant *C2, bool DoFold) {
+  return get(Instruction::Xor, C1, C2, DoFold);
 }
 
 Constant *ConstantExpr::getShl(Constant *C1, Constant *C2,
-                               bool HasNUW, bool HasNSW) {
+                               bool HasNUW, bool HasNSW, bool DoFold) {
   unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
                    (HasNSW ? OverflowingBinaryOperator::NoSignedWrap   : 0);
-  return get(Instruction::Shl, C1, C2, Flags);
+  return get(Instruction::Shl, C1, C2, Flags, DoFold);
 }
 
-Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2, bool isExact) {
+Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2, bool isExact, bool DoFold) {
   return get(Instruction::LShr, C1, C2,
-             isExact ? PossiblyExactOperator::IsExact : 0);
+             isExact ? PossiblyExactOperator::IsExact : 0, DoFold);
 }
 
-Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) {
+Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact, bool DoFold) {
   return get(Instruction::AShr, C1, C2,
-             isExact ? PossiblyExactOperator::IsExact : 0);
+             isExact ? PossiblyExactOperator::IsExact : 0, DoFold);
 }
 
 // destroyConstant - Remove the constant from the constant table...
