Thanks, with the testcase this LGTM! -- adrian > On May 11, 2017, at 12:07 AM, Andrew Jeffery <and...@aj.id.au> wrote: > > Ping - does anyone have a moment to take a look? > > Cheers, > > Andrew > > On Thu, 2017-04-27 at 13:52 +0930, Andrew Jeffery wrote: >> 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> >> --- >> 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 aab3160af0f9..e32ad0b2dc39 100644 >> --- a/lib/Basic/Targets.cpp >> +++ b/lib/Basic/Targets.cpp >> @@ -1708,6 +1708,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 d2fc3888ef29..6193f6c4ac29 100644 >> --- a/lib/CodeGen/TargetInfo.cpp >> +++ b/lib/CodeGen/TargetInfo.cpp >> @@ -4175,7 +4175,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, >> @@ -4219,7 +4219,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; >> @@ -4262,6 +4262,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 000000000000..fa00484fc185 >> --- /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 000000000000..b94932b1f8c7 >> --- /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 c1f098172371..4ee06b58ea42 100644 >> --- a/test/CodeGen/64bit-swiftcall.c >> +++ b/test/CodeGen/64bit-swiftcall.c >> @@ -1,7 +1,8 @@ >> // 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: >> aarch64-registered-target,x86-registered-target,powerpc-registered-target >> >> #define SWIFTCALL __attribute__((swiftcall)) >> #define OUT __attribute__((swift_indirect_result)) >> @@ -66,8 +67,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))); >> @@ -368,94 +367,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));
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits