From 446d95224b35b0fef06200b950d45839f1d5f262 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Tue, 11 Oct 2011 06:10:30 +0000 Subject: [PATCH] Remove a lot of the fancy scalar replacement code for dealing with llvm-gcc's lowering of NEON code. It provides little-to-no benefit now and only introduces additional complexity. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141646 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/ScalarReplAggregates.cpp | 221 ++---------------- test/Transforms/ScalarRepl/vector_promote.ll | 167 ------------- 2 files changed, 16 insertions(+), 372 deletions(-) diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index b4bfdd52eb8..3a4fac07ad3 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -298,8 +298,6 @@ AllocaInst *ConvertToScalarInfo::TryConvert(AllocaInst *AI) { if (ScalarKind == Unknown) ScalarKind = Integer; - // FIXME: It should be possible to promote the vector type up to the alloca's - // size. if (ScalarKind == Vector && VectorTy->getBitWidth() != AllocaSize * 8) ScalarKind = Integer; @@ -334,16 +332,12 @@ AllocaInst *ConvertToScalarInfo::TryConvert(AllocaInst *AI) { /// (VectorTy) so far at the offset specified by Offset (which is specified in /// bytes). /// -/// There are three cases we handle here: +/// There are two cases we handle here: /// 1) A union of vector types of the same size and potentially its elements. /// Here we turn element accesses into insert/extract element operations. /// This promotes a <4 x float> with a store of float to the third element /// into a <4 x float> that uses insert element. -/// 2) A union of vector types with power-of-2 size differences, e.g. a float, -/// <2 x float> and <4 x float>. Here we turn element accesses into insert -/// and extract element operations, and <2 x float> accesses into a cast to -/// <2 x double>, an extract, and a cast back to <2 x float>. -/// 3) A fully general blob of memory, which we turn into some (potentially +/// 2) A fully general blob of memory, which we turn into some (potentially /// large) integer type with extract and insert operations where the loads /// and stores would mutate the memory. We mark this by setting VectorTy /// to VoidTy. @@ -374,20 +368,13 @@ void ConvertToScalarInfo::MergeInTypeForLoadOrStore(Type *In, // if the implied vector agrees with what we already have and if Offset is // compatible with it. if (Offset % EltSize == 0 && AllocaSize % EltSize == 0 && - (!VectorTy || Offset * 8 < VectorTy->getPrimitiveSizeInBits())) { + (!VectorTy || EltSize == VectorTy->getElementType() + ->getPrimitiveSizeInBits()/8)) { if (!VectorTy) { ScalarKind = ImplicitVector; VectorTy = VectorType::get(In, AllocaSize/EltSize); - return; } - - unsigned CurrentEltSize = VectorTy->getElementType() - ->getPrimitiveSizeInBits()/8; - if (EltSize == CurrentEltSize) - return; - - if (In->isIntegerTy() && isPowerOf2_32(AllocaSize / EltSize)) - return; + return; } } @@ -400,78 +387,19 @@ void ConvertToScalarInfo::MergeInTypeForLoadOrStore(Type *In, /// returning true if the type was successfully merged and false otherwise. bool ConvertToScalarInfo::MergeInVectorType(VectorType *VInTy, uint64_t Offset) { - // TODO: Support nonzero offsets? - if (Offset != 0) - return false; - - // Only allow vectors that are a power-of-2 away from the size of the alloca. - if (!isPowerOf2_64(AllocaSize / (VInTy->getBitWidth() / 8))) - return false; - - // If this the first vector we see, remember the type so that we know the - // element size. - if (!VectorTy) { - ScalarKind = Vector; - VectorTy = VInTy; - return true; - } - - unsigned BitWidth = VectorTy->getBitWidth(); - unsigned InBitWidth = VInTy->getBitWidth(); - - // Vectors of the same size can be converted using a simple bitcast. - if (InBitWidth == BitWidth && AllocaSize == (InBitWidth / 8)) { + if (VInTy->getBitWidth()/8 == AllocaSize && Offset == 0) { + // If we're storing/loading a vector of the right size, allow it as a + // vector. If this the first vector we see, remember the type so that + // we know the element size. If this is a subsequent access, ignore it + // even if it is a differing type but the same size. Worst case we can + // bitcast the resultant vectors. + if (!VectorTy) + VectorTy = VInTy; ScalarKind = Vector; return true; } - Type *ElementTy = VectorTy->getElementType(); - Type *InElementTy = VInTy->getElementType(); - - // If they're the same alloc size, we'll be attempting to convert between - // them with a vector shuffle, which requires the element types to match. - if (TD.getTypeAllocSize(VectorTy) == TD.getTypeAllocSize(VInTy) && - ElementTy != InElementTy) - return false; - - // Do not allow mixed integer and floating-point accesses from vectors of - // different sizes. - if (ElementTy->isFloatingPointTy() != InElementTy->isFloatingPointTy()) - return false; - - if (ElementTy->isFloatingPointTy()) { - // Only allow floating-point vectors of different sizes if they have the - // same element type. - // TODO: This could be loosened a bit, but would anything benefit? - if (ElementTy != InElementTy) - return false; - - // There are no arbitrary-precision floating-point types, which limits the - // number of legal vector types with larger element types that we can form - // to bitcast and extract a subvector. - // TODO: We could support some more cases with mixed fp128 and double here. - if (!(BitWidth == 64 || BitWidth == 128) || - !(InBitWidth == 64 || InBitWidth == 128)) - return false; - } else { - assert(ElementTy->isIntegerTy() && "Vector elements must be either integer " - "or floating-point."); - unsigned BitWidth = ElementTy->getPrimitiveSizeInBits(); - unsigned InBitWidth = InElementTy->getPrimitiveSizeInBits(); - - // Do not allow integer types smaller than a byte or types whose widths are - // not a multiple of a byte. - if (BitWidth < 8 || InBitWidth < 8 || - BitWidth % 8 != 0 || InBitWidth % 8 != 0) - return false; - } - - // Pick the largest of the two vector types. - ScalarKind = Vector; - if (InBitWidth > BitWidth) - VectorTy = VInTy; - - return true; + return false; } /// CanConvertToScalar - V is a pointer. If we can convert the pointee and all @@ -735,63 +663,6 @@ void ConvertToScalarInfo::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, } } -/// getScaledElementType - Gets a scaled element type for a partial vector -/// access of an alloca. The input types must be integer or floating-point -/// scalar or vector types, and the resulting type is an integer, float or -/// double. -static Type *getScaledElementType(Type *Ty1, Type *Ty2, - unsigned NewBitWidth) { - bool IsFP1 = Ty1->isFloatingPointTy() || - (Ty1->isVectorTy() && - cast(Ty1)->getElementType()->isFloatingPointTy()); - bool IsFP2 = Ty2->isFloatingPointTy() || - (Ty2->isVectorTy() && - cast(Ty2)->getElementType()->isFloatingPointTy()); - - LLVMContext &Context = Ty1->getContext(); - - // Prefer floating-point types over integer types, as integer types may have - // been created by earlier scalar replacement. - if (IsFP1 || IsFP2) { - if (NewBitWidth == 32) - return Type::getFloatTy(Context); - if (NewBitWidth == 64) - return Type::getDoubleTy(Context); - } - - return Type::getIntNTy(Context, NewBitWidth); -} - -/// CreateShuffleVectorCast - Creates a shuffle vector to convert one vector -/// to another vector of the same element type which has the same allocation -/// size but different primitive sizes (e.g. <3 x i32> and <4 x i32>). -static Value *CreateShuffleVectorCast(Value *FromVal, Type *ToType, - IRBuilder<> &Builder) { - Type *FromType = FromVal->getType(); - VectorType *FromVTy = cast(FromType); - VectorType *ToVTy = cast(ToType); - assert((ToVTy->getElementType() == FromVTy->getElementType()) && - "Vectors must have the same element type"); - Value *UnV = UndefValue::get(FromType); - unsigned numEltsFrom = FromVTy->getNumElements(); - unsigned numEltsTo = ToVTy->getNumElements(); - - SmallVector Args; - Type* Int32Ty = Builder.getInt32Ty(); - unsigned minNumElts = std::min(numEltsFrom, numEltsTo); - unsigned i; - for (i=0; i != minNumElts; ++i) - Args.push_back(ConstantInt::get(Int32Ty, i)); - - if (i < numEltsTo) { - Constant* UnC = UndefValue::get(Int32Ty); - for (; i != numEltsTo; ++i) - Args.push_back(UnC); - } - Constant *Mask = ConstantVector::get(Args); - return Builder.CreateShuffleVector(FromVal, UnV, Mask, "tmpV"); -} - /// ConvertScalar_ExtractValue - Extract a value of type ToType from an integer /// or vector value FromVal, extracting the bits from the offset specified by /// Offset. This returns the value, which is of type ToType. @@ -815,38 +686,8 @@ ConvertScalar_ExtractValue(Value *FromVal, Type *ToType, if (VectorType *VTy = dyn_cast(FromType)) { unsigned FromTypeSize = TD.getTypeAllocSize(FromType); unsigned ToTypeSize = TD.getTypeAllocSize(ToType); - if (FromTypeSize == ToTypeSize) { - // If the two types have the same primitive size, use a bit cast. - // Otherwise, it is two vectors with the same element type that has - // the same allocation size but different number of elements so use - // a shuffle vector. - if (FromType->getPrimitiveSizeInBits() == - ToType->getPrimitiveSizeInBits()) + if (FromTypeSize == ToTypeSize) return Builder.CreateBitCast(FromVal, ToType); - else - return CreateShuffleVectorCast(FromVal, ToType, Builder); - } - - if (isPowerOf2_64(FromTypeSize / ToTypeSize)) { - assert(!(ToType->isVectorTy() && Offset != 0) && "Can't extract a value " - "of a smaller vector type at a nonzero offset."); - - Type *CastElementTy = getScaledElementType(FromType, ToType, - ToTypeSize * 8); - unsigned NumCastVectorElements = FromTypeSize / ToTypeSize; - - LLVMContext &Context = FromVal->getContext(); - Type *CastTy = VectorType::get(CastElementTy, - NumCastVectorElements); - Value *Cast = Builder.CreateBitCast(FromVal, CastTy); - - unsigned EltSize = TD.getTypeAllocSizeInBits(CastElementTy); - unsigned Elt = Offset/EltSize; - assert(EltSize*Elt == Offset && "Invalid modulus in validity checking"); - Value *Extract = Builder.CreateExtractElement(Cast, ConstantInt::get( - Type::getInt32Ty(Context), Elt)); - return Builder.CreateBitCast(Extract, ToType); - } // Otherwise it must be an element access. unsigned Elt = 0; @@ -961,38 +802,8 @@ ConvertScalar_InsertValue(Value *SV, Value *Old, // Changing the whole vector with memset or with an access of a different // vector type? - if (ValSize == VecSize) { - // If the two types have the same primitive size, use a bit cast. - // Otherwise, it is two vectors with the same element type that has - // the same allocation size but different number of elements so use - // a shuffle vector. - if (VTy->getPrimitiveSizeInBits() == - SV->getType()->getPrimitiveSizeInBits()) + if (ValSize == VecSize) return Builder.CreateBitCast(SV, AllocaType); - else - return CreateShuffleVectorCast(SV, VTy, Builder); - } - - if (isPowerOf2_64(VecSize / ValSize)) { - assert(!(SV->getType()->isVectorTy() && Offset != 0) && "Can't insert a " - "value of a smaller vector type at a nonzero offset."); - - Type *CastElementTy = getScaledElementType(VTy, SV->getType(), - ValSize); - unsigned NumCastVectorElements = VecSize / ValSize; - - Type *OldCastTy = VectorType::get(CastElementTy, NumCastVectorElements); - Value *OldCast = Builder.CreateBitCast(Old, OldCastTy); - - Value *SVCast = Builder.CreateBitCast(SV, CastElementTy); - - unsigned EltSize = TD.getTypeAllocSizeInBits(CastElementTy); - unsigned Elt = Offset/EltSize; - assert(EltSize*Elt == Offset && "Invalid modulus in validity checking"); - Value *Insert = - Builder.CreateInsertElement(OldCast, SVCast, Builder.getInt32(Elt)); - return Builder.CreateBitCast(Insert, AllocaType); - } // Must be an element insertion. assert(SV->getType() == VTy->getElementType()); diff --git a/test/Transforms/ScalarRepl/vector_promote.ll b/test/Transforms/ScalarRepl/vector_promote.ll index e8919abddbc..3058a36a978 100644 --- a/test/Transforms/ScalarRepl/vector_promote.ll +++ b/test/Transforms/ScalarRepl/vector_promote.ll @@ -86,7 +86,6 @@ define i32 @test5(float %X) { ;; should turn into bitcast. ; CHECK-NEXT: ret i32 } - define i64 @test6(<2 x float> %X) { %X_addr = alloca <2 x float> store <2 x float> %X, <2 x float>* %X_addr @@ -97,169 +96,3 @@ define i64 @test6(<2 x float> %X) { ; CHECK: bitcast <2 x float> %X to i64 ; CHECK: ret i64 } - -define float @test7(<4 x float> %x) { - %a = alloca <4 x float> - store <4 x float> %x, <4 x float>* %a - %p = bitcast <4 x float>* %a to <2 x float>* - %b = load <2 x float>* %p - %q = getelementptr <4 x float>* %a, i32 0, i32 2 - %c = load float* %q - ret float %c -; CHECK: @test7 -; CHECK-NOT: alloca -; CHECK: bitcast <4 x float> %x to <2 x double> -; CHECK-NEXT: extractelement <2 x double> -; CHECK-NEXT: bitcast double %2 to <2 x float> -; CHECK-NEXT: extractelement <4 x float> -} - -define void @test8(<4 x float> %x, <2 x float> %y) { - %a = alloca <4 x float> - store <4 x float> %x, <4 x float>* %a - %p = bitcast <4 x float>* %a to <2 x float>* - store <2 x float> %y, <2 x float>* %p - ret void -; CHECK: @test8 -; CHECK-NOT: alloca -; CHECK: bitcast <4 x float> %x to <2 x double> -; CHECK-NEXT: bitcast <2 x float> %y to double -; CHECK-NEXT: insertelement <2 x double> -; CHECK-NEXT: bitcast <2 x double> %3 to <4 x float> -} - -define i256 @test9(<4 x i256> %x) { - %a = alloca <4 x i256> - store <4 x i256> %x, <4 x i256>* %a - %p = bitcast <4 x i256>* %a to <2 x i256>* - %b = load <2 x i256>* %p - %q = getelementptr <4 x i256>* %a, i32 0, i32 2 - %c = load i256* %q - ret i256 %c -; CHECK: @test9 -; CHECK-NOT: alloca -; CHECK: bitcast <4 x i256> %x to <2 x i512> -; CHECK-NEXT: extractelement <2 x i512> -; CHECK-NEXT: bitcast i512 %2 to <2 x i256> -; CHECK-NEXT: extractelement <4 x i256> -} - -define void @test10(<4 x i256> %x, <2 x i256> %y) { - %a = alloca <4 x i256> - store <4 x i256> %x, <4 x i256>* %a - %p = bitcast <4 x i256>* %a to <2 x i256>* - store <2 x i256> %y, <2 x i256>* %p - ret void -; CHECK: @test10 -; CHECK-NOT: alloca -; CHECK: bitcast <4 x i256> %x to <2 x i512> -; CHECK-NEXT: bitcast <2 x i256> %y to i512 -; CHECK-NEXT: insertelement <2 x i512> -; CHECK-NEXT: bitcast <2 x i512> %3 to <4 x i256> -} - -%union.v = type { <2 x i64> } - -define void @test11(<2 x i64> %x) { - %a = alloca %union.v - %p = getelementptr inbounds %union.v* %a, i32 0, i32 0 - store <2 x i64> %x, <2 x i64>* %p, align 16 - %q = getelementptr inbounds %union.v* %a, i32 0, i32 0 - %r = bitcast <2 x i64>* %q to <4 x float>* - %b = load <4 x float>* %r, align 16 - ret void -; CHECK: @test11 -; CHECK-NOT: alloca -} - -define void @test12() { -entry: - %a = alloca <64 x i8>, align 64 - store <64 x i8> undef, <64 x i8>* %a, align 64 - %p = bitcast <64 x i8>* %a to <16 x i8>* - %0 = load <16 x i8>* %p, align 64 - store <16 x i8> undef, <16 x i8>* %p, align 64 - %q = bitcast <16 x i8>* %p to <64 x i8>* - %1 = load <64 x i8>* %q, align 64 - ret void -; CHECK: @test12 -; CHECK-NOT: alloca -; CHECK: extractelement <4 x i128> -; CHECK: insertelement <4 x i128> -} - -define float @test13(<4 x float> %x, <2 x i32> %y) { - %a = alloca <4 x float> - store <4 x float> %x, <4 x float>* %a - %p = bitcast <4 x float>* %a to <2 x float>* - %b = load <2 x float>* %p - %q = getelementptr <4 x float>* %a, i32 0, i32 2 - %c = load float* %q - %r = bitcast <4 x float>* %a to <2 x i32>* - store <2 x i32> %y, <2 x i32>* %r - ret float %c -; CHECK: @test13 -; CHECK-NOT: alloca -; CHECK: bitcast <4 x float> %x to i128 -} - -define <3 x float> @test14(<3 x float> %x) { -entry: - %x.addr = alloca <3 x float>, align 16 - %r = alloca <3 x i32>, align 16 - %extractVec = shufflevector <3 x float> %x, <3 x float> undef, <4 x i32> - %storetmp = bitcast <3 x float>* %x.addr to <4 x float>* - store <4 x float> %extractVec, <4 x float>* %storetmp, align 16 - %tmp = load <3 x float>* %x.addr, align 16 - %cmp = fcmp une <3 x float> %tmp, zeroinitializer - %sext = sext <3 x i1> %cmp to <3 x i32> - %and = and <3 x i32> , %sext - %extractVec1 = shufflevector <3 x i32> %and, <3 x i32> undef, <4 x i32> - %storetmp2 = bitcast <3 x i32>* %r to <4 x i32>* - store <4 x i32> %extractVec1, <4 x i32>* %storetmp2, align 16 - %tmp3 = load <3 x i32>* %r, align 16 - %0 = bitcast <3 x i32> %tmp3 to <3 x float> - %tmp4 = load <3 x float>* %x.addr, align 16 - ret <3 x float> %tmp4 -; CHECK: @test14 -; CHECK-NOT: alloca -; CHECK: shufflevector <4 x i32> %extractVec1, <4 x i32> undef, <3 x i32> -} - -define void @test15(<3 x i64>* sret %agg.result, <3 x i64> %x, <3 x i64> %min) { -entry: - %x.addr = alloca <3 x i64>, align 32 - %min.addr = alloca <3 x i64>, align 32 - %extractVec = shufflevector <3 x i64> %x, <3 x i64> undef, <4 x i32> - %storetmp = bitcast <3 x i64>* %x.addr to <4 x i64>* - store <4 x i64> %extractVec, <4 x i64>* %storetmp, align 32 - %extractVec1 = shufflevector <3 x i64> %min, <3 x i64> undef, <4 x i32> - %storetmp2 = bitcast <3 x i64>* %min.addr to <4 x i64>* - store <4 x i64> %extractVec1, <4 x i64>* %storetmp2, align 32 - %tmp = load <3 x i64>* %x.addr - %tmp5 = extractelement <3 x i64> %tmp, i32 0 - %tmp11 = insertelement <3 x i64> %tmp, i64 %tmp5, i32 0 - store <3 x i64> %tmp11, <3 x i64>* %x.addr - %tmp30 = load <3 x i64>* %x.addr, align 32 - store <3 x i64> %tmp30, <3 x i64>* %agg.result - ret void -; CHECK: @test15 -; CHECK-NOT: alloca -; CHECK: shufflevector <4 x i64> %tmpV1, <4 x i64> undef, <3 x i32> -} - -define <4 x float> @test16(<4 x float> %x, i64 %y0, i64 %y1) { -entry: - %tmp8 = bitcast <4 x float> undef to <2 x double> - %tmp9 = bitcast i64 %y0 to double - %tmp10 = insertelement <2 x double> %tmp8, double %tmp9, i32 0 - %tmp11 = bitcast <2 x double> %tmp10 to <4 x float> - %tmp3 = bitcast <4 x float> %tmp11 to <2 x double> - %tmp4 = bitcast i64 %y1 to double - %tmp5 = insertelement <2 x double> %tmp3, double %tmp4, i32 1 - %tmp6 = bitcast <2 x double> %tmp5 to <4 x float> - ret <4 x float> %tmp6 -; CHECK: @test16 -; CHECK-NOT: alloca -; CHECK: bitcast <4 x float> %tmp11 to <2 x double> -}