Skip to content

Commit

Permalink
[PPC] [AIX] Implement calling convention IR for C99 complex types on AIX
Browse files Browse the repository at this point in the history
Add AIX calling convention logic to Clang for C99 complex types on AIX

Differential Revision: https://reviews.llvm.org/D88130
  • Loading branch information
cebowler authored and ZarkoT committed Sep 25, 2020
1 parent 8524476 commit f330d9f
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 37 deletions.
9 changes: 5 additions & 4 deletions clang/lib/CodeGen/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4504,7 +4504,7 @@ bool AIXABIInfo::isPromotableTypeForABI(QualType Ty) const {

ABIArgInfo AIXABIInfo::classifyReturnType(QualType RetTy) const {
if (RetTy->isAnyComplexType())
llvm::report_fatal_error("complex type is not supported on AIX yet");
return ABIArgInfo::getDirect();

if (RetTy->isVectorType())
llvm::report_fatal_error("vector type is not supported on AIX yet");
Expand All @@ -4525,7 +4525,7 @@ ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const {
Ty = useFirstFieldIfTransparentUnion(Ty);

if (Ty->isAnyComplexType())
llvm::report_fatal_error("complex type is not supported on AIX yet");
return ABIArgInfo::getDirect();

if (Ty->isVectorType())
llvm::report_fatal_error("vector type is not supported on AIX yet");
Expand All @@ -4550,8 +4550,9 @@ ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const {
}

CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const {
if (Ty->isAnyComplexType())
llvm::report_fatal_error("complex type is not supported on AIX yet");
// Complex types are passed just like their elements.
if (const ComplexType *CTy = Ty->getAs<ComplexType>())
Ty = CTy->getElementType();

if (Ty->isVectorType())
llvm::report_fatal_error("vector type is not supported on AIX yet");
Expand Down
10 changes: 0 additions & 10 deletions clang/test/CodeGen/aix-complex.c

This file was deleted.

51 changes: 28 additions & 23 deletions clang/test/CodeGen/powerpc-c99complex.c
Original file line number Diff line number Diff line change
@@ -1,39 +1,44 @@
// RUN: %clang_cc1 -triple powerpc64-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefixes=PPC64LNX
// RUN: %clang_cc1 -triple ppc64le-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefixes=PPC64LNX
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOLDBL128
// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOLDBL128
// RUN: %clang_cc1 -triple powerpc64-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LDBL128
// RUN: %clang_cc1 -triple ppc64le-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LDBL128
// RUN: %clang_cc1 -triple powerpc-unknown-linux -emit-llvm %s -o - | FileCheck %s --check-prefix=PPC32LNX

_Complex float foo1(_Complex float x) {
return x;
// PPC64LNX-LABEL: define { float, float } @foo1(float %x.{{.*}}, float %x.{{.*}}) #0 {
// PPC64LNX: ret { float, float }
// CHECK-LABEL: define { float, float } @foo1(float %x.{{.*}}, float %x.{{.*}}) #0 {
// CHECK: ret { float, float }

// PPC32LNX-LABEL: define void @foo1({ float, float }* noalias sret align 4 %agg.result, { float, float }* byval({ float, float }) align 4 %x) #0 {
// PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds { float, float }, { float, float }* %agg.result, i32 0, i32 0
// PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds { float, float }, { float, float }* %agg.result, i32 0, i32 1
// PPC32LNX-NEXT: store float %{{.*}}, float* [[RETREAL]], align 4
// PPC32LNX-NEXT: store float %{{.*}}, float* [[RETIMAG]], align 4
// PPC32LNX-LABEL: define void @foo1({ float, float }* noalias sret align 4 %agg.result, { float, float }* byval({ float, float }) align 4 %x) #0 {
// PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds { float, float }, { float, float }* %agg.result, i32 0, i32 0
// PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds { float, float }, { float, float }* %agg.result, i32 0, i32 1
// PPC32LNX-NEXT: store float %{{.*}}, float* [[RETREAL]], align 4
// PPC32LNX-NEXT: store float %{{.*}}, float* [[RETIMAG]], align 4
}

_Complex double foo2(_Complex double x) {
return x;
// PPC64LNX-LABEL: define { double, double } @foo2(double %x.{{.*}}, double %x.{{.*}}) #0 {
// PPC64LNX: ret { double, double }
// CHECK-LABEL: define { double, double } @foo2(double %x.{{.*}}, double %x.{{.*}}) #0 {
// CHECK: ret { double, double }

// PPC32LNX-LABEL: define void @foo2({ double, double }* noalias sret align 8 %agg.result, { double, double }* byval({ double, double }) align 8 %x) #0 {
// PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds { double, double }, { double, double }* %agg.result, i32 0, i32 0
// PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds { double, double }, { double, double }* %agg.result, i32 0, i32 1
// PPC32LNX-NEXT: store double %{{.*}}, double* [[RETREAL]], align 8
// PPC32LNX-NEXT: store double %{{.*}}, double* [[RETIMAG]], align 8
// PPC32LNX-LABEL: define void @foo2({ double, double }* noalias sret align 8 %agg.result, { double, double }* byval({ double, double }) align 8 %x) #0 {
// PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds { double, double }, { double, double }* %agg.result, i32 0, i32 0
// PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds { double, double }, { double, double }* %agg.result, i32 0, i32 1
// PPC32LNX-NEXT: store double %{{.*}}, double* [[RETREAL]], align 8
// PPC32LNX-NEXT: store double %{{.*}}, double* [[RETIMAG]], align 8
}

_Complex long double foo3(_Complex long double x) {
return x;
// PPC64LNX-LABEL: define { ppc_fp128, ppc_fp128 } @foo3(ppc_fp128 %x.{{.*}}, ppc_fp128 %x.{{.*}}) #0 {
// PPC64LNX: ret { ppc_fp128, ppc_fp128 }
// CHECK-NOLDBL128-LABEL: define { double, double } @foo3(double %x.{{.*}}, double %x.{{.*}}) #0 {
// CHECK-NOLDBL128: ret { double, double }

// PPC32LNX-LABEL: define void @foo3({ ppc_fp128, ppc_fp128 }* noalias sret align 16 %agg.result, { ppc_fp128, ppc_fp128 }* byval({ ppc_fp128, ppc_fp128 }) align 16 %x) #0 {
// PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, { ppc_fp128, ppc_fp128 }* %agg.result, i32 0, i32 0
// PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, { ppc_fp128, ppc_fp128 }* %agg.result, i32 0, i32 1
// PPC32LNX-NEXT: store ppc_fp128 %{{.*}}, ppc_fp128* [[RETREAL]], align 16
// PPC32LNX-NEXT: store ppc_fp128 %{{.*}}, ppc_fp128* [[RETIMAG]], align 16
// CHECK-LDBL128-LABEL: define { ppc_fp128, ppc_fp128 } @foo3(ppc_fp128 %x.{{.*}}, ppc_fp128 %x.{{.*}}) #0 {
// CHECK-LDBL128: ret { ppc_fp128, ppc_fp128 }

// PPC32LNX-LABEL: define void @foo3({ ppc_fp128, ppc_fp128 }* noalias sret align 16 %agg.result, { ppc_fp128, ppc_fp128 }* byval({ ppc_fp128, ppc_fp128 }) align 16 %x) #0 {
// PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, { ppc_fp128, ppc_fp128 }* %agg.result, i32 0, i32 0
// PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, { ppc_fp128, ppc_fp128 }* %agg.result, i32 0, i32 1
// PPC32LNX-NEXT: store ppc_fp128 %{{.*}}, ppc_fp128* [[RETREAL]], align 16
// PPC32LNX-NEXT: store ppc_fp128 %{{.*}}, ppc_fp128* [[RETIMAG]], align 16
}

0 comments on commit f330d9f

Please sign in to comment.