Skip to content

[X86_32] Teach X86_32 va_arg to ignore empty structs. #86075

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

Merged
merged 1 commit into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/Targets/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,12 @@ Address X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF,

auto TypeInfo = getContext().getTypeInfoInChars(Ty);

CCState State(*const_cast<CGFunctionInfo *>(CGF.CurFnInfo));
ABIArgInfo AI = classifyArgumentType(Ty, State, /*ArgIndex*/ 0);
// Empty records are ignored for parameter passing purposes.
if (AI.isIgnore())
return CGF.CreateMemTemp(Ty);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to use classifyArgumentType, like we do for the 64-bit case, instead of trying to duplicate the logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

classifyArgumentType in X86_32 need CCState parameter, but we can not get it in this scope, because the CCState is temporarily calculated in X86_32ABIInfo::computeInfo.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it doesn't work with the code as-is, please refactor to the code to make it work. Scattered checks like this are hard to maintain.

The simplest thing here would be to just construct a CCState here, I think? Or if that doesn't work for some reason, make the CCState parameter to classifyArgumentType optional.


// x86-32 changes the alignment of certain arguments on the stack.
//
// Just messing with TypeInfo like this works because we never pass
Expand Down
21 changes: 21 additions & 0 deletions clang/test/CodeGenCXX/x86_32-vaarg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -triple i386-linux-gnu -emit-llvm -o - %s | FileCheck %s

typedef struct {} empty;

// CHECK-LABEL: @_Z17empty_record_testiz(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[Z_ADDR:%.*]] = alloca i32, align 4
// CHECK-NEXT: [[LIST:%.*]] = alloca ptr, align 4
// CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_EMPTY:%.*]], align 1
// CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4
// CHECK-NEXT: store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
// CHECK-NEXT: call void @llvm.va_start.p0(ptr [[LIST]])
// CHECK-NEXT: ret void
//
empty empty_record_test(int z, ...) {
__builtin_va_list list;
__builtin_va_start(list, z);
return __builtin_va_arg(list, empty);
}