[PATCH v2] [PPC64]: Add support for Swift calling convention

Adrian Prantl via cfe-commits cfe-commits at lists.llvm.org
Thu May 11 08:46:15 PDT 2017


Thanks, with the testcase this LGTM!

-- adrian
> On May 11, 2017, at 12:07 AM, Andrew Jeffery <andrew at 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 <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));



More information about the cfe-commits mailing list