Skip to content

Conversation

@bylaws
Copy link
Contributor

@bylaws bylaws commented Aug 20, 2025

This is part of the ABI and ensures the aarch64 variadic layout matches the x64 one.

CC: @cjacek @efriedma-quic

@llvmbot llvmbot added clang Clang issues not falling into any other category backend:AArch64 clang:codegen IR generation bugs: mangling, exceptions, etc. labels Aug 20, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 20, 2025

@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-backend-aarch64

Author: Billy Laws (bylaws)

Changes

This is part of the ABI and ensures the aarch64 variadic layout matches the x64 one.

CC: @cjacek @efriedma-quic


Full diff: https://github.com/llvm/llvm-project/pull/154578.diff

2 Files Affected:

  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+6-4)
  • (modified) clang/test/CodeGen/AArch64/varargs-ms.c (+17-1)
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index 289f8a9dcf211..1e00bd76f1a79 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -474,8 +474,9 @@ 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 +1153,9 @@ 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]]
+}

@efriedma-quic
Copy link
Collaborator

Duplicate of #152411?

@github-actions
Copy link

github-actions bot commented Aug 20, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@bylaws
Copy link
Contributor Author

bylaws commented Aug 20, 2025

Missed the pr implementing this 2 weeks ago

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:AArch64 clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants