Skip to content

Commit a16c9e1

Browse files
[fixup] Fix passing of named PST arguments to variadic functions
... even though the AArch64 backend does not support it (currently).
1 parent 479ac0e commit a16c9e1

File tree

2 files changed

+29
-19
lines changed

2 files changed

+29
-19
lines changed

clang/lib/CodeGen/Targets/AArch64.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ class AArch64ABIInfo : public ABIInfo {
3434
AArch64ABIKind getABIKind() const { return Kind; }
3535
bool isDarwinPCS() const { return Kind == AArch64ABIKind::DarwinPCS; }
3636

37-
ABIArgInfo classifyReturnType(QualType RetTy, bool IsVariadic) const;
38-
ABIArgInfo classifyArgumentType(QualType RetTy, bool IsVariadic,
39-
unsigned CallingConvention, unsigned &NSRN,
40-
unsigned &NPRN) const;
37+
ABIArgInfo classifyReturnType(QualType RetTy, bool IsVariadicFn) const;
38+
ABIArgInfo classifyArgumentType(QualType RetTy, bool IsVariadicFn,
39+
bool IsNamedArg, unsigned CallingConvention,
40+
unsigned &NSRN, unsigned &NPRN) const;
4141
llvm::Type *convertFixedToScalableVectorType(const VectorType *VT) const;
4242
ABIArgInfo coerceIllegalVector(QualType Ty, unsigned &NSRN,
4343
unsigned &NPRN) const;
@@ -65,8 +65,9 @@ class AArch64ABIInfo : public ABIInfo {
6565

6666
unsigned NSRN = 0, NPRN = 0;
6767
for (auto &it : FI.arguments())
68-
it.info = classifyArgumentType(it.type, FI.isVariadic(),
69-
FI.getCallingConvention(), NSRN, NPRN);
68+
it.info =
69+
classifyArgumentType(it.type, FI.isVariadic(), /* IsNamedArg */ true,
70+
FI.getCallingConvention(), NSRN, NPRN);
7071
}
7172

7273
RValue EmitDarwinVAArg(Address VAListAddr, QualType Ty, CodeGenFunction &CGF,
@@ -343,7 +344,8 @@ ABIArgInfo AArch64ABIInfo::coerceAndExpandPureScalableAggregate(
343344
return ABIArgInfo::getCoerceAndExpand(CoerceToType, UnpaddedCoerceToType);
344345
}
345346

346-
ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadic,
347+
ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn,
348+
bool IsNamedArg,
347349
unsigned CallingConvention,
348350
unsigned &NSRN,
349351
unsigned &NPRN) const {
@@ -408,7 +410,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadic,
408410
uint64_t Members = 0;
409411
bool IsWin64 = Kind == AArch64ABIKind::Win64 ||
410412
CallingConvention == llvm::CallingConv::Win64;
411-
bool IsWinVariadic = IsWin64 && IsVariadic;
413+
bool IsWinVariadic = IsWin64 && IsVariadicFn;
412414
// In variadic functions on Windows, all composite types are treated alike,
413415
// no special handling of HFAs/HVAs.
414416
if (!IsWinVariadic && isHomogeneousAggregate(Ty, Base, Members)) {
@@ -429,7 +431,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadic,
429431

430432
// In AAPCS named arguments of a Pure Scalable Type are passed expanded in
431433
// registers, or indirectly if there are not enough registers.
432-
if (Kind == AArch64ABIKind::AAPCS && !IsVariadic) {
434+
if (Kind == AArch64ABIKind::AAPCS && IsNamedArg) {
433435
unsigned NVec = 0, NPred = 0;
434436
SmallVector<llvm::Type *> UnpaddedCoerceToSeq;
435437
if (passAsPureScalableType(Ty, NVec, NPred, UnpaddedCoerceToSeq) &&
@@ -468,7 +470,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadic,
468470
}
469471

470472
ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
471-
bool IsVariadic) const {
473+
bool IsVariadicFn) const {
472474
if (RetTy->isVoidType())
473475
return ABIArgInfo::getIgnore();
474476

@@ -506,7 +508,7 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
506508
uint64_t Members = 0;
507509
if (isHomogeneousAggregate(RetTy, Base, Members) &&
508510
!(getTarget().getTriple().getArch() == llvm::Triple::aarch64_32 &&
509-
IsVariadic))
511+
IsVariadicFn))
510512
// Homogeneous Floating-point Aggregates (HFAs) are returned directly.
511513
return ABIArgInfo::getDirect();
512514

@@ -796,7 +798,7 @@ RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
796798
// `classifyArgumentType` here.
797799
unsigned NSRN = 0, NPRN = 0;
798800
ABIArgInfo AI =
799-
classifyArgumentType(Ty, /*IsVariadic=*/true,
801+
classifyArgumentType(Ty, /*IsVariadicFn=*/true, /* IsNamedArg */ false,
800802
CGF.CurFnInfo->getCallingConvention(), NSRN, NPRN);
801803
// Empty records are ignored for parameter passing purposes.
802804
if (AI.isIgnore())

clang/test/CodeGen/aarch64-pure-scalable-args.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,14 +288,22 @@ BigPST test_return_big_pst(BigPST *p) {
288288
// CHECK-AAPCS: define dso_local void @test_return_big_pst(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.BigPST) align 16 %agg.result, ptr nocapture noundef readonly %p)
289289
// CHECK-DARWIN: define void @test_return_big_pst(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.BigPST) align 16 %agg.result, ptr nocapture noundef readonly %p)
290290

291-
// Variadic arguments are unnamed, PST passed indirectly
292-
// 0 -> x0
293-
// *p -> memory, address -> x1
294-
void test_pass_variadic(PST *p) {
295-
void pass_variadic_callee(int n, ...);
296-
pass_variadic_callee(0, *p);
291+
// Variadic arguments are unnamed, PST passed indirectly.
292+
// (Passing SVE types to bvariadic fucntion currently unsupported by
293+
// the AArch64 backend)
294+
// p->a -> p0
295+
// p->x -> q0
296+
// p->y[0] -> q1
297+
// p->y[1] -> q2
298+
// p->z -> q3
299+
// p->b -> p1
300+
// *q -> memory, address -> x1
301+
void test_pass_variadic(PST *p, PST *q) {
302+
void pass_variadic_callee(PST, ...);
303+
pass_variadic_callee(*p, *q);
297304
}
298-
// CHECK: declare void @pass_variadic_callee(i32 noundef, ...)
305+
// CHECK-AAPCS: declare void @pass_variadic_callee(<vscale x 16 x i1>, <vscale x 2 x double>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 16 x i8>, <vscale x 16 x i1>, ...)
306+
// CHECK-DARWIN: declare void @pass_variadic_callee(ptr noundef, ...)
299307

300308

301309
// Test handling of a PST argument when passed in registers, from the callee side.

0 commit comments

Comments
 (0)