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

Reply via email to