aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/TargetInfo.cpp8
-rw-r--r--test/CodeGen/arm-arguments.c19
2 files changed, 27 insertions, 0 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 92ff312425..c0b5f655fa 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -1661,6 +1661,14 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
if (isEmptyRecord(Context, RetTy, false))
return ABIArgInfo::getIgnore();
+ // Complex types are all returned as packed integers.
+ //
+ // FIXME: Consider using 2 x vector types if the back end handles them
+ // correctly.
+ if (RetTy->isAnyComplexType())
+ return ABIArgInfo::getCoerce(llvm::IntegerType::get(
+ VMContext, Context.getTypeSize(RetTy)));
+
// Integer like structures are returned in r0.
if (isIntegerLikeType(RetTy, Context, VMContext)) {
// Return in the smallest viable integer type.
diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c
index c97c97bc58..e5b41da38b 100644
--- a/test/CodeGen/arm-arguments.c
+++ b/test/CodeGen/arm-arguments.c
@@ -119,3 +119,22 @@ struct s20 f20(void) {}
// AAPCS: define arm_aapcscc i32 @f21()
struct s21 { struct {} f1; int f0 : 4; };
struct s21 f21(void) {}
+
+// APCS-GNU: define arm_apcscc i16 @f22()
+// APCS-GNU: define arm_apcscc i32 @f23()
+// APCS-GNU: define arm_apcscc i64 @f24()
+// APCS-GNU: define arm_apcscc i128 @f25()
+// APCS-GNU: define arm_apcscc i64 @f26()
+// APCS-GNU: define arm_apcscc i128 @f27()
+// AAPCS: define arm_aapcscc i16 @f22()
+// AAPCS: define arm_aapcscc i32 @f23()
+// AAPCS: define arm_aapcscc void @f24({{.*}} noalias sret
+// AAPCS: define arm_aapcscc void @f25({{.*}} noalias sret
+// AAPCS: define arm_aapcscc void @f26({{.*}} noalias sret
+// AAPCS: define arm_aapcscc void @f27({{.*}} noalias sret
+_Complex char f22(void) {}
+_Complex short f23(void) {}
+_Complex int f24(void) {}
+_Complex long long f25(void) {}
+_Complex float f26(void) {}
+_Complex double f27(void) {}