diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 53436000e03..c245b143273 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -193,6 +193,22 @@ private: }; } // end anonymous namespace. + +/// IsVerbotenVectorType - Return true if this is a vector type ScalarRepl isn't +/// allowed to form. We do this to avoid MMX types, which is a complete hack, +/// but is required until the backend is fixed. +static bool IsVerbotenVectorType(const VectorType *VTy) { + // Reject all the MMX vector types. + switch (VTy->getNumElements()) { + default: return false; + case 1: return VTy->getElementType()->isIntegerTy(64); + case 2: return VTy->getElementType()->isIntegerTy(32); + case 4: return VTy->getElementType()->isIntegerTy(16); + case 8: return VTy->getElementType()->isIntegerTy(8); + } +} + + /// TryConvert - Analyze the specified alloca, and if it is safe to do so, /// rewrite it to be a new alloca which is mem2reg'able. This returns the new /// alloca if possible or null if not. @@ -209,7 +225,8 @@ AllocaInst *ConvertToScalarInfo::TryConvert(AllocaInst *AI) { // we just get a lot of insert/extracts. If at least one vector is // involved, then we probably really do have a union of vector/array. const Type *NewTy; - if (VectorTy && VectorTy->isVectorTy() && HadAVector) { + if (VectorTy && VectorTy->isVectorTy() && HadAVector && + !IsVerbotenVectorType(cast(VectorTy))) { DEBUG(dbgs() << "CONVERT TO VECTOR: " << *AI << "\n TYPE = " << *VectorTy << '\n'); NewTy = VectorTy; // Use the vector type. @@ -1662,6 +1679,12 @@ void SROA::RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocaInst *AI, /// HasPadding - Return true if the specified type has any structure or /// alignment padding, false otherwise. static bool HasPadding(const Type *Ty, const TargetData &TD) { + if (const ArrayType *ATy = dyn_cast(Ty)) + return HasPadding(ATy->getElementType(), TD); + + if (const VectorType *VTy = dyn_cast(Ty)) + return HasPadding(VTy->getElementType(), TD); + if (const StructType *STy = dyn_cast(Ty)) { const StructLayout *SL = TD.getStructLayout(STy); unsigned PrevFieldBitOffset = 0; @@ -1691,12 +1714,8 @@ static bool HasPadding(const Type *Ty, const TargetData &TD) { if (PrevFieldEnd < SL->getSizeInBits()) return true; } - - } else if (const ArrayType *ATy = dyn_cast(Ty)) { - return HasPadding(ATy->getElementType(), TD); - } else if (const VectorType *VTy = dyn_cast(Ty)) { - return HasPadding(VTy->getElementType(), TD); } + return TD.getTypeSizeInBits(Ty) != TD.getTypeAllocSizeInBits(Ty); } diff --git a/test/Transforms/ScalarRepl/vector_promote.ll b/test/Transforms/ScalarRepl/vector_promote.ll index dd4251bde98..5287cbe38bf 100644 --- a/test/Transforms/ScalarRepl/vector_promote.ll +++ b/test/Transforms/ScalarRepl/vector_promote.ll @@ -85,3 +85,17 @@ define i32 @test5(float %X) { ;; should turn into bitcast. ; CHECK-NEXT: ret i32 } + +;; should not turn into <1 x i64> - It is a banned MMX datatype. +;; rdar://8380055 +define i64 @test6(<2 x float> %X) { + %X_addr = alloca <2 x float> + store <2 x float> %X, <2 x float>* %X_addr + %P = bitcast <2 x float>* %X_addr to i64* + %tmp = load i64* %P + ret i64 %tmp +; CHECK: @test6 +; CHECK-NEXT: bitcast <2 x float> %X to i64 +; CHECK-NEXT: ret i64 +} +