fix Analysis/BasicAA/2004-12-08-BasicAACrash.ll by allowing opaque types.
[oota-llvm.git] / lib / VMCore / Instructions.cpp
index 3fb1c61b7227dace46674bce95542c5e6759417d..7f5d4615d187a4de8f8dc108354868d4a6c9cc4b 100644 (file)
@@ -25,72 +25,77 @@ using namespace llvm;
 //                            CallSite Class
 //===----------------------------------------------------------------------===//
 
+#define CALLSITE_DELEGATE_GETTER(METHOD) \
+  Instruction *II(getInstruction());     \
+  return isCall()                        \
+    ? cast<CallInst>(II)->METHOD         \
+    : cast<InvokeInst>(II)->METHOD
+
+#define CALLSITE_DELEGATE_SETTER(METHOD) \
+  Instruction *II(getInstruction());     \
+  if (isCall())                          \
+    cast<CallInst>(II)->METHOD;          \
+  else                                   \
+    cast<InvokeInst>(II)->METHOD
+
 CallSite::CallSite(Instruction *C) {
   assert((isa<CallInst>(C) || isa<InvokeInst>(C)) && "Not a call!");
-  I = C;
+  I.setPointer(C);
+  I.setInt(isa<CallInst>(C));
 }
 unsigned CallSite::getCallingConv() const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->getCallingConv();
-  else
-    return cast<InvokeInst>(I)->getCallingConv();
+  CALLSITE_DELEGATE_GETTER(getCallingConv());
 }
 void CallSite::setCallingConv(unsigned CC) {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    CI->setCallingConv(CC);
-  else
-    cast<InvokeInst>(I)->setCallingConv(CC);
+  CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
 }
-const PAListPtr &CallSite::getParamAttrs() const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->getParamAttrs();
-  else
-    return cast<InvokeInst>(I)->getParamAttrs();
+const AttrListPtr &CallSite::getAttributes() const {
+  CALLSITE_DELEGATE_GETTER(getAttributes());
 }
-void CallSite::setParamAttrs(const PAListPtr &PAL) {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    CI->setParamAttrs(PAL);
-  else
-    cast<InvokeInst>(I)->setParamAttrs(PAL);
+void CallSite::setAttributes(const AttrListPtr &PAL) {
+  CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
 }
-bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->paramHasAttr(i, attr);
-  else
-    return cast<InvokeInst>(I)->paramHasAttr(i, attr);
+bool CallSite::paramHasAttr(uint16_t i, Attributes attr) const {
+  CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr));
 }
 uint16_t CallSite::getParamAlignment(uint16_t i) const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->getParamAlignment(i);
-  else
-    return cast<InvokeInst>(I)->getParamAlignment(i);
+  CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
 }
-
 bool CallSite::doesNotAccessMemory() const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->doesNotAccessMemory();
-  else
-    return cast<InvokeInst>(I)->doesNotAccessMemory();
+  CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
+}
+void CallSite::setDoesNotAccessMemory(bool doesNotAccessMemory) {
+  CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory));
 }
 bool CallSite::onlyReadsMemory() const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->onlyReadsMemory();
-  else
-    return cast<InvokeInst>(I)->onlyReadsMemory();
+  CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
+}
+void CallSite::setOnlyReadsMemory(bool onlyReadsMemory) {
+  CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory));
+}
+bool CallSite::doesNotReturn() const {
+ CALLSITE_DELEGATE_GETTER(doesNotReturn());
+}
+void CallSite::setDoesNotReturn(bool doesNotReturn) {
+  CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn));
 }
 bool CallSite::doesNotThrow() const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->doesNotThrow();
-  else
-    return cast<InvokeInst>(I)->doesNotThrow();
+  CALLSITE_DELEGATE_GETTER(doesNotThrow());
 }
 void CallSite::setDoesNotThrow(bool doesNotThrow) {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    CI->setDoesNotThrow(doesNotThrow);
-  else
-    cast<InvokeInst>(I)->setDoesNotThrow(doesNotThrow);
+  CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow));
 }
 
