This situation can occur:
[oota-llvm.git] / lib / VMCore / Constants.cpp
index d0c837335dcee118e4accb91a1451a9e34b9797c..e6398a3bbd3b5c9dd243f5e9c0ab5e94b718e3f3 100644 (file)
@@ -367,7 +367,7 @@ ConstantArray::ConstantArray(const ArrayType *T,
             (T->isAbstract() &&
              C->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
            "Initializer for array element doesn't match array element type!");
-    OL->init(C, this);
+    *OL = C;
   }
 }
 
@@ -389,7 +389,7 @@ ConstantStruct::ConstantStruct(const StructType *T,
              T->getElementType(I-V.begin())->getTypeID() == 
                    C->getType()->getTypeID())) &&
            "Initializer for struct element doesn't match struct element type!");
-    OL->init(C, this);
+    *OL = C;
   }
 }
 
@@ -407,7 +407,7 @@ ConstantVector::ConstantVector(const VectorType *T,
             (T->isAbstract() &&
              C->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
            "Initializer for vector element doesn't match vector element type!");
-    OL->init(C, this);
+    *OL = C;
   }
 }
 
@@ -445,8 +445,8 @@ public:
   }
   BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
     : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
-    Op<0>().init(C1, this);
-    Op<1>().init(C2, this);
+    Op<0>() = C1;
+    Op<1>() = C2;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -463,9 +463,9 @@ public:
   }
   SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
     : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
-    Op<0>().init(C1, this);
-    Op<1>().init(C2, this);
-    Op<2>().init(C3, this);
+    Op<0>() = C1;
+    Op<1>() = C2;
+    Op<2>() = C3;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -484,8 +484,8 @@ public:
   ExtractElementConstantExpr(Constant *C1, Constant *C2)
     : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), 
                    Instruction::ExtractElement, &Op<0>(), 2) {
-    Op<0>().init(C1, this);
-    Op<1>().init(C2, this);
+    Op<0>() = C1;
+    Op<1>() = C2;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -504,9 +504,9 @@ public:
   InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
     : ConstantExpr(C1->getType(), Instruction::InsertElement, 
                    &Op<0>(), 3) {
-    Op<0>().init(C1, this);
-    Op<1>().init(C2, this);
-    Op<2>().init(C3, this);
+    Op<0>() = C1;
+    Op<1>() = C2;
+    Op<2>() = C3;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -525,23 +525,77 @@ public:
   ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
   : ConstantExpr(C1->getType(), Instruction::ShuffleVector, 
                  &Op<0>(), 3) {
-    Op<0>().init(C1, this);
-    Op<1>().init(C2, this);
-    Op<2>().init(C3, this);
+    Op<0>() = C1;
+    Op<1>() = C2;
+    Op<2>() = C3;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 };
 
+/// ExtractValueConstantExpr - This class is private to
+/// Constants.cpp, and is used behind the scenes to implement
+/// extractvalue constant exprs.
+class VISIBILITY_HIDDEN ExtractValueConstantExpr : public ConstantExpr {
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
+public:
+  // allocate space for exactly one operand
+  void *operator new(size_t s) {
+    return User::operator new(s, 1);
+  }
+  ExtractValueConstantExpr(Constant *Agg,
+                           const SmallVector<unsigned, 4> &IdxList,
+                           const Type *DestTy)
+    : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
+      Indices(IdxList) {
+    Op<0>() = Agg;
+  }
+
+  /// Indices - These identify which value to extract.
+  const SmallVector<unsigned, 4> Indices;
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+};
+
+/// InsertValueConstantExpr - This class is private to
+/// Constants.cpp, and is used behind the scenes to implement
+/// insertvalue constant exprs.
+class VISIBILITY_HIDDEN InsertValueConstantExpr : public ConstantExpr {
+  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
+public:
+  // allocate space for exactly one operand
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
+  InsertValueConstantExpr(Constant *Agg, Constant *Val,
+                          const SmallVector<unsigned, 4> &IdxList,
+                          const Type *DestTy)
+    : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
+      Indices(IdxList) {
+    Op<0>() = Agg;
+    Op<1>() = Val;
+  }
+
+  /// Indices - These identify the position for the insertion.
+  const SmallVector<unsigned, 4> Indices;
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+};
+
+
 /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
 /// used behind the scenes to implement getelementpr constant exprs.
 class VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr {
   GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
                             const Type *DestTy);
 public:
-  static GetElementPtrConstantExpr *Create(Constant *C, const std::vector<Constant*> &IdxList,
+  static GetElementPtrConstantExpr *Create(Constant *C,
+                                           const std::vector<Constant*>&IdxList,
                                            const Type *DestTy) {
-    return new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
+    return new(IdxList.size() + 1)
+      GetElementPtrConstantExpr(C, IdxList, DestTy);
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -557,11 +611,11 @@ struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr {
     return User::operator new(s, 2);
   }
   unsigned short predicate;
-  CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred, 
-                      Constant* LHS, Constant* RHS)
-    : ConstantExpr(Type::Int1Ty, opc, &Op<0>(), 2), predicate(pred) {
-    Op<0>().init(LHS, this);
-    Op<1>().init(RHS, this);
+  CompareConstantExpr(const Type *ty, Instruction::OtherOps opc,
+                      unsigned short pred,  Constant* LHS, Constant* RHS)
+    : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
+    Op<0>() = LHS;
+    Op<1>() = RHS;
   }
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -599,6 +653,15 @@ struct OperandTraits<ShuffleVectorConstantExpr> : FixedNumOperandTraits<3> {
 };
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
 
+template <>
+struct OperandTraits<ExtractValueConstantExpr> : FixedNumOperandTraits<1> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
+
+template <>
+struct OperandTraits<InsertValueConstantExpr> : FixedNumOperandTraits<2> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
 
 template <>
 struct OperandTraits<GetElementPtrConstantExpr> : VariadicOperandTraits<1> {
@@ -612,9 +675,9 @@ GetElementPtrConstantExpr::GetElementPtrConstantExpr
                    OperandTraits<GetElementPtrConstantExpr>::op_end(this)
                    - (IdxList.size()+1),
                    IdxList.size()+1) {
-  OperandList[0].init(C, this);
+  OperandList[0] = C;
   for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
-    OperandList[i+1].init(IdxList[i], this);
+    OperandList[i+1] = IdxList[i];
 }
 
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
@@ -640,6 +703,19 @@ bool ConstantExpr::isCompare() const {
   return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp;
 }
 
+bool ConstantExpr::hasIndices() const {
+  return getOpcode() == Instruction::ExtractValue ||
+         getOpcode() == Instruction::InsertValue;
+}
+
+const SmallVector<unsigned, 4> &ConstantExpr::getIndices() const {
+  if (const ExtractValueConstantExpr *EVCE =
+        dyn_cast<ExtractValueConstantExpr>(this))
+    return EVCE->Indices;
+
+  return cast<InsertValueConstantExpr>(this)->Indices;
+}
+
 /// ConstantExpr::get* - Return some common constants without having to
 /// specify the full Instruction::OPCODE identifier.
 ///
@@ -690,7 +766,10 @@ Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
   return get(Instruction::Xor, C1, C2);
 }
 unsigned ConstantExpr::getPredicate() const {
-  assert(getOpcode() == Instruction::FCmp || getOpcode() == Instruction::ICmp);
+  assert(getOpcode() == Instruction::FCmp || 
+         getOpcode() == Instruction::ICmp ||
+         getOpcode() == Instruction::VFCmp ||
+         getOpcode() == Instruction::VICmp);
   return ((const CompareConstantExpr*)this)->predicate;
 }
 Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) {
@@ -747,11 +826,24 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
     Op1 = (OpNo == 1) ? Op : getOperand(1);
     Op2 = (OpNo == 2) ? Op : getOperand(2);
     return ConstantExpr::getShuffleVector(Op0, Op1, Op2);
+  case Instruction::InsertValue: {
+    const SmallVector<unsigned, 4> &Indices = getIndices();
+    Op0 = (OpNo == 0) ? Op : getOperand(0);
+    Op1 = (OpNo == 1) ? Op : getOperand(1);
+    return ConstantExpr::getInsertValue(Op0, Op1,
+                                        &Indices[0], Indices.size());
+  }
+  case Instruction::ExtractValue: {
+    assert(OpNo == 0 && "ExtractaValue has only one operand!");
+    const SmallVector<unsigned, 4> &Indices = getIndices();
+    return
+      ConstantExpr::getExtractValue(Op, &Indices[0], Indices.size());
+  }
   case Instruction::GetElementPtr: {
     SmallVector<Constant*, 8> Ops;
-    Ops.resize(getNumOperands());
+    Ops.resize(getNumOperands()-1);
     for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
-      Ops[i] = getOperand(i);
+      Ops[i-1] = getOperand(i);
     if (OpNo == 0)
       return ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
     Ops[OpNo-1] = Op;
@@ -802,6 +894,16 @@ getWithOperands(const std::vector<Constant*> &Ops) const {
     return ConstantExpr::getExtractElement(Ops[0], Ops[1]);
   case Instruction::ShuffleVector:
     return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
+  case Instruction::InsertValue: {
+    const SmallVector<unsigned, 4> &Indices = getIndices();
+    return ConstantExpr::getInsertValue(Ops[0], Ops[1],
+                                        &Indices[0], Indices.size());
+  }
+  case Instruction::ExtractValue: {
+    const SmallVector<unsigned, 4> &Indices = getIndices();
+    return ConstantExpr::getExtractValue(Ops[0],
+                                         &Indices[0], Indices.size());
+  }
   case Instruction::GetElementPtr:
     return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], Ops.size()-1);
   case Instruction::ICmp:
@@ -1511,22 +1613,33 @@ void UndefValue::destroyConstant() {
 //---- ConstantExpr::get() implementations...
 //
 
+namespace {
+
 struct ExprMapKeyType {
-  explicit ExprMapKeyType(unsigned opc, std::vector<Constant*> ops,
-      unsigned short pred = 0) : opcode(opc), predicate(pred), operands(ops) { }
+  typedef SmallVector<unsigned, 4> IndexList;
+
+  ExprMapKeyType(unsigned opc,
+      const std::vector<Constant*> &ops,
+      unsigned short pred = 0,
+      const IndexList &inds = IndexList())
+        : opcode(opc), predicate(pred), operands(ops), indices(inds) {}
   uint16_t opcode;
   uint16_t predicate;
   std::vector<Constant*> operands;
+  IndexList indices;
   bool operator==(const ExprMapKeyType& that) const {
     return this->opcode == that.opcode &&
            this->predicate == that.predicate &&
            this->operands == that.operands;
+           this->indices == that.indices;
   }
   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);
+       this->operands < that.operands) ||
+      (this->opcode == that.opcode && this->predicate == that.predicate &&
+       this->operands == that.operands && this->indices < that.indices);
   }
 
   bool operator!=(const ExprMapKeyType& that) const {
@@ -1534,6 +1647,8 @@ struct ExprMapKeyType {
   }
 };
 
+}
+
 namespace llvm {
   template<>
   struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
@@ -1555,6 +1670,11 @@ namespace llvm {
       if (V.opcode == Instruction::ShuffleVector)
         return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
                                              V.operands[2]);
+      if (V.opcode == Instruction::InsertValue)
+        return new InsertValueConstantExpr(V.operands[0], V.operands[1],
+                                           V.indices, Ty);
+      if (V.opcode == Instruction::ExtractValue)
+        return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
       if (V.opcode == Instruction::GetElementPtr) {
         std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
         return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty);
@@ -1564,10 +1684,16 @@ namespace llvm {
       // 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, 
+        return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate, 
                                        V.operands[0], V.operands[1]);
       if (V.opcode == Instruction::FCmp) 
-        return new CompareConstantExpr(Instruction::FCmp, V.predicate, 
+        return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate, 
+                                       V.operands[0], V.operands[1]);
+      if (V.opcode == Instruction::VICmp)
+        return new CompareConstantExpr(Ty, Instruction::VICmp, V.predicate, 
+                                       V.operands[0], V.operands[1]);
+      if (V.opcode == Instruction::VFCmp) 
+        return new CompareConstantExpr(Ty, Instruction::VFCmp, V.predicate, 
                                        V.operands[0], V.operands[1]);
       assert(0 && "Invalid ConstantExpr!");
       return 0;
@@ -1627,7 +1753,9 @@ static ExprMapKeyType getValType(ConstantExpr *CE) {
   for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
     Operands.push_back(cast<Constant>(CE->getOperand(i)));
   return ExprMapKeyType(CE->getOpcode(), Operands, 
-      CE->isCompare() ? CE->getPredicate() : 0);
+      CE->isCompare() ? CE->getPredicate() : 0,
+      CE->hasIndices() ?
+        CE->getIndices() : SmallVector<unsigned, 4>());
 }
 
 static ManagedStatic<ValueMap<ExprMapKeyType, Type,
@@ -1960,7 +2088,9 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
 Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
                                            Value* const *Idxs,
                                            unsigned NumIdx) {
-  assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true) &&
+  assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs,
+                                           Idxs+NumIdx) ==
+         cast<PointerType>(ReqTy)->getElementType() &&
          "GEP indices invalid!");
 
   if (Constant *FC = ConstantFoldGetElementPtr(C, (Constant**)Idxs, NumIdx))
