forked from OSchip/llvm-project
[ARM64-BE] Correctly deal with single element HFAs in varargs.
Just because the first "if" didn't fire, doesn't mean we can not have an HFA in the "else" clause. llvm-svn: 208216
This commit is contained in:
parent
6d58e0726d
commit
467be60748
|
@ -3550,7 +3550,8 @@ static llvm::Value *EmitAArch64VAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
|
|
||||||
const Type *Base = 0;
|
const Type *Base = 0;
|
||||||
uint64_t NumMembers;
|
uint64_t NumMembers;
|
||||||
if (isHomogeneousAggregate(Ty, Base, Ctx, &NumMembers) && NumMembers > 1) {
|
bool IsHFA = isHomogeneousAggregate(Ty, Base, Ctx, &NumMembers);
|
||||||
|
if (IsHFA && NumMembers > 1) {
|
||||||
// Homogeneous aggregates passed in registers will have their elements split
|
// Homogeneous aggregates passed in registers will have their elements split
|
||||||
// and stored 16-bytes apart regardless of size (they're notionally in qN,
|
// and stored 16-bytes apart regardless of size (they're notionally in qN,
|
||||||
// qN+1, ...). We reload and store into a temporary local variable
|
// qN+1, ...). We reload and store into a temporary local variable
|
||||||
|
@ -3579,7 +3580,8 @@ static llvm::Value *EmitAArch64VAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
} else {
|
} else {
|
||||||
// Otherwise the object is contiguous in memory
|
// Otherwise the object is contiguous in memory
|
||||||
unsigned BeAlign = reg_top_index == 2 ? 16 : 8;
|
unsigned BeAlign = reg_top_index == 2 ? 16 : 8;
|
||||||
if (CGF.CGM.getDataLayout().isBigEndian() && !isAggregateTypeForABI(Ty) &&
|
if (CGF.CGM.getDataLayout().isBigEndian() &&
|
||||||
|
(IsHFA || !isAggregateTypeForABI(Ty)) &&
|
||||||
Ctx.getTypeSize(Ty) < (BeAlign * 8)) {
|
Ctx.getTypeSize(Ty) < (BeAlign * 8)) {
|
||||||
int Offset = BeAlign - Ctx.getTypeSize(Ty) / 8;
|
int Offset = BeAlign - Ctx.getTypeSize(Ty) / 8;
|
||||||
BaseAddr = CGF.Builder.CreatePtrToInt(BaseAddr, CGF.Int64Ty);
|
BaseAddr = CGF.Builder.CreatePtrToInt(BaseAddr, CGF.Int64Ty);
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
// RUN: %clang_cc1 -triple arm64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - %s | FileCheck %s
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
// A single member HFA must be aligned just like a non-HFA register argument.
|
||||||
|
double callee(int a, ...) {
|
||||||
|
// CHECK: %align_be = add i64 %{{.*}}, 8
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, a);
|
||||||
|
double result = va_arg(vl, struct { double a; }).a;
|
||||||
|
va_end(vl);
|
||||||
|
return result;
|
||||||
|
}
|
Loading…
Reference in New Issue