Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
if (Field1Ty)
return false;
QualType EltTy = CTy->getElementType();
// Only floating-point complex types (e.g. _Complex float/double) are
// eligible to be passed in floating-point argument registers. Complex
// integer types (a GNU extension) should be treated like a normal
// aggregate and packed into GPRs instead.
if (!EltTy->isRealFloatingType())
return false;
if (getContext().getTypeSize(EltTy) > FLen)
return false;
Field1Ty = CGT.ConvertType(EltTy);
Expand Down
27 changes: 9 additions & 18 deletions clang/test/CodeGen/RISCV/riscv32-abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1888,14 +1888,15 @@ struct float16complex_s f_ret_float16complex_s(void) {
return (struct float16complex_s){1.0};
}

// CHECK-LABEL: define{{.*}} i64 @f_ucharcomplex(i64 %x.coerce)
// Complex integer values or structs containing a single complex
// integer value should be passed as if it were an int+int struct.

// ILP32-ILP32F-ILP32D-LABEL: define dso_local i16 @f_ucharcomplex
// ILP32-ILP32F-ILP32D-SAME: (i16 noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
unsigned char __complex__ f_ucharcomplex(unsigned char __complex__ x) { return x; }

// CHECK-LABEL: define{{.*}} i64 @f_ushortcomplex(i64 %x.coerce)
// ILP32-ILP32F-ILP32D-LABEL: define dso_local i32 @f_ushortcomplex
// ILP32-ILP32F-ILP32D-SAME: (i32 noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
Expand All @@ -1905,14 +1906,9 @@ unsigned short __complex__ f_ushortcomplex(unsigned short __complex__ x) { retur
struct ucharcomplex_s {
unsigned char __complex__ c;
};
// CHECK-LABEL: define{{.*}} i64 @f_ucharcomplex_s(i64 %x.coerce)
// ILP32-LABEL: define dso_local i16 @f_ucharcomplex_s
// ILP32-SAME: (i16 [[X_COERCE:%.*]]) #[[ATTR0]] {
// ILP32: entry:
//
// ILP32F-ILP32D-LABEL: define dso_local { i8, i8 } @f_ucharcomplex_s
// ILP32F-ILP32D-SAME: (i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) #[[ATTR0]] {
// ILP32F-ILP32D: entry:
// ILP32-ILP32F-ILP32D-LABEL: define dso_local i16 @f_ucharcomplex_s
// ILP32-ILP32F-ILP32D-SAME: (i16 [[X_COERCE:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
struct ucharcomplex_s f_ucharcomplex_s(struct ucharcomplex_s x) {
return x;
Expand All @@ -1921,14 +1917,9 @@ struct ucharcomplex_s f_ucharcomplex_s(struct ucharcomplex_s x) {
struct ushortcomplex_s {
unsigned short __complex__ c;
};
// CHECK-LABEL: define{{.*}} i64 @f_ushortcomplex_s(i64 %x.coerce)
// ILP32-LABEL: define dso_local i32 @f_ushortcomplex_s
// ILP32-SAME: (i32 [[X_COERCE:%.*]]) #[[ATTR0]] {
// ILP32: entry:
//
// ILP32F-ILP32D-LABEL: define dso_local { i16, i16 } @f_ushortcomplex_s
// ILP32F-ILP32D-SAME: (i16 [[TMP0:%.*]], i16 [[TMP1:%.*]]) #[[ATTR0]] {
// ILP32F-ILP32D: entry:
// ILP32-ILP32F-ILP32D-LABEL: define dso_local i32 @f_ushortcomplex_s
// ILP32-ILP32F-ILP32D-SAME: (i32 [[X_COERCE:%.*]]) #[[ATTR0]] {
// ILP32-ILP32F-ILP32D: entry:
//
struct ushortcomplex_s f_ushortcomplex_s(struct ushortcomplex_s x) {
return x;
Expand Down
27 changes: 9 additions & 18 deletions clang/test/CodeGen/RISCV/riscv64-abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -709,14 +709,15 @@ struct floatcomplex_s f_ret_floatcomplex_s(void) {
return (struct floatcomplex_s){1.0};
}

// CHECK-LABEL: define{{.*}} i64 @f_ucharcomplex(i64 %x.coerce)
// Complex integer values or structs containing a single complex
// integer value should be passed as if it were an int+int struct.

// LP64-LP64F-LP64D-LABEL: define dso_local i16 @f_ucharcomplex
// LP64-LP64F-LP64D-SAME: (i16 noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
unsigned char __complex__ f_ucharcomplex(unsigned char __complex__ x) { return x; }

// CHECK-LABEL: define{{.*}} i64 @f_ushortcomplex(i64 %x.coerce)
// LP64-LP64F-LP64D-LABEL: define dso_local i32 @f_ushortcomplex
// LP64-LP64F-LP64D-SAME: (i32 noundef [[X_COERCE:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
Expand All @@ -726,14 +727,9 @@ unsigned short __complex__ f_ushortcomplex(unsigned short __complex__ x) { retur
struct ucharcomplex_s {
unsigned char __complex__ c;
};
// CHECK-LABEL: define{{.*}} i64 @f_ucharcomplex_s(i64 %x.coerce)
// LP64-LABEL: define dso_local i16 @f_ucharcomplex_s
// LP64-SAME: (i16 [[X_COERCE:%.*]]) #[[ATTR0]] {
// LP64: entry:
//
// LP64F-LP64D-LABEL: define dso_local { i8, i8 } @f_ucharcomplex_s
// LP64F-LP64D-SAME: (i8 [[TMP0:%.*]], i8 [[TMP1:%.*]]) #[[ATTR0]] {
// LP64F-LP64D: entry:
// LP64-LP64F-LP64D-LABEL: define dso_local i16 @f_ucharcomplex_s
// LP64-LP64F-LP64D-SAME: (i16 [[X_COERCE:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
struct ucharcomplex_s f_ucharcomplex_s(struct ucharcomplex_s x) {
return x;
Expand All @@ -742,14 +738,9 @@ struct ucharcomplex_s f_ucharcomplex_s(struct ucharcomplex_s x) {
struct ushortcomplex_s {
unsigned short __complex__ c;
};
// CHECK-LABEL: define{{.*}} i64 @f_ushortcomplex_s(i64 %x.coerce)
// LP64-LABEL: define dso_local i32 @f_ushortcomplex_s
// LP64-SAME: (i32 [[X_COERCE:%.*]]) #[[ATTR0]] {
// LP64: entry:
//
// LP64F-LP64D-LABEL: define dso_local { i16, i16 } @f_ushortcomplex_s
// LP64F-LP64D-SAME: (i16 [[TMP0:%.*]], i16 [[TMP1:%.*]]) #[[ATTR0]] {
// LP64F-LP64D: entry:
// LP64-LP64F-LP64D-LABEL: define dso_local i32 @f_ushortcomplex_s
// LP64-LP64F-LP64D-SAME: (i32 [[X_COERCE:%.*]]) #[[ATTR0]] {
// LP64-LP64F-LP64D: entry:
//
struct ushortcomplex_s f_ushortcomplex_s(struct ushortcomplex_s x) {
return x;
Expand Down
Loading