+bool CallSite::hasArgument(const Value *Arg) const {
+  for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E; ++AI)
+    if (AI->get() == Arg)
+      return true;
+  return false;
+}
+
+#undef CALLSITE_DELEGATE_GETTER
+#undef CALLSITE_DELEGATE_SETTER
+
 //===----------------------------------------------------------------------===//
 //                            TerminatorInst Class
 //===----------------------------------------------------------------------===//
@@ -107,6 +112,33 @@ TerminatorInst::~TerminatorInst() {
 UnaryInstruction::~UnaryInstruction() {
 }
 
+//===----------------------------------------------------------------------===//
+//                              SelectInst Class
+//===----------------------------------------------------------------------===//
+
+/// areInvalidOperands - Return a string if the specified operands are invalid
+/// for a select operation, otherwise return null.
+const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) {
+  if (Op1->getType() != Op2->getType())
+    return "both values to select must have same type";
+  
+  if (const VectorType *VT = dyn_cast<VectorType>(Op0->getType())) {
+    // Vector select.
+    if (VT->getElementType() != Type::Int1Ty)
+      return "vector select condition element type must be i1";
+    const VectorType *ET = dyn_cast<VectorType>(Op1->getType());
+    if (ET == 0)
+      return "selected values for vector select must be vectors";
+    if (ET->getNumElements() != VT->getNumElements())
+      return "vector select requires selected vectors to have "
+                   "the same vector length as select condition";
+  } else if (Op0->getType() != Type::Int1Ty) {
+    return "select condition must be i1 or <n x i1>";
+  }
+  return 0;
+}
+
+
 //===----------------------------------------------------------------------===//
 //                               PHINode Class
 //===----------------------------------------------------------------------===//
@@ -123,7 +155,8 @@ PHINode::PHINode(const PHINode &PN)
 }
 
 PHINode::~PHINode() {
-  dropHungoffUses(OperandList);
+  if (OperandList)
+    dropHungoffUses(OperandList);
 }
 
 // removeIncomingValue - Remove an incoming value.  This is useful if a
@@ -182,9 +215,7 @@ void PHINode::resizeOperands(unsigned NumOps) {
   ReservedSpace = NumOps;
   Use *OldOps = OperandList;
   Use *NewOps = allocHungoffUses(NumOps);
-  for (unsigned i = 0; i != e; ++i) {
-      NewOps[i] = OldOps[i];
-  }
+  std::copy(OldOps, OldOps + e, NewOps);
   OperandList = NewOps;
   if (OldOps) Use::zap(OldOps, OldOps + e, true);
 }
@@ -364,7 +395,7 @@ CallInst::CallInst(const CallInst &CI)
   : Instruction(CI.getType(), Instruction::Call,
                 OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(),
                 CI.getNumOperands()) {
-  setParamAttrs(CI.getParamAttrs());
+  setAttributes(CI.getAttributes());
   SubclassData = CI.SubclassData;
   Use *OL = OperandList;
   Use *InOL = CI.OperandList;
@@ -372,29 +403,26 @@ CallInst::CallInst(const CallInst &CI)
     OL[i] = InOL[i];
 }
 
-void CallInst::addParamAttr(unsigned i, ParameterAttributes attr) {
-  PAListPtr PAL = getParamAttrs();
+void CallInst::addAttribute(unsigned i, Attributes attr) {
+  AttrListPtr PAL = getAttributes();
   PAL = PAL.addAttr(i, attr);
-  setParamAttrs(PAL);
+  setAttributes(PAL);
+}
+
+void CallInst::removeAttribute(unsigned i, Attributes attr) {
+  AttrListPtr PAL = getAttributes();
+  PAL = PAL.removeAttr(i, attr);
+  setAttributes(PAL);
 }
 
-bool CallInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
-  if (ParamAttrs.paramHasAttr(i, attr))
+bool CallInst::paramHasAttr(unsigned i, Attributes attr) const {
+  if (AttributeList.paramHasAttr(i, attr))
     return true;
   if (const Function *F = getCalledFunction())
     return F->paramHasAttr(i, attr);
   return false;
 }
 
-void CallInst::setDoesNotThrow(bool doesNotThrow) {
-  PAListPtr PAL = getParamAttrs();
-  if (doesNotThrow)
-    PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
-  else
-    PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
-  setParamAttrs(PAL);
-}
-
 
 //===----------------------------------------------------------------------===//
 //                        InvokeInst Implementation
@@ -429,7 +457,7 @@ InvokeInst::InvokeInst(const InvokeInst &II)
                    OperandTraits<InvokeInst>::op_end(this)
                    - II.getNumOperands(),
                    II.getNumOperands()) {
-  setParamAttrs(II.getParamAttrs());
+  setAttributes(II.getAttributes());
   SubclassData = II.SubclassData;
   Use *OL = OperandList, *InOL = II.OperandList;
   for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i)
@@ -446,27 +474,24 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) {
   return setSuccessor(idx, B);
 }
 
-bool InvokeInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
-  if (ParamAttrs.paramHasAttr(i, attr))
+bool InvokeInst::paramHasAttr(unsigned i, Attributes attr) const {
+  if (AttributeList.paramHasAttr(i, attr))
     return true;
   if (const Function *F = getCalledFunction())
     return F->paramHasAttr(i, attr);
   return false;
 }
 
-void InvokeInst::addParamAttr(unsigned i, ParameterAttributes attr) {
-  PAListPtr PAL = getParamAttrs();
+void InvokeInst::addAttribute(unsigned i, Attributes attr) {
+  AttrListPtr PAL = getAttributes();
   PAL = PAL.addAttr(i, attr);
-  setParamAttrs(PAL);
+  setAttributes(PAL);
 }
 
-void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
-  PAListPtr PAL = getParamAttrs();
-  if (doesNotThrow)
-    PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
-  else
-    PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
-  setParamAttrs(PAL);
+void InvokeInst::removeAttribute(unsigned i, Attributes attr) {
+  AttrListPtr PAL = getAttributes();
+  PAL = PAL.removeAttr(i, attr);
+  setAttributes(PAL);
 }
 
 
@@ -476,75 +501,30 @@ void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
 
 ReturnInst::ReturnInst(const ReturnInst &RI)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this)
-                   - RI.getNumOperands(),
+                   OperandTraits<ReturnInst>::op_end(this) -
+                     RI.getNumOperands(),
                    RI.getNumOperands()) {
-  unsigned N = RI.getNumOperands();
-  if (N == 1)
+  if (RI.getNumOperands())
     Op<0>() = RI.Op<0>();
-  else if (N) {
-    Use *OL = OperandList;
-    for (unsigned i = 0; i < N; ++i)
-      OL[i] = RI.getOperand(i);
-  }
 }
 
 ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
-                   retVal != 0, InsertBefore) {
+                   OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal,
+                   InsertBefore) {
   if (retVal)
-    init(&retVal, 1);
+    Op<0>() = retVal;
 }
 ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
-                   retVal != 0, InsertAtEnd) {
+                   OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal,
+                   InsertAtEnd) {
   if (retVal)
-    init(&retVal, 1);
+    Op<0>() = retVal;
 }
 ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this),
-                   0, InsertAtEnd) {
-}
-
-ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
-                       Instruction *InsertBefore)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this) - N,
-                   N, InsertBefore) {
-  if (N != 0)
-    init(retVals, N);
-}
-ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
-                       BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this) - N,
-                   N, InsertAtEnd) {
-  if (N != 0)
-    init(retVals, N);
-}
-
-void ReturnInst::init(Value * const* retVals, unsigned N) {
-  assert (N > 0 && "Invalid operands numbers in ReturnInst init");
-
-  NumOperands = N;
-  if (NumOperands == 1) {
-    Value *V = *retVals;
-    if (V->getType() == Type::VoidTy)
-      return;
-    Op<0>() = V;
-    return;
-  }
-
-  Use *OL = OperandList;
-  for (unsigned i = 0; i < NumOperands; ++i) {
-    Value *V = *retVals++;
-    assert(!isa<BasicBlock>(V) &&
-           "Cannot return basic block.  Probably using the incorrect ctor");
-    OL[i] = V;
-  }
+                   OperandTraits<ReturnInst>::op_end(this), 0, InsertAtEnd) {
 }
 
 unsigned ReturnInst::getNumSuccessorsV() const {
@@ -753,6 +733,18 @@ AllocaInst::AllocaInst(const AllocaInst &AI)
                    Instruction::Alloca, AI.getAlignment()) {
 }
 
+/// isStaticAlloca - Return true if this alloca is in the entry block of the
+/// function and is a constant size.  If so, the code generator will fold it
+/// into the prolog/epilog code, so it is basically free.
+bool AllocaInst::isStaticAlloca() const {
+  // Must be constant size.
+  if (!isa<ConstantInt>(getArraySize())) return false;
+  
+  // Must be in the entry block.
+  const BasicBlock *Parent = getParent();
+  return Parent == &Parent->getParent()->front();
+}
+
 MallocInst::MallocInst(const MallocInst &MI)
   : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0),
                    Instruction::Malloc, MI.getAlignment()) {
@@ -895,6 +887,7 @@ void LoadInst::setAlignment(unsigned Align) {
 //===----------------------------------------------------------------------===//
 
 void StoreInst::AssertOK() {
+  assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!");
   assert(isa<PointerType>(getOperand(1)->getType()) &&
          "Ptr must have pointer type!");
   assert(getOperand(0)->getType() ==
@@ -992,7 +985,8 @@ static unsigned retrieveAddrSpace(const Value *Val) {
   return cast<PointerType>(Val->getType())->getAddressSpace();
 }
 
-void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx, const std::string &Name) {
+void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx,
+                             const std::string &Name) {
   assert(NumOperands == 1+NumIdx && "NumOperands not initialized?");
   Use *OL = OperandList;
   OL[0] = Ptr;
@@ -1043,28 +1037,38 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
   init(Ptr, Idx, Name);
 }
 
-// getIndexedType - Returns the type of the element that would be loaded with
-// a load instruction with the specified parameters.
-//
-// A null type is returned if the indices are invalid for the specified
-// pointer type.
-//
-const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
-                                              Value* const *Idxs,
-                                              unsigned NumIdx) {
+/// getIndexedType - Returns the type of the element that would be accessed with
+/// a gep instruction with the specified parameters.
+///
+/// The Idxs pointer should point to a continuous piece of memory containing the
+/// indices, either as Value* or uint64_t.
+///
+/// A null type is returned if the indices are invalid for the specified
+/// pointer type.
+///
+template <typename IndexTy>
+static const Type* getIndexedTypeInternal(const Type *Ptr, IndexTy const *Idxs,
+                                          unsigned NumIdx) {
   const PointerType *PTy = dyn_cast<PointerType>(Ptr);
   if (!PTy) return 0;   // Type isn't a pointer type!
   const Type *Agg = PTy->getElementType();
 
-  // Handle the special case of the empty set index set...
+  // Handle the special case of the empty set index set, which is always valid.
   if (NumIdx == 0)
     return Agg;
+  
+  // If there is at least one index, the top level type must be sized, otherwise
+  // it cannot be 'stepped over'.  We explicitly allow abstract types (those
+  // that contain opaque types) under the assumption that it will be resolved to
+  // a sane type later.
+  if (!Agg->isSized() && !Agg->isAbstract())
+    return 0;
 
   unsigned CurIdx = 1;
   for (; CurIdx != NumIdx; ++CurIdx) {
     const CompositeType *CT = dyn_cast<CompositeType>(Agg);
     if (!CT || isa<PointerType>(CT)) return 0;
-    Value *Index = Idxs[CurIdx];
+    IndexTy Index = Idxs[CurIdx];
     if (!CT->indexValid(Index)) return 0;
     Agg = CT->getTypeAtIndex(Index);
 
@@ -1078,6 +1082,18 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
   return CurIdx == NumIdx ? Agg : 0;
 }
 
+const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
+                                              Value* const *Idxs,
+                                              unsigned NumIdx) {
+  return getIndexedTypeInternal(Ptr, Idxs, NumIdx);
+}
+
+const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
+                                              uint64_t const *Idxs,
+                                              unsigned NumIdx) {
+  return getIndexedTypeInternal(Ptr, Idxs, NumIdx);
+}
+
 const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) {
   const PointerType *PTy = dyn_cast<PointerType>(Ptr);
   if (!PTy) return 0;   // Type isn't a pointer type!
@@ -1290,10 +1306,12 @@ ShuffleVectorInst::ShuffleVectorInst(const ShuffleVectorInst &SV)
 ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
                                      const std::string &Name,
                                      Instruction *InsertBefore)
-  : Instruction(V1->getType(), ShuffleVector,
-                OperandTraits<ShuffleVectorInst>::op_begin(this),
-                OperandTraits<ShuffleVectorInst>::operands(this),
-                InsertBefore) {
+: Instruction(VectorType::get(cast<VectorType>(V1->getType())->getElementType(),
+                cast<VectorType>(Mask->getType())->getNumElements()),
+              ShuffleVector,
+              OperandTraits<ShuffleVectorInst>::op_begin(this),
+              OperandTraits<ShuffleVectorInst>::operands(this),
+              InsertBefore) {
   assert(isValidOperands(V1, V2, Mask) &&
          "Invalid shuffle vector instruction operands!");
   Op<0>() = V1;
@@ -1303,7 +1321,7 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
 }
 
 ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
-                                     const std::string &Name, 
+                                     const std::string &Name,
                                      BasicBlock *InsertAtEnd)
   : Instruction(V1->getType(), ShuffleVector,
                 OperandTraits<ShuffleVectorInst>::op_begin(this),
@@ -1318,17 +1336,14 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
   setName(Name);
 }
 
-bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, 
+bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
                                         const Value *Mask) {
-  if (!isa<VectorType>(V1->getType()) || 
-      V1->getType() != V2->getType()) 
+  if (!isa<VectorType>(V1->getType()) || V1->getType() != V2->getType())
     return false;
   
   const VectorType *MaskTy = dyn_cast<VectorType>(Mask->getType());
   if (!isa<Constant>(Mask) || MaskTy == 0 ||
-      MaskTy->getElementType() != Type::Int32Ty ||
-      MaskTy->getNumElements() != 
-      cast<VectorType>(V1->getType())->getNumElements())
+      MaskTy->getElementType() != Type::Int32Ty)
     return false;
   return true;
 }
