diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/VMCore/Constants.cpp | 41 | ||||
-rw-r--r-- | llvm/lib/VMCore/Instructions.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/VMCore/Type.cpp | 28 | ||||
-rw-r--r-- | llvm/lib/VMCore/Verifier.cpp | 41 |
6 files changed, 81 insertions, 57 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index ac803c57833..de404728be6 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1697,8 +1697,7 @@ bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { if ((unsigned)Size != Size) return Error(SizeLoc, "size too large for vector"); if (!VectorType::isValidElementType(EltTy)) - return Error(TypeLoc, - "vector element type must be fp, integer or a pointer to these types"); + return Error(TypeLoc, "invalid vector element type"); Result = VectorType::get(EltTy, unsigned(Size)); } else { if (!ArrayType::isValidElementType(EltTy)) @@ -4032,9 +4031,6 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Indices.push_back(Val); } - if (Val && Val->getType()->isVectorTy() && Indices.size() != 1) - return Error(EltLoc, "vector getelementptrs must have a single index"); - if (!GetElementPtrInst::getIndexedType(Ptr->getType(), Indices)) return Error(Loc, "invalid getelementptr indices"); Inst = GetElementPtrInst::Create(Ptr, Indices); diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 1ed9004eb5a..cf3839d4b0a 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -24,8 +24,8 @@ #include <algorithm> using namespace llvm; -static bool isIntegerValue(const std::pair<const Value*, unsigned> &V) { - return V.first->getType()->isIntegerTy(); +static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) { + return V.first->getType()->isIntOrIntVectorTy(); } /// ValueEnumerator - Enumerate module-level information. @@ -192,10 +192,11 @@ void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) { CstSortPredicate P(*this); std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P); - // Ensure that integer constants are at the start of the constant pool. This - // is important so that GEP structure indices come before gep constant exprs. + // Ensure that integer and vector of integer constants are at the start of the + // constant pool. This is important so that GEP structure indices come before + // gep constant exprs. std::partition(Values.begin()+CstStart, Values.begin()+CstEnd, - isIntegerValue); + isIntOrIntVectorValue); // Rebuild the modified portion of ValueMap. for (; CstStart != CstEnd; ++CstStart) diff --git a/llvm/lib/VMCore/Constants.cpp b/llvm/lib/VMCore/Constants.cpp index a4e21e16b3f..f96fb1d4019 100644 --- a/llvm/lib/VMCore/Constants.cpp +++ b/llvm/lib/VMCore/Constants.cpp @@ -1213,6 +1213,19 @@ void ConstantVector::destroyConstant() { destroyConstantImpl(); } +/// getSplatValue - If this is a splat vector constant, meaning that all of +/// the elements have the same value, return that value. Otherwise return 0. +Constant *Constant::getSplatValue() const { + assert(this->getType()->isVectorTy() && "Only valid for vectors!"); + if (isa<ConstantAggregateZero>(this)) + return getNullValue(this->getType()->getVectorElementType()); + if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) + return CV->getSplatValue(); + if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) + return CV->getSplatValue(); + return 0; +} + /// getSplatValue - If this is a splat constant, where all of the /// elements have the same value, return that value. Otherwise return null. Constant *ConstantVector::getSplatValue() const { @@ -1225,6 +1238,18 @@ Constant *ConstantVector::getSplatValue() const { return Elt; } +/// If C is a constant integer then return its value, otherwise C must be a +/// vector of constant integers, all equal, and the common value is returned. +const APInt &Constant::getUniqueInteger() const { + if (const ConstantInt *CI = dyn_cast<ConstantInt>(this)) + return CI->getValue(); + assert(this->getSplatValue() && "Doesn't contain a unique integer!"); + const Constant *C = this->getAggregateElement(0U); + assert(C && isa<ConstantInt>(C) && "Not a vector of numbers!"); + return cast<ConstantInt>(C)->getValue(); +} + + //---- ConstantPointerNull::get() implementation. // @@ -1739,6 +1764,9 @@ Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2) { Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs, bool InBounds) { + assert(C->getType()->isPtrOrPtrVectorTy() && + "Non-pointer type for constant GetElementPtr expression"); + if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs)) return FC; // Fold a few common cases. @@ -1747,15 +1775,22 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs, assert(Ty && "GEP indices invalid!"); unsigned AS = C->getType()->getPointerAddressSpace(); Type *ReqTy = Ty->getPointerTo(AS); + if (VectorType *VecTy = dyn_cast<VectorType>(C->getType())) + ReqTy = VectorType::get(ReqTy, VecTy->getNumElements()); - assert(C->getType()->isPointerTy() && - "Non-pointer type for constant GetElementPtr expression"); // Look up the constant in the table first to ensure uniqueness std::vector<Constant*> ArgVec; ArgVec.reserve(1 + Idxs.size()); ArgVec.push_back(C); - for (unsigned i = 0, e = Idxs.size(); i != e; ++i) + for (unsigned i = 0, e = Idxs.size(); i != e; ++i) { + assert(Idxs[i]->getType()->isVectorTy() == ReqTy->isVectorTy() && + "getelementptr index type missmatch"); + assert((!Idxs[i]->getType()->isVectorTy() || + ReqTy->getVectorNumElements() == + Idxs[i]->getType()->getVectorNumElements()) && + "getelementptr index type missmatch"); ArgVec.push_back(cast<Constant>(Idxs[i])); + } const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0, InBounds ? GEPOperator::IsInBounds : 0); diff --git a/llvm/lib/VMCore/Instructions.cpp b/llvm/lib/VMCore/Instructions.cpp index 94bd2a15632..ca7cd4eb978 100644 --- a/llvm/lib/VMCore/Instructions.cpp +++ b/llvm/lib/VMCore/Instructions.cpp @@ -1353,16 +1353,7 @@ GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI) /// template <typename IndexTy> static Type *getIndexedTypeInternal(Type *Ptr, ArrayRef<IndexTy> IdxList) { - if (Ptr->isVectorTy()) { - assert(IdxList.size() == 1 && - "GEP with vector pointers must have a single index"); - PointerType *PTy = dyn_cast<PointerType>( - cast<VectorType>(Ptr)->getElementType()); - assert(PTy && "Gep with invalid vector pointer found"); - return PTy->getElementType(); - } - - PointerType *PTy = dyn_cast<PointerType>(Ptr); + PointerType *PTy = dyn_cast<PointerType>(Ptr->getScalarType()); if (!PTy) return 0; // Type isn't a pointer type! Type *Agg = PTy->getElementType(); diff --git a/llvm/lib/VMCore/Type.cpp b/llvm/lib/VMCore/Type.cpp index 1656ab2cab3..4d75a7e060f 100644 --- a/llvm/lib/VMCore/Type.cpp +++ b/llvm/lib/VMCore/Type.cpp @@ -629,11 +629,12 @@ StructType *Module::getTypeByName(StringRef Name) const { Type *CompositeType::getTypeAtIndex(const Value *V) { if (StructType *STy = dyn_cast<StructType>(this)) { - unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue(); + unsigned Idx = + (unsigned)cast<Constant>(V)->getUniqueInteger().getZExtValue(); assert(indexValid(Idx) && "Invalid structure index!"); return STy->getElementType(Idx); } - + return cast<SequentialType>(this)->getElementType(); } Type *CompositeType::getTypeAtIndex(unsigned Idx) { @@ -646,15 +647,19 @@ Type *CompositeType::getTypeAtIndex(unsigned Idx) { } bool CompositeType::indexValid(const Value *V) const { if (const StructType *STy = dyn_cast<StructType>(this)) { - // Structure indexes require 32-bit integer constants. - if (V->getType()->isIntegerTy(32)) - if (const ConstantInt *CU = dyn_cast<ConstantInt>(V)) - return CU->getZExtValue() < STy->getNumElements(); - return false; + // Structure indexes require (vectors of) 32-bit integer constants. In the + // vector case all of the indices must be equal. + if (!V->getType()->getScalarType()->isIntegerTy(32)) + return false; + const Constant *C = dyn_cast<Constant>(V); + if (C && V->getType()->isVectorTy()) + C = C->getSplatValue(); + const ConstantInt *CU = dyn_cast_or_null<ConstantInt>(C); + return CU && CU->getZExtValue() < STy->getNumElements(); } - + // Sequential types can be indexed by any integer. - return V->getType()->isIntegerTy(); + return V->getType()->isIntOrIntVectorTy(); } bool CompositeType::indexValid(unsigned Idx) const { @@ -717,9 +722,8 @@ VectorType *VectorType::get(Type *elementType, unsigned NumElements) { } bool VectorType::isValidElementType(Type *ElemTy) { - if (PointerType *PTy = dyn_cast<PointerType>(ElemTy)) - ElemTy = PTy->getElementType(); - return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy(); + return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() || + ElemTy->isPointerTy(); } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/VMCore/Verifier.cpp b/llvm/lib/VMCore/Verifier.cpp index eb40b09d29f..3782957f3b3 100644 --- a/llvm/lib/VMCore/Verifier.cpp +++ b/llvm/lib/VMCore/Verifier.cpp @@ -1375,34 +1375,31 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { "GEP base pointer is not a vector or a vector of pointers", &GEP); Assert1(cast<PointerType>(TargetTy)->getElementType()->isSized(), "GEP into unsized type!", &GEP); + Assert1(GEP.getPointerOperandType()->isVectorTy() == + GEP.getType()->isVectorTy(), "Vector GEP must return a vector value", + &GEP); SmallVector<Value*, 16> Idxs(GEP.idx_begin(), GEP.idx_end()); Type *ElTy = GetElementPtrInst::getIndexedType(GEP.getPointerOperandType(), Idxs); Assert1(ElTy, "Invalid indices for GEP pointer type!", &GEP); - if (GEP.getPointerOperandType()->isPointerTy()) { - // Validate GEPs with scalar indices. - Assert2(GEP.getType()->isPointerTy() && - cast<PointerType>(GEP.getType())->getElementType() == ElTy, - "GEP is not of right type for indices!", &GEP, ElTy); - } else { - // Validate GEPs with a vector index. - Assert1(Idxs.size() == 1, "Invalid number of indices!", &GEP); - Value *Index = Idxs[0]; - Type *IndexTy = Index->getType(); - Assert1(IndexTy->isVectorTy(), - "Vector GEP must have vector indices!", &GEP); - Assert1(GEP.getType()->isVectorTy(), - "Vector GEP must return a vector value", &GEP); - Type *ElemPtr = cast<VectorType>(GEP.getType())->getElementType(); - Assert1(ElemPtr->isPointerTy(), - "Vector GEP pointer operand is not a pointer!", &GEP); - unsigned IndexWidth = cast<VectorType>(IndexTy)->getNumElements(); - unsigned GepWidth = cast<VectorType>(GEP.getType())->getNumElements(); - Assert1(IndexWidth == GepWidth, "Invalid GEP index vector width", &GEP); - Assert1(ElTy == cast<PointerType>(ElemPtr)->getElementType(), - "Vector GEP type does not match pointer type!", &GEP); + Assert2(GEP.getType()->getScalarType()->isPointerTy() && + cast<PointerType>(GEP.getType()->getScalarType())->getElementType() + == ElTy, "GEP is not of right type for indices!", &GEP, ElTy); + + if (GEP.getPointerOperandType()->isVectorTy()) { + // Additional checks for vector GEPs. + unsigned GepWidth = GEP.getPointerOperandType()->getVectorNumElements(); + Assert1(GepWidth == GEP.getType()->getVectorNumElements(), + "Vector GEP result width doesn't match operand's", &GEP); + for (unsigned i = 0, e = Idxs.size(); i != e; ++i) { + Type *IndexTy = Idxs[i]->getType(); + Assert1(IndexTy->isVectorTy(), + "Vector GEP must have vector indices!", &GEP); + unsigned IndexWidth = IndexTy->getVectorNumElements(); + Assert1(IndexWidth == GepWidth, "Invalid GEP index vector width", &GEP); + } } visitInstruction(GEP); } |