@@ -1982,7 +2112,7 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
                                          unsigned NumIdx) {
   // Get the result type of the getelementptr!
   const Type *Ty = 
-    GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true);
+    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);
@@ -2029,6 +2159,79 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
   return ExprConstants->getOrCreate(Type::Int1Ty, Key);
 }
 
+Constant *
+ConstantExpr::getVICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+  assert(isa<VectorType>(LHS->getType()) &&
+         "Tried to create vicmp operation on non-vector type!");
+  assert(LHS->getType() == RHS->getType());
+  assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE && 
+         pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid VICmp Predicate");
+
+  const VectorType *VTy = cast<VectorType>(LHS->getType());
+  const Type *EltTy = VTy->getElementType();
+  unsigned NumElts = VTy->getNumElements();
+
+  SmallVector<Constant *, 8> Elts;
+  for (unsigned i = 0; i != NumElts; ++i) {
+    Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i),
+                                                        RHS->getOperand(i));
+    if (FC) {
+      uint64_t Val = cast<ConstantInt>(FC)->getZExtValue();
+      if (Val != 0ULL)
+        Elts.push_back(ConstantInt::getAllOnesValue(EltTy));
+      else
+        Elts.push_back(ConstantInt::get(EltTy, 0ULL));
+    }
+  }
+  if (Elts.size() == NumElts)
+    return ConstantVector::get(&Elts[0], Elts.size());
+
+  // Look up the constant in the table first to ensure uniqueness
+  std::vector<Constant*> ArgVec;
+  ArgVec.push_back(LHS);
+  ArgVec.push_back(RHS);
+  // Get the key type with both the opcode and predicate
+  const ExprMapKeyType Key(Instruction::VICmp, ArgVec, pred);
+  return ExprConstants->getOrCreate(LHS->getType(), Key);
+}
+
+Constant *
+ConstantExpr::getVFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+  assert(isa<VectorType>(LHS->getType()) &&
+         "Tried to create vfcmp operation on non-vector type!");
+  assert(LHS->getType() == RHS->getType());
+  assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid VFCmp Predicate");
+
+  const VectorType *VTy = cast<VectorType>(LHS->getType());
+  unsigned NumElts = VTy->getNumElements();
+  const Type *EltTy = VTy->getElementType();
+  const Type *REltTy = IntegerType::get(EltTy->getPrimitiveSizeInBits());
+  const Type *ResultTy = VectorType::get(REltTy, NumElts);
+
+  SmallVector<Constant *, 8> Elts;
+  for (unsigned i = 0; i != NumElts; ++i) {
+    Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i),
+                                                        RHS->getOperand(i));
+    if (FC) {
+      uint64_t Val = cast<ConstantInt>(FC)->getZExtValue();
+      if (Val != 0ULL)
+        Elts.push_back(ConstantInt::getAllOnesValue(REltTy));
+      else
+        Elts.push_back(ConstantInt::get(REltTy, 0ULL));
+    }
+  }
+  if (Elts.size() == NumElts)
+    return ConstantVector::get(&Elts[0], Elts.size());
+
+  // Look up the constant in the table first to ensure uniqueness
+  std::vector<Constant*> ArgVec;
+  ArgVec.push_back(LHS);
+  ArgVec.push_back(RHS);
+  // Get the key type with both the opcode and predicate
+  const ExprMapKeyType Key(Instruction::VFCmp, ArgVec, pred);
+  return ExprConstants->getOrCreate(ResultTy, Key);
+}
+
 Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
                                             Constant *Idx) {
   if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
@@ -2092,6 +2295,67 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
   return getShuffleVectorTy(V1->getType(), V1, V2, Mask);
 }
 
