diff options
author | Mon P Wang <wangmp@apple.com> | 2011-04-13 21:40:02 +0000 |
---|---|---|
committer | Mon P Wang <wangmp@apple.com> | 2011-04-13 21:40:02 +0000 |
commit | be0761c8202405cdd33f1103d262c0aa97895a8e (patch) | |
tree | bc5c8de29e9cc35e63549adaca085e042bffdd4d /lib/Transforms | |
parent | 6c7e4147dc7faf2f7b4bdaaf7940c2fe65d6fbc5 (diff) | |
download | external_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.cpp | 70 |
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 " |