Skip to content
Closed
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
14 changes: 10 additions & 4 deletions clang/lib/CodeGen/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,8 +474,11 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn,
Ty, IsNamedArg, NVec, NPred, UnpaddedCoerceToSeq, NSRN, NPRN);
}

// Aggregates <= 16 bytes are passed directly in registers or on the stack.
if (Size <= 128) {
// Aggregates <= 16 bytes (8 bytes for variadic Arm64EC) are passed directly
// in registers or on the stack.
uint64_t MaxDirectSize =
(IsVariadicFn && getTarget().getTriple().isWindowsArm64EC()) ? 64 : 128;
if (Size <= MaxDirectSize) {
unsigned Alignment;
if (Kind == AArch64ABIKind::AAPCS) {
Alignment = getContext().getTypeUnadjustedAlign(Ty);
Expand Down Expand Up @@ -1152,8 +1155,11 @@ RValue AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty, AggValueSlot Slot) const {
bool IsIndirect = false;

// Composites larger than 16 bytes are passed by reference.
if (isAggregateTypeForABI(Ty) && getContext().getTypeSize(Ty) > 128)
// Composites larger than 16 bytes (8 bytes on Arm64EC) are passed by
// reference.
uint64_t MaxDirectSize =
getTarget().getTriple().isWindowsArm64EC() ? 64 : 128;
if (isAggregateTypeForABI(Ty) && getContext().getTypeSize(Ty) > MaxDirectSize)
IsIndirect = true;

return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect,
Expand Down
18 changes: 17 additions & 1 deletion clang/test/CodeGen/AArch64/varargs-ms.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple arm64-windows-msvc -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple arm64-windows-msvc -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-A64
// RUN: %clang_cc1 -triple arm64ec-windows-msvc -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-EC

#include <stdarg.h>

Expand All @@ -8,3 +9,18 @@ int simple_int(va_list ap) {
// CHECK: [[RESULT:%[a-z_0-9]+]] = load i32, ptr %argp.cur
// CHECK: ret i32 [[RESULT]]
}

struct bigstruct {
int item[4];
};
struct bigstruct big_struct(va_list ap) {
// CHECK-LABEL: define dso_local [2 x i64] @big_struct
return va_arg(ap, struct bigstruct);
// CHECK-EC: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 8
// CHECK-EC: [[PTR:%[0-9]+]] = load ptr, ptr %argp.cur, align 8
// CHECK-EC: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %retval, ptr align 4 [[PTR]], i64 16, i1 false)
// CHECK-A64: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 16
// CHECK-A64: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %retval, ptr align 8 %argp.cur, i64 16, i1 false)
// CHECK: [[RESULT:%[0-9]+]] = load [2 x i64], ptr %coerce.dive
// CHECK: ret [2 x i64] [[RESULT]]
}