[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker closed https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker updated https://github.com/llvm/llvm-project/pull/85394 >From ad805988f682030cd3ed6ff6b063488ed6f5707c Mon Sep 17 00:00:00 2001 From: Longsheng Mou Date: Fri, 15 Mar 2024 20:50:54 +0800 Subject: [PATCH] [X86_64] fix arg pass error in struct. In some struct like s67, 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, using memory like gcc. --- 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 , postMerge(Size, Lo, Hi); return; } + + bool InMemory = Offset % getContext().getTypeAlign(i->getType()) || + (i->getType()->getAs() && + 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: ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker updated https://github.com/llvm/llvm-project/pull/85394 >From 07e8b31dbe6eaa1a385d52160bf1913c9fa1c17e Mon Sep 17 00:00:00 2001 From: Longsheng Mou Date: Fri, 15 Mar 2024 20:50:54 +0800 Subject: [PATCH] [X86_64] fix arg pass error in struct. In some struct like s67, 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 , postMerge(Size, Lo, Hi); return; } + + bool InMemory = Offset % getContext().getTypeAlign(i->getType()) || + (i->getType()->getAs() && + 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: ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
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 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 , postMerge(Size, Lo, Hi); return; } + + bool InMemory = Offset % getContext().getTypeAlign(i->getType()) || + (i->getType()->getAs() && + 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: ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
efriedma-quic wrote: gcc uses memory, and the ABI standard doesn't explicitly contradict it, so let's just go with that. https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
CoTinker wrote: Which is more appropriate to pass this structure through, memory or register? https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
CoTinker wrote: Thanks, I'll modify it according to this. https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
efriedma-quic wrote: I think the logic the code is using is that t67 is actually properly aligned: it's a type with size 8 and alignment 4, so everything is fine. If that's not right, we should tweak the relevant logic (around line 2104). Specifically checking whether a type crosses an 8-byte boundary seems wrong; the only relevant text I can find in the standard is just "if the size of an object is larger than eight eightbytes, or it contains unaligned fields, it has class MEMORY." https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker updated https://github.com/llvm/llvm-project/pull/85394 >From d344d20883a73ef1d273a4b74eb1b5df2893041e Mon Sep 17 00:00:00 2001 From: Longsheng Mou 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, 24 insertions(+) diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 2291c991fb1107..d91911ece69683 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 = Hi = NoClass; Class = OffsetBase < 64 ? Lo : Hi; + bool IsSplit = + OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; Current = Memory; if (const BuiltinType *BT = Ty->getAs()) { @@ -1798,9 +1800,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class , Lo = Integer; Hi = Integer; } else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) { + if (IsSplit) +return; Current = Integer; } else if (k == BuiltinType::Float || k == BuiltinType::Double || k == BuiltinType::Float16 || k == BuiltinType::BFloat16) { + if (IsSplit) +return; Current = SSE; } else if (k == BuiltinType::Float128) { Lo = SSE; 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: ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker updated https://github.com/llvm/llvm-project/pull/85394 >From 57760b2bfe87c689030975d5914393fd29d7d1f5 Mon Sep 17 00:00:00 2001 From: Longsheng Mou 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, 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 = Hi = NoClass; Class = OffsetBase < 64 ? Lo : Hi; + bool IsSplit = + OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; Current = Memory; if (const BuiltinType *BT = Ty->getAs()) { @@ -1799,9 +1801,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class , 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
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
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 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 = Hi = NoClass; Class = OffsetBase < 64 ? Lo : Hi; + bool IsSplit = + OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; Current = Memory; if (const BuiltinType *BT = Ty->getAs()) { @@ -1799,9 +1801,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class , 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
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker updated https://github.com/llvm/llvm-project/pull/85394 >From be6b4bdd75554b9287092ab42063a9d4e260dd9c Mon Sep 17 00:00:00 2001 From: Longsheng Mou 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 = Hi = NoClass; Class = OffsetBase < 64 ? Lo : Hi; + bool IsSplit = + OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; Current = Memory; if (const BuiltinType *BT = Ty->getAs()) { @@ -1799,9 +1801,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class , 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
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker edited https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker edited https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker updated https://github.com/llvm/llvm-project/pull/85394 >From b31780cba73ea39bf7f630a059a554914d804446 Mon Sep 17 00:00:00 2001 From: Longsheng Mou 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 = Hi = NoClass; Class = OffsetBase < 64 ? Lo : Hi; + bool IsSplit = + OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; Current = Memory; if (const BuiltinType *BT = Ty->getAs()) { @@ -1799,9 +1801,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class , 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
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker edited https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/RKSimon edited https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker updated https://github.com/llvm/llvm-project/pull/85394 >From 30d8d0490b383b8b52fee7d8ddd591f8ed5b585e Mon Sep 17 00:00:00 2001 From: Longsheng Mou Date: Fri, 15 Mar 2024 20:50:54 +0800 Subject: [PATCH] [X86_64] fix arg pass error in struct. 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. --- 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 = Hi = NoClass; Class = OffsetBase < 64 ? Lo : Hi; + bool IsSplit = + OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; Current = Memory; if (const BuiltinType *BT = Ty->getAs()) { @@ -1799,9 +1801,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class , 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: ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker edited https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker edited https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 61671e2500771dfbf502acd86e2ef70cba847a39 8efa87d7b03ebf2cf304e97c5fcebdb4211350b4 -- clang/lib/CodeGen/Targets/X86.cpp clang/test/CodeGen/X86/x86_64-arguments.c `` View the diff from clang-format here. ``diff diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 1a02d94a8e..c3e32e5ed6 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -1787,7 +1787,8 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class , Lo = Hi = NoClass; Class = OffsetBase < 64 ? Lo : Hi; - bool IsSplit = OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; + bool IsSplit = + OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; Current = Memory; if (const BuiltinType *BT = Ty->getAs()) { `` https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
llvmbot wrote: @llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-clang Author: Longsheng Mou (CoTinker) Changes 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 = Hi = NoClass; Class = OffsetBase < 64 ? Lo : Hi; + bool IsSplit = OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; Current = Memory; if (const BuiltinType *BT = Ty->getAs()) { @@ -1799,9 +1800,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class , 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: `` https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/85394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [X86_64] fix arg pass error in struct. (PR #85394)
https://github.com/CoTinker created https://github.com/llvm/llvm-project/pull/85394 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. >From 8efa87d7b03ebf2cf304e97c5fcebdb4211350b4 Mon Sep 17 00:00:00 2001 From: Longsheng Mou Date: Fri, 15 Mar 2024 20:50:54 +0800 Subject: [PATCH] [X86_64] fix arg pass error in struct. 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. --- clang/lib/CodeGen/Targets/X86.cpp | 5 + clang/test/CodeGen/X86/x86_64-arguments.c | 18 ++ 2 files changed, 23 insertions(+) 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 = Hi = NoClass; Class = OffsetBase < 64 ? Lo : Hi; + bool IsSplit = OffsetBase < 64 && (OffsetBase + getContext().getTypeSize(Ty)) > 64; Current = Memory; if (const BuiltinType *BT = Ty->getAs()) { @@ -1799,9 +1800,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class , 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: ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits