Skip to content

Commit 2753633

Browse files
committed
[AArch64][Clang] Limit variadic onstack args to 8 bytes on Arm64EC.
1 parent d69ccde commit 2753633

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

clang/lib/CodeGen/Targets/AArch64.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,11 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn,
474474
Ty, IsNamedArg, NVec, NPred, UnpaddedCoerceToSeq, NSRN, NPRN);
475475
}
476476

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

1155-
// Composites larger than 16 bytes are passed by reference.
1156-
if (isAggregateTypeForABI(Ty) && getContext().getTypeSize(Ty) > 128)
1158+
// Composites larger than 16 bytes (8 bytes on Arm64EC) are passed by
1159+
// reference.
1160+
uint64_t MaxDirectSize =
1161+
getTarget().getTriple().isWindowsArm64EC() ? 64 : 128;
1162+
if (isAggregateTypeForABI(Ty) && getContext().getTypeSize(Ty) > MaxDirectSize)
11571163
IsIndirect = true;
11581164

11591165
return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect,

clang/test/CodeGen/AArch64/varargs-ms.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %clang_cc1 -triple arm64-windows-msvc -emit-llvm -o - %s | FileCheck %s
1+
// RUN: %clang_cc1 -triple arm64-windows-msvc -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-A64
2+
// RUN: %clang_cc1 -triple arm64ec-windows-msvc -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-EC
23

34
#include <stdarg.h>
45

@@ -8,3 +9,18 @@ int simple_int(va_list ap) {
89
// CHECK: [[RESULT:%[a-z_0-9]+]] = load i32, ptr %argp.cur
910
// CHECK: ret i32 [[RESULT]]
1011
}
12+
13+
struct bigstruct {
14+
int item[4];
15+
};
16+
struct bigstruct big_struct(va_list ap) {
17+
// CHECK-LABEL: define dso_local [2 x i64] @big_struct
18+
return va_arg(ap, struct bigstruct);
19+
// CHECK-EC: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 8
20+
// CHECK-EC: [[PTR:%[0-9]+]] = load ptr, ptr %argp.cur, align 8
21+
// CHECK-EC: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %retval, ptr align 4 [[PTR]], i64 16, i1 false)
22+
// CHECK-A64: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 16
23+
// CHECK-A64: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %retval, ptr align 8 %argp.cur, i64 16, i1 false)
24+
// CHECK: [[RESULT:%[0-9]+]] = load [2 x i64], ptr %coerce.dive
25+
// CHECK: ret [2 x i64] [[RESULT]]
26+
}

0 commit comments

Comments
 (0)