@@ -1376,6 +1391,8 @@ InsertValueInst::InsertValueInst(const InsertValueInst &IVI)
   : Instruction(IVI.getType(), InsertValue,
                 OperandTraits<InsertValueInst>::op_begin(this), 2),
     Indices(IVI.Indices) {
+  Op<0>() = IVI.getOperand(0);
+  Op<1>() = IVI.getOperand(1);
 }
 
 InsertValueInst::InsertValueInst(Value *Agg,
@@ -1404,25 +1421,23 @@ InsertValueInst::InsertValueInst(Value *Agg,
 //                             ExtractValueInst Class
 //===----------------------------------------------------------------------===//
 
-void ExtractValueInst::init(Value *Agg, const unsigned *Idx, unsigned NumIdx, const std::string &Name) {
+void ExtractValueInst::init(const unsigned *Idx, unsigned NumIdx,
+                            const std::string &Name) {
   assert(NumOperands == 1 && "NumOperands not initialized?");
-  Op<0>() = Agg;
 
   Indices.insert(Indices.end(), Idx, Idx + NumIdx);
   setName(Name);
 }
 
-void ExtractValueInst::init(Value *Agg, unsigned Idx, const std::string &Name) {
+void ExtractValueInst::init(unsigned Idx, const std::string &Name) {
   assert(NumOperands == 1 && "NumOperands not initialized?");
-  Op<0>() = Agg;
 
   Indices.push_back(Idx);
   setName(Name);
 }
 
 ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI)
-  : Instruction(reinterpret_cast<const Type*>(EVI.getType()), ExtractValue,
-                OperandTraits<ExtractValueInst>::op_begin(this), 1),
+  : UnaryInstruction(EVI.getType(), ExtractValue, EVI.getOperand(0)),
     Indices(EVI.Indices) {
 }
 
@@ -1453,26 +1468,9 @@ const Type* ExtractValueInst::getIndexedType(const Type *Agg,
   return CurIdx == NumIdx ? Agg : 0;
 }
 
-ExtractValueInst::ExtractValueInst(Value *Agg,
-                                   unsigned Idx,
-                                   const std::string &Name,
-                                   BasicBlock *InsertAtEnd)
-  : Instruction(checkType(getIndexedType(Agg->getType(), &Idx, 1)),
-                ExtractValue,
-                OperandTraits<ExtractValueInst>::op_begin(this),
-                1, InsertAtEnd) {
-  init(Agg, Idx, Name);
-}
-
-ExtractValueInst::ExtractValueInst(Value *Agg,
-                                   unsigned Idx,
-                                   const std::string &Name,
-                                   Instruction *InsertBefore)
-  : Instruction(checkType(getIndexedType(Agg->getType(), &Idx, 1)),
-                ExtractValue,
-                OperandTraits<ExtractValueInst>::op_begin(this),
-                1, InsertBefore) {
-  init(Agg, Idx, Name);
+const Type* ExtractValueInst::getIndexedType(const Type *Agg,
+                                             unsigned Idx) {
+  return getIndexedType(Agg, &Idx, 1);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1556,8 +1554,10 @@ void BinaryOperator::init(BinaryOps iType) {
   case AShr:
     assert(getType() == LHS->getType() &&
            "Shift operation should return same type as operands!");
-    assert(getType()->isInteger() && 
-           "Shift operation requires integer operands");
+    assert((getType()->isInteger() ||
+            (isa<VectorType>(getType()) && 
+             cast<VectorType>(getType())->getElementType()->isInteger())) &&
+           "Tried to create a shift operation on a non-integral type!");
     break;
   case And: case Or:
   case Xor:
@@ -2190,6 +2190,7 @@ CastInst::getCastOpcode(
     } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
       assert(DestBits == PTy->getBitWidth() &&
                "Casting vector to integer of different width");
+      PTy = NULL;
       return BitCast;                             // Same size, no-op cast
     } else {
       assert(isa<PointerType>(SrcTy) &&
@@ -2213,7 +2214,8 @@ CastInst::getCastOpcode(
     } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
       assert(DestBits == PTy->getBitWidth() &&
              "Casting vector to floating point of different width");
-        return BitCast;                             // same size, no-op cast
+      PTy = NULL;
+      return BitCast;                             // same size, no-op cast
     } else {
       assert(0 && "Casting pointer or non-first class to float");
     }
@@ -2221,6 +2223,7 @@ CastInst::getCastOpcode(
     if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
       assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() &&
              "Casting vector to vector of different widths");
+      SrcPTy = NULL;
       return BitCast;                             // vector -> vector
     } else if (DestPTy->getBitWidth() == SrcBits) {
       return BitCast;                               // float/int -> vector
@@ -2269,37 +2272,42 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
   switch (op) {
   default: return false; // This is an input error
   case Instruction::Trunc:
-    return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize > DstBitSize;
+    return SrcTy->isIntOrIntVector() &&
+           DstTy->isIntOrIntVector()&& SrcBitSize > DstBitSize;
   case Instruction::ZExt:
-    return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize < DstBitSize;
+    return SrcTy->isIntOrIntVector() &&
+           DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize;
   case Instruction::SExt: 
-    return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize < DstBitSize;
+    return SrcTy->isIntOrIntVector() &&
+           DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize;
   case Instruction::FPTrunc:
-    return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() && 
-      SrcBitSize > DstBitSize;
+    return SrcTy->isFPOrFPVector() &&
+           DstTy->isFPOrFPVector() && 
+           SrcBitSize > DstBitSize;
   case Instruction::FPExt:
-    return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() && 
-      SrcBitSize < DstBitSize;
+    return SrcTy->isFPOrFPVector() &&
+           DstTy->isFPOrFPVector() && 
+           SrcBitSize < DstBitSize;
   case Instruction::UIToFP:
   case Instruction::SIToFP:
     if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
       if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
-        return SVTy->getElementType()->isInteger() &&
-               DVTy->getElementType()->isFloatingPoint() &&
+        return SVTy->getElementType()->isIntOrIntVector() &&
+               DVTy->getElementType()->isFPOrFPVector() &&
                SVTy->getNumElements() == DVTy->getNumElements();
       }
     }
-    return SrcTy->isInteger() && DstTy->isFloatingPoint();
+    return SrcTy->isIntOrIntVector() && DstTy->isFPOrFPVector();
   case Instruction::FPToUI:
   case Instruction::FPToSI:
     if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
       if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
-        return SVTy->getElementType()->isFloatingPoint() &&
-               DVTy->getElementType()->isInteger() &&
+        return SVTy->getElementType()->isFPOrFPVector() &&
+               DVTy->getElementType()->isIntOrIntVector() &&
                SVTy->getNumElements() == DVTy->getNumElements();
       }
     }
-    return SrcTy->isFloatingPoint() && DstTy->isInteger();
+    return SrcTy->isFPOrFPVector() && DstTy->isIntOrIntVector();
   case Instruction::PtrToInt:
     return isa<PointerType>(SrcTy) && DstTy->isInteger();
   case Instruction::IntToPtr:
@@ -2847,43 +2855,6 @@ void SwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) {
   setSuccessor(idx, B);
 }
 
-//===----------------------------------------------------------------------===//
-//                           GetResultInst Implementation
-//===----------------------------------------------------------------------===//
-
-GetResultInst::GetResultInst(Value *Aggregate, unsigned Index,
-                             const std::string &Name,
-                             Instruction *InsertBef)
-  : UnaryInstruction(cast<StructType>(Aggregate->getType())
-                       ->getElementType(Index),
-                     GetResult, Aggregate, InsertBef),
-    Idx(Index) {
-  assert(isValidOperands(Aggregate, Index)
-         && "Invalid GetResultInst operands!");
-  setName(Name);
-}
-
-bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) {
-  if (!Aggregate)
-    return false;
-
-  if (const StructType *STy = dyn_cast<StructType>(Aggregate->getType())) {
-    unsigned NumElements = STy->getNumElements();
-    if (Index >= NumElements || NumElements == 0)
-      return false;
-
-    // getresult aggregate value's element types are restricted to
-    // avoid nested aggregates.
-    for (unsigned i = 0; i < NumElements; ++i)
-      if (!STy->getElementType(i)->isFirstClassType())
-        return false;
-
-    // Otherwise, Aggregate is valid.
-    return true;
-  }
-  return false;
-}
-
 // Define these methods here so vtables don't get emitted into every translation
 // unit that uses these classes.
 
@@ -2964,4 +2935,3 @@ InvokeInst *InvokeInst::clone() const {
 }
 UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
 UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
-GetResultInst *GetResultInst::clone() const { return new GetResultInst(*this); }