Skip to content

Commit 45a5163

Browse files
committed
[AArch64] Fix va_arg for soft-float
The AArch64 back-end already avoids saving the FP registers to the va_list when the FP registers aren't present, but clang also needs to know not to load them from the FP register save area when generating code for va_arg. The layout of va_list remains the same, but the vr_top and vr_offs fields are unused. Change-Id: I5d3dee1ac4a29f189432957910662939b79d9329
1 parent 898484f commit 45a5163

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

clang/lib/CodeGen/Targets/AArch64.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ class AArch64ABIInfo : public ABIInfo {
5353
Address EmitDarwinVAArg(Address VAListAddr, QualType Ty,
5454
CodeGenFunction &CGF) const;
5555

56-
Address EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
57-
CodeGenFunction &CGF) const;
56+
Address EmitAAPCSVAArg(Address VAListAddr, QualType Ty, CodeGenFunction &CGF,
57+
AArch64ABIKind Kind) const;
5858

5959
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
6060
QualType Ty) const override {
@@ -65,7 +65,7 @@ class AArch64ABIInfo : public ABIInfo {
6565

6666
return Kind == AArch64ABIKind::Win64 ? EmitMSVAArg(CGF, VAListAddr, Ty)
6767
: isDarwinPCS() ? EmitDarwinVAArg(VAListAddr, Ty, CGF)
68-
: EmitAAPCSVAArg(VAListAddr, Ty, CGF);
68+
: EmitAAPCSVAArg(VAListAddr, Ty, CGF, Kind);
6969
}
7070

7171
Address EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
@@ -516,7 +516,8 @@ bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
516516
}
517517

518518
Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
519-
CodeGenFunction &CGF) const {
519+
CodeGenFunction &CGF,
520+
AArch64ABIKind Kind) const {
520521
ABIArgInfo AI = classifyArgumentType(Ty, /*IsVariadic=*/true,
521522
CGF.CurFnInfo->getCallingConvention());
522523
// Empty records are ignored for parameter passing purposes.
@@ -541,7 +542,8 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
541542
BaseTy = ArrTy->getElementType();
542543
NumRegs = ArrTy->getNumElements();
543544
}
544-
bool IsFPR = BaseTy->isFloatingPointTy() || BaseTy->isVectorTy();
545+
bool IsFPR = Kind == AArch64ABIKind::AAPCS &&
546+
(BaseTy->isFloatingPointTy() || BaseTy->isVectorTy());
545547

546548
// The AArch64 va_list type and handling is specified in the Procedure Call
547549
// Standard, section B.4:

clang/test/CodeGen/aarch64-soft-float-abi.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// RUN: %clang_cc1 -triple aarch64 -target-feature +fp-armv8 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,HARD
22
// RUN: %clang_cc1 -triple aarch64 -target-feature -fp-armv8 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,SOFT
33

4+
// The va_list type does not change between the ABIs
5+
// CHECK: %struct.__va_list = type { ptr, ptr, ptr, i32, i32 }
6+
47
// Floats are passed in integer registers, this will be handled by the backend.
58
// CHECK: define dso_local half @test0(half noundef %a)
69
// CHECK: define dso_local bfloat @test1(bfloat noundef %a)
@@ -30,6 +33,21 @@ struct B {
3033
// HARD: define dso_local %struct.B @test11([2 x double] alignstack(8) %a.coerce)
3134
struct B test11(struct B a) { return a; }
3235

36+
#include <stdarg.h>
37+
38+
// For variadic arguments, va_arg will always retreive
39+
// CHECK-LABEL: define dso_local double @test20(i32 noundef %a, ...)
40+
// CHECK: %vl = alloca %struct.__va_list, align 8
41+
// SOFT: %gr_offs_p = getelementptr inbounds %struct.__va_list, ptr %vl, i32 0, i32 3
42+
// SOFT: %reg_top_p = getelementptr inbounds %struct.__va_list, ptr %vl, i32 0, i32 1
43+
// HARD: %vr_offs_p = getelementptr inbounds %struct.__va_list, ptr %vl, i32 0, i32 4
44+
// HARD: %reg_top_p = getelementptr inbounds %struct.__va_list, ptr %vl, i32 0, i32 2
45+
double test20(int a, ...) {
46+
va_list vl;
47+
va_start(vl, a);
48+
return va_arg(vl, double);
49+
}
50+
3351
// Vector types are only available for targets with the correct hardware, and
3452
// their calling-convention is left undefined by the soft-float ABI, so they
3553
// aren't tested here.

0 commit comments

Comments
 (0)