aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorMon P Wang <wangmp@apple.com>2011-04-13 21:40:02 +0000
committerMon P Wang <wangmp@apple.com>2011-04-13 21:40:02 +0000
commitbe0761c8202405cdd33f1103d262c0aa97895a8e (patch)
treebc5c8de29e9cc35e63549adaca085e042bffdd4d /lib/Transforms
parent6c7e4147dc7faf2f7b4bdaaf7940c2fe65d6fbc5 (diff)
downloadexternal_llvm-be0761c8202405cdd33f1103d262c0aa97895a8e.zip
external_llvm-be0761c8202405cdd33f1103d262c0aa97895a8e.tar.gz
external_llvm-be0761c8202405cdd33f1103d262c0aa97895a8e.tar.bz2
Vectors with different number of elements of the same element type can have
the same allocation size but different primitive sizes(e.g., <3xi32> and <4xi32>). When ScalarRepl promotes them, it can't use a bit cast but should use a shuffle vector instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129472 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/ScalarReplAggregates.cpp70
1 files changed, 64 insertions, 6 deletions
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index 42246ff..0ae12ae 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -690,15 +690,45 @@ Value *ConvertToScalarInfo::
ConvertScalar_ExtractValue(Value *FromVal, const Type *ToType,
uint64_t Offset, IRBuilder<> &Builder) {
// If the load is of the whole new alloca, no conversion is needed.
- if (FromVal->getType() == ToType && Offset == 0)
+ const Type *FromType = FromVal->getType();
+ if (FromType == ToType && Offset == 0)
return FromVal;
// If the result alloca is a vector type, this is either an element
// access or a bitcast to another vector type of the same size.
- if (const VectorType *VTy = dyn_cast<VectorType>(FromVal->getType())) {
+ if (const VectorType *VTy = dyn_cast<VectorType>(FromType)) {
unsigned ToTypeSize = TD.getTypeAllocSize(ToType);
- if (ToTypeSize == AllocaSize)
- return Builder.CreateBitCast(FromVal, ToType, "tmp");
+ if (ToTypeSize == AllocaSize) {
+ if (FromType->getPrimitiveSizeInBits() ==
+ ToType->getPrimitiveSizeInBits())
+ return Builder.CreateBitCast(FromVal, ToType, "tmp");
+ else {
+ // Vectors with the same element type can have the same allocation
+ // size but different primitive sizes (e.g., <3 x i32> and <4 x i32>)
+ // In this case, use a shuffle vector instead of a bit cast.
+ const VectorType *ToVTy = dyn_cast<VectorType>(ToType);
+ assert(ToVTy && (ToVTy->getElementType() == VTy->getElementType()) &&
+ "Vectors must have the same element type");
+ LLVMContext &Context = FromVal->getContext();
+ Value *UnV = UndefValue::get(FromType);
+ unsigned numEltsFrom = VTy->getNumElements();
+ unsigned numEltsTo = ToVTy->getNumElements();
+
+ SmallVector<Constant*, 3> Args;
+ unsigned minNumElts = std::min(numEltsFrom, numEltsTo);
+ unsigned i;
+ for (i=0; i != minNumElts; ++i)
+ Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), i));
+
+ if (i < numEltsTo) {
+ Constant* UnC = UndefValue::get(Type::getInt32Ty(Context));
+ for (; i != numEltsTo; ++i)
+ Args.push_back(UnC);
+ }
+ Constant *Mask = ConstantVector::get(Args);
+ return Builder.CreateShuffleVector(FromVal, UnV, Mask, "tmpV");
+ }
+ }
if (ToType->isVectorTy()) {
assert(isPowerOf2_64(AllocaSize / ToTypeSize) &&
@@ -837,8 +867,36 @@ ConvertScalar_InsertValue(Value *SV, Value *Old,
// Changing the whole vector with memset or with an access of a different
// vector type?
- if (ValSize == VecSize)
- return Builder.CreateBitCast(SV, AllocaType, "tmp");
+ if (ValSize == VecSize) {
+ if (VTy->getPrimitiveSizeInBits() ==
+ SV->getType()->getPrimitiveSizeInBits())
+ return Builder.CreateBitCast(SV, AllocaType, "tmp");
+ else {
+ // Vectors with the same element type can have the same allocation
+ // size but different primitive sizes (e.g., <3 x i32> and <4 x i32>)
+ // In this case, use a shuffle vector instead of a bit cast.
+ const VectorType *SVVTy = dyn_cast<VectorType>(SV->getType());
+ assert(SVVTy && (SVVTy->getElementType() == VTy->getElementType()) &&
+ "Vectors must have the same element type");
+ Value *UnV = UndefValue::get(SVVTy);
+ unsigned numEltsFrom = SVVTy->getNumElements();
+ unsigned numEltsTo = VTy->getNumElements();
+
+ SmallVector<Constant*, 3> Args;
+ unsigned minNumElts = std::min(numEltsFrom, numEltsTo);
+ unsigned i;
+ for (i=0; i != minNumElts; ++i)
+ Args.push_back(ConstantInt::get(Type::getInt32Ty(Context), i));
+
+ if (i < numEltsTo) {
+ Constant* UnC = UndefValue::get(Type::getInt32Ty(Context));
+ for (; i != numEltsTo; ++i)
+ Args.push_back(UnC);
+ }
+ Constant *Mask = ConstantVector::get(Args);
+ return Builder.CreateShuffleVector(SV, UnV, Mask, "tmpV");
+ }
+ }
if (SV->getType()->isVectorTy() && isPowerOf2_64(VecSize / ValSize)) {
assert(Offset == 0 && "Can't insert a value of a smaller vector type at "