[clang] [X86_64] fix arg pass error in struct. (PR #85394)
Longsheng Mou via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 22 01:21:43 PDT 2024
https://github.com/CoTinker updated https://github.com/llvm/llvm-project/pull/85394
>From 57cdbcab4ad13441a3f8731c4cdedc51acfbc7b1 Mon Sep 17 00:00:00 2001
From: Longsheng Mou <moulongsheng at huawei.com>
Date: Fri, 15 Mar 2024 20:50:54 +0800
Subject: [PATCH] [X86_64] fix arg pass error in struct.
typedef long long ll __attribute__((aligned (4)));
struct S {
int a;
ll 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, 23 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 2291c991fb1107..de0dfe32a54d3a 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -2100,8 +2100,12 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
postMerge(Size, Lo, Hi);
return;
}
+
+ bool InMemory = Offset % getContext().getTypeAlign(i->getType()) ||
+ (i->getType()->getAs<BuiltinType>() &&
+ Offset % getContext().getTypeSize(i->getType()));
// Note, skip this test for bit-fields, see below.
- if (!BitField && Offset % getContext().getTypeAlign(i->getType())) {
+ if (!BitField && InMemory) {
Lo = Memory;
postMerge(Size, Lo, Hi);
return;
diff --git a/clang/test/CodeGen/X86/x86_64-arguments.c b/clang/test/CodeGen/X86/x86_64-arguments.c
index cf5636cfd518b6..82845f0a2b31fd 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(ptr noundef byval(%struct.s67) align 8 %x)
+void f67(struct s67 x) {
+}
+
+typedef double t68 __attribute__((aligned (4)));
+struct s68 {
+ int a;
+ t68 b;
+};
+// CHECK-LABEL: define{{.*}} void @f68(ptr noundef byval(%struct.s68) align 8 %x)
+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:
More information about the cfe-commits
mailing list