Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RISCV] Handle empty structs/unions passing in C++ #97315

Merged
merged 4 commits into from
Jul 9, 2024
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
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,7 @@ RISC-V Support

- ``__attribute__((rvv_vector_bits(N)))`` is now supported for RVV vbool*_t types.
- Profile names in ``-march`` option are now supported.
- Passing empty structs/unions as arguments in C++ is now handled correctly. The behavior is similar to GCC's.

CUDA/HIP Language Changes
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/CodeGen/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,12 +361,13 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
CGCXXABI::RAA_DirectInMemory);
}

// Ignore empty structs/unions.
if (isEmptyRecord(getContext(), Ty, true))
return ABIArgInfo::getIgnore();

uint64_t Size = getContext().getTypeSize(Ty);

// Ignore empty structs/unions whose size is zero. According to the calling
// convention empty structs/unions are required to be sized types in C++.
if (isEmptyRecord(getContext(), Ty, true) && Size == 0)
return ABIArgInfo::getIgnore();

// Pass floating point values via FPRs if possible.
if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
FLen >= Size && ArgFPRsLeft) {
Expand Down
55 changes: 55 additions & 0 deletions clang/test/CodeGen/RISCV/abi-empty-structs.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,61 @@ struct s9 {
//
void test_s9(struct s9 a) {}

struct s10 { };
// CHECK-C-LABEL: define dso_local void @test_s10
// CHECK-C-SAME: () #[[ATTR0]] {
// CHECK-C: entry:
//
// CHECK32-CXX-LABEL: define dso_local i32 @_Z8test_s103s10
// CHECK32-CXX-SAME: (i32 [[A_COERCE:%.*]]) #[[ATTR0]] {
// CHECK32-CXX: entry:
//
// CHECK64-CXX-LABEL: define dso_local i64 @_Z8test_s103s10
// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {
// CHECK64-CXX: entry:
//
struct s10 test_s10(struct s10 a) {
return a;
}

struct s11 { int : 0; };
// CHECK-C-LABEL: define dso_local void @test_s11
// CHECK-C-SAME: () #[[ATTR0]] {
// CHECK-C: entry:
//
// CHECK32-CXX-LABEL: define dso_local i32 @_Z8test_s113s11
// CHECK32-CXX-SAME: (i32 [[A_COERCE:%.*]]) #[[ATTR0]] {
// CHECK32-CXX: entry:
//
// CHECK64-CXX-LABEL: define dso_local i64 @_Z8test_s113s11
// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {
// CHECK64-CXX: entry:
//
struct s11 test_s11(struct s11 a) {
return a;
}

struct s12 {int x[0];};
// CHECK32-C-LABEL: define dso_local i32 @test_s12
// CHECK32-C-SAME: (i32 noundef [[I1:%.*]], i32 noundef [[I2:%.*]]) #[[ATTR0]] {
// CHECK32-C: entry:
//
// CHECK64-C-LABEL: define dso_local signext i32 @test_s12
// CHECK64-C-SAME: (i32 noundef signext [[I1:%.*]], i32 noundef signext [[I2:%.*]]) #[[ATTR0]] {
// CHECK64-C: entry:
//
// CHECK32-CXX-LABEL: define dso_local noundef i32 @_Z8test_s12i3s12i
// CHECK32-CXX-SAME: (i32 noundef [[I1:%.*]], i32 noundef [[I2:%.*]]) #[[ATTR0]] {
// CHECK32-CXX: entry:
//
// CHECK64-CXX-LABEL: define dso_local noundef signext i32 @_Z8test_s12i3s12i
// CHECK64-CXX-SAME: (i32 noundef signext [[I1:%.*]], i32 noundef signext [[I2:%.*]]) #[[ATTR0]] {
// CHECK64-CXX: entry:
//
int test_s12(int32_t i1, struct s12 a, int32_t i2) {
return i2;
}

//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
// CHECK32-C: {{.*}}
// CHECK64-C: {{.*}}
Loading