[clang] [X86_64] fix arg pass error in struct. (PR #85394)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 15 06:07:41 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-clang
Author: Longsheng Mou (CoTinker)
<details>
<summary>Changes</summary>
typedef long long Alignll __attribute__((align (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. fix #<!-- -->85387.
---
Full diff: https://github.com/llvm/llvm-project/pull/85394.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/Targets/X86.cpp (+5)
- (modified) clang/test/CodeGen/X86/x86_64-arguments.c (+18)
``````````diff
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 2291c991fb1107..1a02d94a8eb530 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -1787,6 +1787,7 @@ 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 +1800,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..c8a215989cf9fc 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__((align (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__((align (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:
``````````
</details>
https://github.com/llvm/llvm-project/pull/85394
More information about the cfe-commits
mailing list