llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen 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 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
