llvm.org GIT mirror llvm / 344731c
Fix another case of <rdar://problem/9184212> that only occurs with code generated by llvm-gcc, since llvm-gcc uses 2 i64s for passing a 4 x float vector on ARM rather than an i64 array like Clang. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129878 91177308-0d34-0410-b5e6-96231b3b80d8 Cameron Zwarich 9 years ago
2 changed file(s) with 62 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
350350 ->getPrimitiveSizeInBits()/8;
351351 if (EltSize == CurrentEltSize)
352352 return;
353
354 if (In->isIntegerTy() && isPowerOf2_32(AllocaSize / EltSize))
355 return;
353356 }
354357 }
355358
660663 }
661664
662665 /// getScaledElementType - Gets a scaled element type for a partial vector
663 /// access of an alloca. The input type must be an integer or float, and
664 /// the resulting type must be an integer, float or double.
665 static const Type *getScaledElementType(const Type *OldTy,
666 /// access of an alloca. The input types must be integer or floating-point
667 /// scalar or vector types, and the resulting type is an integer, float or
668 /// double.
669 static const Type *getScaledElementType(const Type *Ty1, const Type *Ty2,
666670 unsigned NewBitWidth) {
667 assert((OldTy->isIntegerTy() || OldTy->isFloatTy()) && "Partial vector "
668 "accesses must be scaled from integer or float elements.");
669
670 LLVMContext &Context = OldTy->getContext();
671
672 if (OldTy->isIntegerTy())
673 return Type::getIntNTy(Context, NewBitWidth);
674 if (NewBitWidth == 32)
675 return Type::getFloatTy(Context);
676 if (NewBitWidth == 64)
677 return Type::getDoubleTy(Context);
678
679 llvm_unreachable("Invalid type for a partial vector access of an alloca!");
671 bool IsFP1 = Ty1->isFloatingPointTy() ||
672 (Ty1->isVectorTy() &&
673 cast(Ty1)->getElementType()->isFloatingPointTy());
674 bool IsFP2 = Ty2->isFloatingPointTy() ||
675 (Ty2->isVectorTy() &&
676 cast(Ty2)->getElementType()->isFloatingPointTy());
677
678 LLVMContext &Context = Ty1->getContext();
679
680 // Prefer floating-point types over integer types, as integer types may have
681 // been created by earlier scalar replacement.
682 if (IsFP1 || IsFP2) {
683 if (NewBitWidth == 32)
684 return Type::getFloatTy(Context);
685 if (NewBitWidth == 64)
686 return Type::getDoubleTy(Context);
687 }
688
689 return Type::getIntNTy(Context, NewBitWidth);
680690 }
681691
682692 /// CreateShuffleVectorCast - Creates a shuffle vector to convert one vector
743753 return CreateShuffleVectorCast(FromVal, ToType, Builder);
744754 }
745755
746 if (ToType->isVectorTy()) {
747 assert(isPowerOf2_64(AllocaSize / ToTypeSize) &&
748 "Partial vector access of an alloca must have a power-of-2 size "
749 "ratio.");
750 assert(Offset == 0 && "Can't extract a value of a smaller vector type "
751 "from a nonzero offset.");
752
753 const Type *ToElementTy = cast(ToType)->getElementType();
754 const Type *CastElementTy = getScaledElementType(ToElementTy,
756 if (isPowerOf2_64(AllocaSize / ToTypeSize)) {
757 assert(!(ToType->isVectorTy() && Offset != 0) && "Can't extract a value "
758 "of a smaller vector type at a nonzero offset.");
759
760 const Type *CastElementTy = getScaledElementType(FromType, ToType,
755761 ToTypeSize * 8);
756762 unsigned NumCastVectorElements = AllocaSize / ToTypeSize;
757763
759765 const Type *CastTy = VectorType::get(CastElementTy,
760766 NumCastVectorElements);
761767 Value *Cast = Builder.CreateBitCast(FromVal, CastTy, "tmp");
768
769 unsigned EltSize = TD.getTypeAllocSizeInBits(CastElementTy);
770 unsigned Elt = Offset/EltSize;
771 assert(EltSize*Elt == Offset && "Invalid modulus in validity checking");
762772 Value *Extract = Builder.CreateExtractElement(Cast, ConstantInt::get(
763 Type::getInt32Ty(Context), 0), "tmp");
773 Type::getInt32Ty(Context), Elt), "tmp");
764774 return Builder.CreateBitCast(Extract, ToType, "tmp");
765775 }
766776
892902 return CreateShuffleVectorCast(SV, VTy, Builder);
893903 }
894904
895 if (SV->getType()->isVectorTy() && isPowerOf2_64(VecSize / ValSize)) {
896 assert(Offset == 0 && "Can't insert a value of a smaller vector type at "
897 "a nonzero offset.");
898
899 const Type *ToElementTy =
900 cast(SV->getType())->getElementType();
901 const Type *CastElementTy = getScaledElementType(ToElementTy, ValSize);
905 if (isPowerOf2_64(VecSize / ValSize)) {
906 assert(!(SV->getType()->isVectorTy() && Offset != 0) && "Can't insert a "
907 "value of a smaller vector type at a nonzero offset.");
908
909 const Type *CastElementTy = getScaledElementType(VTy, SV->getType(),
910 ValSize);
902911 unsigned NumCastVectorElements = VecSize / ValSize;
903912
904913 LLVMContext &Context = SV->getContext();
907916 Value *OldCast = Builder.CreateBitCast(Old, OldCastTy, "tmp");
908917
909918 Value *SVCast = Builder.CreateBitCast(SV, CastElementTy, "tmp");
919
920 unsigned EltSize = TD.getTypeAllocSizeInBits(CastElementTy);
921 unsigned Elt = Offset/EltSize;
922 assert(EltSize*Elt == Offset && "Invalid modulus in validity checking");
910923 Value *Insert =
911924 Builder.CreateInsertElement(OldCast, SVCast, ConstantInt::get(
912 Type::getInt32Ty(Context), 0), "tmp");
925 Type::getInt32Ty(Context), Elt), "tmp");
913926 return Builder.CreateBitCast(Insert, AllocaType, "tmp");
914927 }
915928
247247 ; CHECK: shufflevector <4 x i64> %tmpV2, <4 x i64> undef, <3 x i32>
248248 }
249249
250 define <4 x float> @test16(<4 x float> %x, i64 %y0, i64 %y1) {
251 entry:
252 %tmp8 = bitcast <4 x float> undef to <2 x double>
253 %tmp9 = bitcast i64 %y0 to double
254 %tmp10 = insertelement <2 x double> %tmp8, double %tmp9, i32 0
255 %tmp11 = bitcast <2 x double> %tmp10 to <4 x float>
256 %tmp3 = bitcast <4 x float> %tmp11 to <2 x double>
257 %tmp4 = bitcast i64 %y1 to double
258 %tmp5 = insertelement <2 x double> %tmp3, double %tmp4, i32 1
259 %tmp6 = bitcast <2 x double> %tmp5 to <4 x float>
260 ret <4 x float> %tmp6
261 ; CHECK: @test16
262 ; CHECK-NOT: alloca
263 ; CHECK: bitcast <4 x float> %tmp11 to <2 x double>
264 }