Author: Lu Weining Date: 2023-11-04T10:04:37+08:00 New Revision: 4253fdc2c462da61cc0deb74a43265665720c828
URL: https://github.com/llvm/llvm-project/commit/4253fdc2c462da61cc0deb74a43265665720c828 DIFF: https://github.com/llvm/llvm-project/commit/4253fdc2c462da61cc0deb74a43265665720c828.diff LOG: [LoongArch] Fix ABI mismatch with g++ when handling empty unions (#71025) In g++, empty unions are not ignored like empty structs when flattening structs to examine whether the structs can be passed via FARs in C++. This patch aligns clang++ with g++. Fix https://github.com/llvm/llvm-project/issues/70890. Added: Modified: clang/lib/CodeGen/Targets/LoongArch.cpp clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c Removed: ################################################################################ diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp index c4d886eb40725f8..7b2c31139b0b2a3 100644 --- a/clang/lib/CodeGen/Targets/LoongArch.cpp +++ b/clang/lib/CodeGen/Targets/LoongArch.cpp @@ -170,10 +170,11 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( // copy constructor are not eligible for the FP calling convention. if (getRecordArgABI(Ty, CGT.getCXXABI())) return false; - if (isEmptyRecord(getContext(), Ty, true, true)) - return true; const RecordDecl *RD = RTy->getDecl(); - // Unions aren't eligible unless they're empty (which is caught above). + if (isEmptyRecord(getContext(), Ty, true, true) && + (!RD->isUnion() || !isa<CXXRecordDecl>(RD))) + return true; + // Unions aren't eligible unless they're empty in C (which is caught above). if (RD->isUnion()) return false; const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c index 281b7b15841a999..2f7596f0ebdc8be 100644 --- a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c +++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -triple loongarch64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - -x c++ | \ // RUN: FileCheck --check-prefix=CHECK-CXX %s -// Fields containing empty structs or unions are ignored when flattening +// Fields containing empty structs are ignored when flattening // structs to examine whether the structs can be passed via FARs, even in C++. // But there is an exception that non-zero-length array of empty structures are // not ignored in C++. These rules are not documented in psABI <https://www.github.com/loongson/la-abi-specs> diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c index b0607425336e285..363e37efb64691e 100644 --- a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c +++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-unions.c @@ -19,8 +19,7 @@ struct s1 { }; // CHECK-C: define{{.*}} { i32, float } @test2(i32{{[^,]*}}, float{{[^,]*}}) -/// FIXME: This doesn't match g++. -// CHECK-CXX: define{{.*}} { i32, float } @_Z5test22s1(i32{{[^,]*}}, float{{[^,]*}}) +// CHECK-CXX: define{{.*}} [2 x i64] @_Z5test22s1([2 x i64]{{[^,]*}}) struct s1 test2(struct s1 a) { return a; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits