https://github.com/bylaws updated https://github.com/llvm/llvm-project/pull/154578
>From 2753633577ce4b9f17d1332448f425307354734e Mon Sep 17 00:00:00 2001 From: Billy Laws <blaw...@gmail.com> Date: Thu, 24 Jul 2025 16:04:25 +0100 Subject: [PATCH] [AArch64][Clang] Limit variadic onstack args to 8 bytes on Arm64EC. --- clang/lib/CodeGen/Targets/AArch64.cpp | 14 ++++++++++---- clang/test/CodeGen/AArch64/varargs-ms.c | 18 +++++++++++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 289f8a9dcf211..6b26c67bbb171 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -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); @@ -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, diff --git a/clang/test/CodeGen/AArch64/varargs-ms.c b/clang/test/CodeGen/AArch64/varargs-ms.c index a9393d4c5ab6a..d311a4b8c952c 100644 --- a/clang/test/CodeGen/AArch64/varargs-ms.c +++ b/clang/test/CodeGen/AArch64/varargs-ms.c @@ -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> @@ -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]] +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits