[PATCH v2] [PPC64]: Add support for Swift calling convention
Andrew Jeffery via cfe-commits
cfe-commits at lists.llvm.org
Thu May 11 00:07:09 PDT 2017
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 <andrew at 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));
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: This is a digitally signed message part
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170511/fdf8352e/attachment-0001.sig>
More information about the cfe-commits
mailing list