-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[X86_32][C++] fix 0 sized struct case in vaarg. #86388
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Longsheng Mou (CoTinker) Changesstruct SuperEmpty { struct{ int a[0];} b;}; llvm-project/clang/lib/CodeGen/ABIInfoImpl.cpp Lines 202 to 216 in 691b97c
This case use indirect before and Full diff: https://github.com/llvm/llvm-project/pull/86388.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 1ec0f159ebcb8a..8e6e7c17452048 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -805,6 +805,9 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State,
if (!IsWin32StructABI && isEmptyRecord(getContext(), Ty, true))
return ABIArgInfo::getIgnore();
+ if (TI.Width == 0 && getContext().getLangOpts().CPlusPlus)
+ return ABIArgInfo::getDirect();
+
llvm::LLVMContext &LLVMContext = getVMContext();
llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext);
bool NeedsPadding = false;
diff --git a/clang/test/CodeGenCXX/regparm.cpp b/clang/test/CodeGenCXX/regparm.cpp
index 1fd471c2d0727b..559702a84c99e1 100644
--- a/clang/test/CodeGenCXX/regparm.cpp
+++ b/clang/test/CodeGenCXX/regparm.cpp
@@ -32,7 +32,7 @@ struct S3 {
} a;
};
__attribute((regparm(2))) void foo4(S3 a, int b);
-// CHECK: declare void @_Z4foo42S3i(ptr noundef byval(%struct.S3) align 4, i32 inreg noundef)
+// CHECK: declare void @_Z4foo42S3i(%struct.anon, i32 inreg noundef)
void bar3(S3 a, int b) {
foo4(a, b);
}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
✅ With the latest revision this PR passed the Python code formatter. |
struct SuperEmpty { struct{ int a[0];} b;}; Such 0 sized structs in c++ mode can not be ignored in i386 for that c++ fields are never empty.But when EmitVAArg, its size is 0, so that va_list not increase.Maybe we can use direct in this case.
(This overlaps with #86075, so I'm going to hold off on reviewing this for now.) |
Or maybe we can just ignore this kind of arguments to fix #86385, like X86_64 did. |
If you implement #86075 like I suggested, the inconsistency here also goes away, I think: if va_arg queries classifyArgumentType, you get the same result as argument lowering, so clang becomes self-consistent. (Whether that's gcc-compatible is a different question...) |
Inconsistency here is inevitable. llvm-project/clang/lib/CodeGen/Targets/X86.cpp Lines 1070 to 1091 in 5949899
And Indirect is false, so that DirectSize = DirectAlign = 0, which leads to error. llvm-project/clang/lib/CodeGen/ABIInfoImpl.cpp Lines 205 to 230 in 5949899
How do I fix this? Change the classifyArgumentType or the EmiVAArg? @efriedma-quic |
struct SuperEmpty { struct{ int a[0];} b;};
Such 0 sized structs in c++ mode can not be ignored in i386 for that c++ fields are never empty.But when EmitVAArg, its size is 0, so that va_list not increase.Maybe we can use direct in this case.
Or we can just Ignore this kind of arguments, like X86_64 did. Fix #86385.