aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLongsheng Mou <moulongsheng@huawei.com>2024-04-10 10:57:35 +0800
committerGitHub <noreply@github.com>2024-04-09 19:57:35 -0700
commit000f2b51633d181bf4a5919fc38cf964a83f2091 (patch)
treecd1c68c72daf48cd783f92a80acc5b4e3152cd92
parent71097e927141e278dd92e847e67f636526510a31 (diff)
downloadllvm-000f2b51633d181bf4a5919fc38cf964a83f2091.zip
llvm-000f2b51633d181bf4a5919fc38cf964a83f2091.tar.gz
llvm-000f2b51633d181bf4a5919fc38cf964a83f2091.tar.bz2
[X86_64] fix arg pass error in struct. (#86902)
``` typedef long long t67 __attribute__((aligned (4))); struct s67 { int a; t67 b; }; void f67(struct s67 x) { } ``` When classify: a: Lo = Integer, Hi = NoClass b: Lo = Integer, Hi = NoClass struct S: Lo = Integer, Hi = NoClass ``` define dso_local void @f67(i64 %x.coerce) { ``` 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. fix https://github.com/llvm/llvm-project/issues/85387.
-rw-r--r--clang/lib/CodeGen/Targets/X86.cpp5
-rw-r--r--clang/test/CodeGen/X86/x86_64-arguments.c18
2 files changed, 22 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index c831777..f04db56 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -2106,8 +2106,11 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
postMerge(Size, Lo, Hi);
return;
}
+
+ bool IsInMemory =
+ Offset % getContext().getTypeAlign(i->getType().getCanonicalType());
// Note, skip this test for bit-fields, see below.
- if (!BitField && Offset % getContext().getTypeAlign(i->getType())) {
+ if (!BitField && IsInMemory) {
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 cf5636c..82845f0 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: