diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 83aa1fdf5722..d0ba74119b7d 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -4821,6 +4821,9 @@ private: bool isSwiftErrorInRegister() const override { return true; } + + bool isLegalVectorTypeForSwift(CharUnits totalSize, llvm::Type *eltTy, + unsigned elts) const override; }; class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { @@ -4994,6 +4997,17 @@ bool AArch64ABIInfo::isIllegalVectorType(QualType Ty) const { return false; } +bool AArch64ABIInfo::isLegalVectorTypeForSwift(CharUnits totalSize, + llvm::Type *eltTy, + unsigned elts) const { + if (!llvm::isPowerOf2_32(elts)) + return false; + if (totalSize.getQuantity() != 8 && + (totalSize.getQuantity() != 16 || elts == 1)) + return false; + return true; +} + bool AArch64ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { // Homogeneous aggregates for AAPCS64 must have base types of a floating // point type or a short-vector type. This is the same as the 32-bit ABI, @@ -5382,6 +5396,8 @@ private: bool isSwiftErrorInRegister() const override { return true; } + bool isLegalVectorTypeForSwift(CharUnits totalSize, llvm::Type *eltTy, + unsigned elts) const override; }; class ARMTargetCodeGenInfo : public TargetCodeGenInfo { @@ -5894,6 +5910,20 @@ bool ARMABIInfo::isIllegalVectorType(QualType Ty) const { return false; } +bool ARMABIInfo::isLegalVectorTypeForSwift(CharUnits vectorSize, + llvm::Type *eltTy, + unsigned numElts) const { + if (!llvm::isPowerOf2_32(numElts)) + return false; + unsigned size = getDataLayout().getTypeStoreSizeInBits(eltTy); + if (size > 64) + return false; + if (vectorSize.getQuantity() != 8 && + (vectorSize.getQuantity() != 16 || numElts == 1)) + return false; + return true; +} + bool ARMABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { // Homogeneous aggregates for AAPCS-VFP must have base types of float, // double, or 64-bit or 128-bit vectors. diff --git a/clang/test/CodeGen/64bit-swiftcall.c b/clang/test/CodeGen/64bit-swiftcall.c index c1f098172371..06c314501552 100644 --- a/clang/test/CodeGen/64bit-swiftcall.c +++ b/clang/test/CodeGen/64bit-swiftcall.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM64 // REQUIRES: aarch64-registered-target,x86-registered-target @@ -60,6 +61,7 @@ SWIFTCALL void context_error_2(short s, CONTEXT int *self, ERROR float **error) /********************************** LOWERING *********************************/ /*****************************************************************************/ +typedef float float3 __attribute__((ext_vector_type(3))); typedef float float4 __attribute__((ext_vector_type(4))); typedef float float8 __attribute__((ext_vector_type(8))); typedef double double2 __attribute__((ext_vector_type(2))); @@ -1005,3 +1007,10 @@ struct { TEST(union_het_vecint) // CHECK: define swiftcc void @return_union_het_vecint([[UNION:%.*]]* noalias sret // CHECK: define swiftcc void @take_union_het_vecint([[UNION]]* + +typedef struct { + float3 f3; +} struct_v1f3; +TEST(struct_v1f3) +// ARM64-LABEL: define swiftcc { <2 x float>, float } @return_struct_v1f3() +// ARM64-LABEL: define swiftcc void @take_struct_v1f3(<2 x float>, float) diff --git a/clang/test/CodeGen/arm-swiftcall.c b/clang/test/CodeGen/arm-swiftcall.c index 5a7e17068b7c..f5c33845e2f4 100644 --- a/clang/test/CodeGen/arm-swiftcall.c +++ b/clang/test/CodeGen/arm-swiftcall.c @@ -57,6 +57,7 @@ SWIFTCALL void context_error_2(short s, CONTEXT int *self, ERROR float **error) /********************************** LOWERING *********************************/ /*****************************************************************************/ +typedef float float3 __attribute__((ext_vector_type(3))); typedef float float4 __attribute__((ext_vector_type(4))); typedef float float8 __attribute__((ext_vector_type(8))); typedef double double2 __attribute__((ext_vector_type(2))); @@ -1013,3 +1014,10 @@ typedef struct { TEST(struct_vf81) // CHECK-LABEL: define swiftcc { <4 x float>, <4 x float> } @return_struct_vf81() // CHECK-LABEL: define swiftcc void @take_struct_vf81(<4 x float>, <4 x float>) + +typedef struct { + float3 f3; +} struct_v1f3; +TEST(struct_v1f3) +// CHECK-LABEL: define swiftcc { <2 x float>, float } @return_struct_v1f3() +// CHECK-LABEL: define swiftcc void @take_struct_v1f3(<2 x float>, float)