[llvm-branch-commits] [clang] release/23.x: [clang][LoongArch] Match GCC ABI handling of integer complex types (#215222) (PR #216034)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Aug 13 05:48:29 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: llvmbot
<details>
<summary>Changes</summary>
Backport 70998dbeda3a9f29b38af26e5256feeeeb20acea
Requested by: @<!-- -->heiher
---
Full diff: https://github.com/llvm/llvm-project/pull/216034.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/Targets/LoongArch.cpp (+6)
- (modified) clang/test/CodeGen/LoongArch/abi-lp64d.c (+28)
``````````diff
diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp
index 878723d67f081..ca080b22fcabd 100644
--- a/clang/lib/CodeGen/Targets/LoongArch.cpp
+++ b/clang/lib/CodeGen/Targets/LoongArch.cpp
@@ -135,6 +135,12 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
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 GARs instead.
+ if (!EltTy->isRealFloatingType())
+ return false;
if (getContext().getTypeSize(EltTy) > FRLen)
return false;
Field1Ty = CGT.ConvertType(EltTy);
diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d.c b/clang/test/CodeGen/LoongArch/abi-lp64d.c
index 9f64cfd662e5f..6bee262f30fa2 100644
--- a/clang/test/CodeGen/LoongArch/abi-lp64d.c
+++ b/clang/test/CodeGen/LoongArch/abi-lp64d.c
@@ -501,6 +501,34 @@ struct doublecomplex_s f_doublecomplex_s(struct doublecomplex_s x) {
return x;
}
+/// A complex integer, or a structure containing just one complex integer
+/// (a GNU extension), is not eligible to be passed in floating-point
+/// registers; it is passed as though it were an aggregate of the same
+/// size, i.e. packed into a single GAR when its size does not exceed
+/// GRLen.
+
+// CHECK-LABEL: define{{.*}} i64 @f_ucharcomplex(i64 %x.coerce)
+unsigned char __complex__ f_ucharcomplex(unsigned char __complex__ x) { return x; }
+
+// CHECK-LABEL: define{{.*}} i64 @f_ushortcomplex(i64 %x.coerce)
+unsigned short __complex__ f_ushortcomplex(unsigned short __complex__ x) { return x; }
+
+struct ucharcomplex_s {
+ unsigned char __complex__ c;
+};
+// CHECK-LABEL: define{{.*}} i64 @f_ucharcomplex_s(i64 %x.coerce)
+struct ucharcomplex_s f_ucharcomplex_s(struct ucharcomplex_s x) {
+ return x;
+}
+
+struct ushortcomplex_s {
+ unsigned short __complex__ c;
+};
+// CHECK-LABEL: define{{.*}} i64 @f_ushortcomplex_s(i64 %x.coerce)
+struct ushortcomplex_s f_ushortcomplex_s(struct ushortcomplex_s x) {
+ return x;
+}
+
/// Part 5: Variadic arguments.
/// Variadic arguments are passed in GARs in the same manner as named arguments.
``````````
</details>
https://github.com/llvm/llvm-project/pull/216034
More information about the llvm-branch-commits
mailing list