https://github.com/CoTinker updated https://github.com/llvm/llvm-project/pull/85394
>From 1ca19591fa11a53559fdfe7e4bf6b298b7658628 Mon Sep 17 00:00:00 2001 From: Longsheng Mou <moulongsh...@huawei.com> Date: Fri, 15 Mar 2024 20:50:54 +0800 Subject: [PATCH] [X86_64] fix arg pass error in struct. typedef long long alignll __attribute__((aligned (4))); struct S { int a; alignll b; }; when classify: a: Lo = Integer, Hi = NoClass b: Lo = Integer, Hi = NoClass struct S: Lo = Integer, Hi = NoClass In this case, only one i64 register is used when the structure parameter is transferred, which is obviously incorrect.So we need to treat the split case specially. --- clang/lib/CodeGen/Targets/X86.cpp | 6 ++++++ clang/test/CodeGen/X86/x86_64-arguments.c | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 2291c991fb1107..c3e32e5ed63a97 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -1787,6 +1787,8 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, Lo = Hi = NoClass; Class &Current = OffsetBase < 64 ? Lo : Hi; + bool IsSplit = + OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; Current = Memory; if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { @@ -1799,9 +1801,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, Hi = Integer; } else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) { Current = Integer; + if (IsSplit) + Hi = Integer; } else if (k == BuiltinType::Float || k == BuiltinType::Double || k == BuiltinType::Float16 || k == BuiltinType::BFloat16) { Current = SSE; + if (IsSplit) + Hi = SSE; } else if (k == BuiltinType::Float128) { Lo = SSE; Hi = SSEUp; diff --git a/clang/test/CodeGen/X86/x86_64-arguments.c b/clang/test/CodeGen/X86/x86_64-arguments.c index cf5636cfd518b6..92b0192658a555 100644 --- a/clang/test/CodeGen/X86/x86_64-arguments.c +++ b/clang/test/CodeGen/X86/x86_64-arguments.c @@ -533,6 +533,24 @@ typedef float t66 __attribute__((__vector_size__(128), __aligned__(128))); void f66(t66 a0) { } +typedef long long t67 __attribute__((aligned (4))); +struct s67 { + int a; + t67 b; +}; +// CHECK-LABEL: define{{.*}} void @f67(i64 %x.coerce0, i32 %x.coerce1) +void f67(struct s67 x) { +} + +typedef double t68 __attribute__((aligned (4))); +struct s68 { + int a; + t68 b; +}; +// CHECK-LABEL: define{{.*}} void @f68(i64 %x.coerce0, double %x.coerce1) +void f68(struct s68 x) { +} + /// The synthesized __va_list_tag does not have file/line fields. // CHECK: = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__va_list_tag", // CHECK-NOT: file: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits