diff options
author | Longsheng Mou <moulongsheng@huawei.com> | 2024-04-10 10:57:35 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-09 19:57:35 -0700 |
commit | 000f2b51633d181bf4a5919fc38cf964a83f2091 (patch) | |
tree | cd1c68c72daf48cd783f92a80acc5b4e3152cd92 | |
parent | 71097e927141e278dd92e847e67f636526510a31 (diff) | |
download | llvm-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.cpp | 5 | ||||
-rw-r--r-- | clang/test/CodeGen/X86/x86_64-arguments.c | 18 |
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: |