aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2012-11-13 12:59:33 +0000
committerDuncan Sands <baldrick@free.fr>2012-11-13 12:59:33 +0000
commit2333e29be441d9d55920651e0b2add23ab0c1613 (patch)
treea81026fd460acee57a8305816fea3c2a75879aee /lib/VMCore
parent563e8fce2ee22b21beb40ac65a6eaf2199d30414 (diff)
downloadexternal_llvm-2333e29be441d9d55920651e0b2add23ab0c1613.zip
external_llvm-2333e29be441d9d55920651e0b2add23ab0c1613.tar.gz
external_llvm-2333e29be441d9d55920651e0b2add23ab0c1613.tar.bz2
Relax the restrictions on vector of pointer types, and vector getelementptr.
Previously in a vector of pointers, the pointer couldn't be any pointer type, it had to be a pointer to an integer or floating point type. This is a hassle for dragonegg because the GCC vectorizer happily produces vectors of pointers where the pointer is a pointer to a struct or whatever. Vector getelementptr was restricted to just one index, but now that vectors of pointers can have any pointer type it is more natural to allow arbitrary vector getelementptrs. There is however the issue of struct GEPs, where if each lane chose different struct fields then from that point on each lane will be working down into unrelated types. This seems like too much pain for too little gain, so when you have a vector struct index all the elements are required to be the same. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167828 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/Constants.cpp41
-rw-r--r--lib/VMCore/Instructions.cpp11
-rw-r--r--lib/VMCore/Type.cpp28
-rw-r--r--lib/VMCore/Verifier.cpp41
4 files changed, 74 insertions, 47 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index a4e21e1..f96fb1d 100644
--- a/lib/VMCore/Constants.cpp
+++ b/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/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 94bd2a1..ca7cd4e 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/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/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index 1656ab2..4d75a7e 100644
--- a/lib/VMCore/Type.cpp
+++ b/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/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index eb40b09..3782957 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/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);
}