+Constant *ConstantExpr::getInsertValueTy(const Type *ReqTy, Constant *Agg,
+                                         Constant *Val,
+                                        const unsigned *Idxs, unsigned NumIdx) {
+  assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs,
+                                          Idxs+NumIdx) == Val->getType() &&
+         "insertvalue indices invalid!");
+  assert(Agg->getType() == ReqTy &&
+         "insertvalue type invalid!");
+  assert(Agg->getType()->isFirstClassType() &&
+         "Non-first-class type for constant InsertValue expression");
+  if (Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx))
+    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(Agg);
+  ArgVec.push_back(Val);
+  SmallVector<unsigned, 4> Indices(Idxs, Idxs + NumIdx);
+  const ExprMapKeyType Key(Instruction::InsertValue, ArgVec, 0, Indices);
+  return ExprConstants->getOrCreate(ReqTy, Key);
+}
+
+Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
+                                     const unsigned *IdxList, unsigned NumIdx) {
+  assert(Agg->getType()->isFirstClassType() &&
+         "Tried to create insertelement operation on non-first-class type!");
+
+  const Type *ReqTy = Agg->getType();
+  const Type *ValTy =
+    ExtractValueInst::getIndexedType(Agg->getType(), IdxList, IdxList+NumIdx);
+  assert(ValTy == Val->getType() && "insertvalue indices invalid!");
+  return getInsertValueTy(ReqTy, Agg, Val, IdxList, NumIdx);
+}
+
+Constant *ConstantExpr::getExtractValueTy(const Type *ReqTy, Constant *Agg,
+                                        const unsigned *Idxs, unsigned NumIdx) {
+  assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs,
+                                          Idxs+NumIdx) == ReqTy &&
+         "extractvalue indices invalid!");
+  assert(Agg->getType()->isFirstClassType() &&
+         "Non-first-class type for constant extractvalue expression");
+  if (Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx))
+    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(Agg);
+  SmallVector<unsigned, 4> Indices(Idxs, Idxs + NumIdx);
+  const ExprMapKeyType Key(Instruction::ExtractValue, ArgVec, 0, Indices);
+  return ExprConstants->getOrCreate(ReqTy, Key);
+}
+
+Constant *ConstantExpr::getExtractValue(Constant *Agg,
+                                     const unsigned *IdxList, unsigned NumIdx) {
+  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);
+}
+
 Constant *ConstantExpr::getZeroValueForNegationExpr(const Type *Ty) {
   if (const VectorType *PTy = dyn_cast<VectorType>(Ty))
     if (PTy->getElementType()->isFloatingPoint()) {
@@ -2317,6 +2581,22 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
     }
     Replacement = ConstantExpr::getGetElementPtr(Pointer,
                                                  &Indices[0], Indices.size());
+  } else if (getOpcode() == Instruction::ExtractValue) {
+    Constant *Agg = getOperand(0);
+    if (Agg == From) Agg = To;
+    
+    const SmallVector<unsigned, 4> &Indices = getIndices();
+    Replacement = ConstantExpr::getExtractValue(Agg,
+                                                &Indices[0], Indices.size());
+  } else if (getOpcode() == Instruction::InsertValue) {
+    Constant *Agg = getOperand(0);
+    Constant *Val = getOperand(1);
+    if (Agg == From) Agg = To;
+    if (Val == From) Val = To;
+    
+    const SmallVector<unsigned, 4> &Indices = getIndices();
+    Replacement = ConstantExpr::getInsertValue(Agg, Val,
+                                               &Indices[0], Indices.size());
   } else if (isCast()) {
     assert(getOperand(0) == From && "Cast only has one use!");
     Replacement = ConstantExpr::getCast(getOpcode(), To, getType());