[clang] 4253fdc - [LoongArch] Fix ABI mismatch with g++ when handling empty unions (#71025)

via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 3 19:04:40 PDT 2023


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;
 }


        


More information about the cfe-commits mailing list