For the tests I've extracted the int5 and int8 cases to cater for different alignments for different platform ABIs. For Linux on POWER the 5 and 8 element vectors must be naturally aligned with respect to the total "soft" vector size, despite being represented as an aggregate. Specifically, the patch caters for the following differences in supporting powerpc64le-unknown-linux:
$ diff -u test/CodeGen/64bit-swiftcall.c test/CodeGen/ppc64-swiftcall.c --- test/CodeGen/64bit-swiftcall.c 2017-04-20 17:14:59.797963820 +0930 +++ test/CodeGen/ppc64-swiftcall.c 2017-04-20 17:15:11.621965118 +0930 @@ -1,7 +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 powerpc64le-unknown-linux -emit-llvm -o - %s | FileCheck %s -// REQUIRES: aarch64-registered-target,x86-registered-target +// REQUIRES: powerpc-registered-target #define SWIFTCALL __attribute__((swiftcall)) #define OUT __attribute__((swift_indirect_result)) @@ -370,8 +369,8 @@ TEST(int8) // CHECK-LABEL: define {{.*}} @return_int8() -// CHECK: [[RET:%.*]] = alloca [[REC:<8 x i32>]], align 16 +// CHECK: [[RET:%.*]] = alloca [[REC:<8 x i32>]], align 32 // CHECK: [[VAR:%.*]] = alloca [[REC]], align // CHECK: store // CHECK: load // CHECK: store @@ -414,8 +413,8 @@ TEST(int5) // CHECK-LABEL: define {{.*}} @return_int5() -// CHECK: [[RET:%.*]] = alloca [[REC:<5 x i32>]], align 16 +// CHECK: [[RET:%.*]] = alloca [[REC:<5 x i32>]], align 32 // CHECK: [[VAR:%.*]] = alloca [[REC]], align // CHECK: store // CHECK: load // CHECK: store Despite some duplication, the advantage of this approach over using pattern matching for alignment in 64bit-swiftcall.c is that we ensure each platform is using the expected alignment but without duplicating the entirety of 64bit-swiftcall.c. Signed-off-by: Andrew Jeffery <and...@aj.id.au> --- Hello, The only change in v3 is rebasing it on top upstream HEAD, fixing a conflict in one of the lit REQUIRES lines. Ulrich, Hal, Bill: I've Cc'ed you as you were fingered by the blame output. As some background I sent the patch several months ago but it hasn't got much traction aside from a LGTM from Adrian (thanks!). I'm hoping it gets a bit more attention as without it we get build failures for Swift on POWER, which is in-turn blocking some CI efforts. Cheers, Andrew lib/Basic/Targets.cpp | 11 ++ lib/CodeGen/TargetInfo.cpp | 14 ++- test/CodeGen/64bit-swiftcall-extvec-agg-align16.c | 117 ++++++++++++++++++++++ test/CodeGen/64bit-swiftcall-extvec-agg-align32.c | 116 +++++++++++++++++++++ test/CodeGen/64bit-swiftcall.c | 93 +---------------- 5 files changed, 258 insertions(+), 93 deletions(-) create mode 100644 test/CodeGen/64bit-swiftcall-extvec-agg-align16.c create mode 100644 test/CodeGen/64bit-swiftcall-extvec-agg-align32.c diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index e23a93e..54b5911 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -1753,6 +1753,17 @@ public: } return false; } + + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + case CC_C: + case CC_Swift: + return CCCR_OK; + default: + break; + } + return CCCR_Warning; + } }; class DarwinPPC32TargetInfo : public DarwinTargetInfo<PPC32TargetInfo> { diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 8d00e05..a82cd24 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -4179,7 +4179,7 @@ PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, namespace { /// PPC64_SVR4_ABIInfo - The 64-bit PowerPC ELF (SVR4) ABI information. -class PPC64_SVR4_ABIInfo : public ABIInfo { +class PPC64_SVR4_ABIInfo : public SwiftABIInfo { public: enum ABIKind { ELFv1 = 0, @@ -4223,7 +4223,7 @@ private: public: PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, ABIKind Kind, bool HasQPX, bool SoftFloatABI) - : ABIInfo(CGT), Kind(Kind), HasQPX(HasQPX), + : SwiftABIInfo(CGT), Kind(Kind), HasQPX(HasQPX), IsSoftFloatABI(SoftFloatABI) {} bool isPromotableTypeForABI(QualType Ty) const; @@ -4266,6 +4266,16 @@ public: Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const override; + + bool shouldPassIndirectlyForSwift(CharUnits totalSize, + ArrayRef<llvm::Type*> scalars, + bool asReturnValue) const override { + return occupiesMoreThan(CGT, scalars, /*total*/ 4); + } + + bool isSwiftErrorInRegister() const override { + return true; + } }; class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo { diff --git a/test/CodeGen/64bit-swiftcall-extvec-agg-align16.c b/test/CodeGen/64bit-swiftcall-extvec-agg-align16.c new file mode 100644 index 0000000..fa00484 --- /dev/null +++ b/test/CodeGen/64bit-swiftcall-extvec-agg-align16.c @@ -0,0 +1,117 @@ +// 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 + +// REQUIRES: aarch64-registered-target,x86-registered-target + +#define SWIFTCALL __attribute__((swiftcall)) + +/*****************************************************************************/ +/********************************** LOWERING *********************************/ +/*****************************************************************************/ + +typedef int int5 __attribute__((ext_vector_type(5))); +typedef int int8 __attribute__((ext_vector_type(8))); + +#define TEST(TYPE) \ + SWIFTCALL TYPE return_##TYPE(void) { \ + TYPE result = {}; \ + return result; \ + } \ + SWIFTCALL void take_##TYPE(TYPE v) { \ + } \ + void test_##TYPE() { \ + take_##TYPE(return_##TYPE()); \ + } + + +/*****************************************************************************/ +/****************************** VECTOR LEGALIZATION **************************/ +/*****************************************************************************/ + +TEST(int8) +// CHECK-LABEL: define {{.*}} @return_int8() +// CHECK: [[RET:%.*]] = alloca [[REC:<8 x i32>]], align 16 +// CHECK: [[VAR:%.*]] = alloca [[REC]], align +// CHECK: store +// CHECK: load +// CHECK: store +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, <4 x i32> }]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, <4 x i32> }]] undef, <4 x i32> [[FIRST]], 0 +// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], <4 x i32> [[SECOND]], 1 +// CHECK: ret [[UAGG]] [[T1]] +// CHECK-LABEL: define {{.*}} @take_int8(<4 x i32>, <4 x i32>) +// CHECK: [[V:%.*]] = alloca [[REC]], align +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: store <4 x i32> %0, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: store <4 x i32> %1, <4 x i32>* [[T0]], align +// CHECK: ret void +// CHECK-LABEL: define void @test_int8() +// CHECK: [[TMP1:%.*]] = alloca [[REC]], align +// CHECK: [[TMP2:%.*]] = alloca [[REC]], align +// CHECK: [[CALL:%.*]] = call [[SWIFTCC:swiftcc]] [[UAGG]] @return_int8() +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0 +// CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1 +// CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align +// CHECK: [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align +// CHECK: store [[REC]] [[V]], [[REC]]* [[TMP2]], align +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: call [[SWIFTCC]] void @take_int8(<4 x i32> [[FIRST]], <4 x i32> [[SECOND]]) +// CHECK: ret void + +TEST(int5) +// CHECK-LABEL: define {{.*}} @return_int5() +// CHECK: [[RET:%.*]] = alloca [[REC:<5 x i32>]], align 16 +// CHECK: [[VAR:%.*]] = alloca [[REC]], align +// CHECK: store +// CHECK: load +// CHECK: store +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, i32 }]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align +// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, i32 }]] undef, <4 x i32> [[FIRST]], 0 +// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1 +// CHECK: ret [[UAGG]] [[T1]] +// CHECK-LABEL: define {{.*}} @take_int5(<4 x i32>, i32) +// CHECK: [[V:%.*]] = alloca [[REC]], align +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: store <4 x i32> %0, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: store i32 %1, i32* [[T0]], align +// CHECK: ret void +// CHECK-LABEL: define void @test_int5() +// CHECK: [[TMP1:%.*]] = alloca [[REC]], align +// CHECK: [[TMP2:%.*]] = alloca [[REC]], align +// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int5() +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0 +// CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1 +// CHECK: store i32 [[T1]], i32* [[T0]], align +// CHECK: [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align +// CHECK: store [[REC]] [[V]], [[REC]]* [[TMP2]], align +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align +// CHECK: call [[SWIFTCC]] void @take_int5(<4 x i32> [[FIRST]], i32 [[SECOND]]) +// CHECK: ret void diff --git a/test/CodeGen/64bit-swiftcall-extvec-agg-align32.c b/test/CodeGen/64bit-swiftcall-extvec-agg-align32.c new file mode 100644 index 0000000..b94932b --- /dev/null +++ b/test/CodeGen/64bit-swiftcall-extvec-agg-align32.c @@ -0,0 +1,116 @@ +// RUN: %clang_cc1 -triple powerpc64le-unknown-linux -emit-llvm -o - %s | FileCheck %s + +// REQUIRES: powerpc-registered-target + +#define SWIFTCALL __attribute__((swiftcall)) + +/*****************************************************************************/ +/********************************** LOWERING *********************************/ +/*****************************************************************************/ + +typedef int int5 __attribute__((ext_vector_type(5))); +typedef int int8 __attribute__((ext_vector_type(8))); + +#define TEST(TYPE) \ + SWIFTCALL TYPE return_##TYPE(void) { \ + TYPE result = {}; \ + return result; \ + } \ + SWIFTCALL void take_##TYPE(TYPE v) { \ + } \ + void test_##TYPE() { \ + take_##TYPE(return_##TYPE()); \ + } + + +/*****************************************************************************/ +/****************************** VECTOR LEGALIZATION **************************/ +/*****************************************************************************/ + +TEST(int8) +// CHECK-LABEL: define {{.*}} @return_int8() +// CHECK: [[RET:%.*]] = alloca [[REC:<8 x i32>]], align 32 +// CHECK: [[VAR:%.*]] = alloca [[REC]], align +// CHECK: store +// CHECK: load +// CHECK: store +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, <4 x i32> }]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, <4 x i32> }]] undef, <4 x i32> [[FIRST]], 0 +// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], <4 x i32> [[SECOND]], 1 +// CHECK: ret [[UAGG]] [[T1]] +// CHECK-LABEL: define {{.*}} @take_int8(<4 x i32>, <4 x i32>) +// CHECK: [[V:%.*]] = alloca [[REC]], align +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: store <4 x i32> %0, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: store <4 x i32> %1, <4 x i32>* [[T0]], align +// CHECK: ret void +// CHECK-LABEL: define void @test_int8() +// CHECK: [[TMP1:%.*]] = alloca [[REC]], align +// CHECK: [[TMP2:%.*]] = alloca [[REC]], align +// CHECK: [[CALL:%.*]] = call [[SWIFTCC:swiftcc]] [[UAGG]] @return_int8() +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0 +// CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1 +// CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align +// CHECK: [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align +// CHECK: store [[REC]] [[V]], [[REC]]* [[TMP2]], align +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: call [[SWIFTCC]] void @take_int8(<4 x i32> [[FIRST]], <4 x i32> [[SECOND]]) +// CHECK: ret void + +TEST(int5) +// CHECK-LABEL: define {{.*}} @return_int5() +// CHECK: [[RET:%.*]] = alloca [[REC:<5 x i32>]], align 32 +// CHECK: [[VAR:%.*]] = alloca [[REC]], align +// CHECK: store +// CHECK: load +// CHECK: store +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, i32 }]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align +// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, i32 }]] undef, <4 x i32> [[FIRST]], 0 +// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1 +// CHECK: ret [[UAGG]] [[T1]] +// CHECK-LABEL: define {{.*}} @take_int5(<4 x i32>, i32) +// CHECK: [[V:%.*]] = alloca [[REC]], align +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: store <4 x i32> %0, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: store i32 %1, i32* [[T0]], align +// CHECK: ret void +// CHECK-LABEL: define void @test_int5() +// CHECK: [[TMP1:%.*]] = alloca [[REC]], align +// CHECK: [[TMP2:%.*]] = alloca [[REC]], align +// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int5() +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0 +// CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1 +// CHECK: store i32 [[T1]], i32* [[T0]], align +// CHECK: [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align +// CHECK: store [[REC]] [[V]], [[REC]]* [[TMP2]], align +// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]* +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 +// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align +// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 +// CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align +// CHECK: call [[SWIFTCC]] void @take_int5(<4 x i32> [[FIRST]], i32 [[SECOND]]) +// CHECK: ret void diff --git a/test/CodeGen/64bit-swiftcall.c b/test/CodeGen/64bit-swiftcall.c index 92ba37c..21f182d 100644 --- a/test/CodeGen/64bit-swiftcall.c +++ b/test/CodeGen/64bit-swiftcall.c @@ -2,8 +2,9 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s --check-prefix=X86-64 // 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 +// RUN: %clang_cc1 -triple powerpc64le-unknown-linux -emit-llvm -o - %s | FileCheck %s -// REQUIRES: aarch64-registered-target,x86-registered-target +// REQUIRES: powerpc-registered-target #define SWIFTCALL __attribute__((swiftcall)) #define OUT __attribute__((swift_indirect_result)) @@ -69,8 +70,6 @@ typedef double double2 __attribute__((ext_vector_type(2))); typedef double double4 __attribute__((ext_vector_type(4))); typedef int int3 __attribute__((ext_vector_type(3))); typedef int int4 __attribute__((ext_vector_type(4))); -typedef int int5 __attribute__((ext_vector_type(5))); -typedef int int8 __attribute__((ext_vector_type(8))); typedef char char16 __attribute__((ext_vector_type(16))); typedef short short8 __attribute__((ext_vector_type(8))); typedef long long long2 __attribute__((ext_vector_type(2))); @@ -371,94 +370,6 @@ TEST(int4) // CHECK-LABEL: define {{.*}} <4 x i32> @return_int4() // CHECK-LABEL: define {{.*}} @take_int4(<4 x i32> -TEST(int8) -// CHECK-LABEL: define {{.*}} @return_int8() -// CHECK: [[RET:%.*]] = alloca [[REC:<8 x i32>]], align 16 -// CHECK: [[VAR:%.*]] = alloca [[REC]], align -// CHECK: store -// CHECK: load -// CHECK: store -// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, <4 x i32> }]]* -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 -// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 -// CHECK: [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align -// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, <4 x i32> }]] undef, <4 x i32> [[FIRST]], 0 -// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], <4 x i32> [[SECOND]], 1 -// CHECK: ret [[UAGG]] [[T1]] -// CHECK-LABEL: define {{.*}} @take_int8(<4 x i32>, <4 x i32>) -// CHECK: [[V:%.*]] = alloca [[REC]], align -// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]* -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 -// CHECK: store <4 x i32> %0, <4 x i32>* [[T0]], align -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 -// CHECK: store <4 x i32> %1, <4 x i32>* [[T0]], align -// CHECK: ret void -// CHECK-LABEL: define void @test_int8() -// CHECK: [[TMP1:%.*]] = alloca [[REC]], align -// CHECK: [[TMP2:%.*]] = alloca [[REC]], align -// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int8() -// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]* -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 -// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0 -// CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 -// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1 -// CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align -// CHECK: [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align -// CHECK: store [[REC]] [[V]], [[REC]]* [[TMP2]], align -// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]* -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 -// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 -// CHECK: [[SECOND:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align -// CHECK: call [[SWIFTCC]] void @take_int8(<4 x i32> [[FIRST]], <4 x i32> [[SECOND]]) -// CHECK: ret void - -TEST(int5) -// CHECK-LABEL: define {{.*}} @return_int5() -// CHECK: [[RET:%.*]] = alloca [[REC:<5 x i32>]], align 16 -// CHECK: [[VAR:%.*]] = alloca [[REC]], align -// CHECK: store -// CHECK: load -// CHECK: store -// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[RET]] to [[AGG:{ <4 x i32>, i32 }]]* -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 -// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 -// CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align -// CHECK: [[T0:%.*]] = insertvalue [[UAGG:{ <4 x i32>, i32 }]] undef, <4 x i32> [[FIRST]], 0 -// CHECK: [[T1:%.*]] = insertvalue [[UAGG]] [[T0]], i32 [[SECOND]], 1 -// CHECK: ret [[UAGG]] [[T1]] -// CHECK-LABEL: define {{.*}} @take_int5(<4 x i32>, i32) -// CHECK: [[V:%.*]] = alloca [[REC]], align -// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[V]] to [[AGG]]* -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 -// CHECK: store <4 x i32> %0, <4 x i32>* [[T0]], align -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 -// CHECK: store i32 %1, i32* [[T0]], align -// CHECK: ret void -// CHECK-LABEL: define void @test_int5() -// CHECK: [[TMP1:%.*]] = alloca [[REC]], align -// CHECK: [[TMP2:%.*]] = alloca [[REC]], align -// CHECK: [[CALL:%.*]] = call [[SWIFTCC]] [[UAGG]] @return_int5() -// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP1]] to [[AGG]]* -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 -// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 0 -// CHECK: store <4 x i32> [[T1]], <4 x i32>* [[T0]], align -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 -// CHECK: [[T1:%.*]] = extractvalue [[UAGG]] [[CALL]], 1 -// CHECK: store i32 [[T1]], i32* [[T0]], align -// CHECK: [[V:%.*]] = load [[REC]], [[REC]]* [[TMP1]], align -// CHECK: store [[REC]] [[V]], [[REC]]* [[TMP2]], align -// CHECK: [[CAST_TMP:%.*]] = bitcast [[REC]]* [[TMP2]] to [[AGG]]* -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 0 -// CHECK: [[FIRST:%.*]] = load <4 x i32>, <4 x i32>* [[T0]], align -// CHECK: [[T0:%.*]] = getelementptr inbounds [[AGG]], [[AGG]]* [[CAST_TMP]], i32 0, i32 1 -// CHECK: [[SECOND:%.*]] = load i32, i32* [[T0]], align -// CHECK: call [[SWIFTCC]] void @take_int5(<4 x i32> [[FIRST]], i32 [[SECOND]]) -// CHECK: ret void - typedef struct { int x; int3 v __attribute__((packed)); -- 2.9.3 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits