forked from OSchip/llvm-project
ABI/x86-32 & x86-64: Alignment on 'byval' must be set when when the alignment
exceeds the minimum ABI alignment. llvm-svn: 102019
This commit is contained in:
parent
f5dbc072a6
commit
53fac692fa
|
@ -292,9 +292,6 @@ class X86_32ABIInfo : public ABIInfo {
|
|||
|
||||
static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context);
|
||||
|
||||
static unsigned getIndirectArgumentAlignment(QualType Ty,
|
||||
ASTContext &Context);
|
||||
|
||||
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
|
||||
/// such that the argument will be passed in memory.
|
||||
ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context,
|
||||
|
@ -496,21 +493,19 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
|
|||
}
|
||||
}
|
||||
|
||||
unsigned X86_32ABIInfo::getIndirectArgumentAlignment(QualType Ty,
|
||||
ASTContext &Context) {
|
||||
unsigned Align = Context.getTypeAlign(Ty);
|
||||
if (Align < 128) return 0;
|
||||
if (const RecordType* RT = Ty->getAs<RecordType>())
|
||||
if (typeContainsSSEVector(RT->getDecl(), Context))
|
||||
return 16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty,
|
||||
ASTContext &Context,
|
||||
bool ByVal) const {
|
||||
return ABIArgInfo::getIndirect(getIndirectArgumentAlignment(Ty, Context),
|
||||
ByVal);
|
||||
if (!ByVal)
|
||||
return ABIArgInfo::getIndirect(0, false);
|
||||
|
||||
// Compute the byval alignment. We trust the back-end to honor the
|
||||
// minimum ABI alignment for byval, to make cleaner IR.
|
||||
const unsigned MinABIAlign = 4;
|
||||
unsigned Align = Context.getTypeAlign(Ty) / 8;
|
||||
if (Align > MinABIAlign)
|
||||
return ABIArgInfo::getIndirect(Align);
|
||||
return ABIArgInfo::getIndirect(0);
|
||||
}
|
||||
|
||||
ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
|
||||
|
@ -696,6 +691,10 @@ class X86_64ABIInfo : public ABIInfo {
|
|||
const llvm::Type *CoerceTo,
|
||||
ASTContext &Context) const;
|
||||
|
||||
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
|
||||
/// such that the argument will be returned in memory.
|
||||
ABIArgInfo getIndirectReturnResult(QualType Ty, ASTContext &Context) const;
|
||||
|
||||
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
|
||||
/// such that the argument will be passed in memory.
|
||||
ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context) const;
|
||||
|
@ -1071,6 +1070,22 @@ ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty,
|
|||
return ABIArgInfo::getCoerce(CoerceTo);
|
||||
}
|
||||
|
||||
ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty,
|
||||
ASTContext &Context) const {
|
||||
// If this is a scalar LLVM value then assume LLVM will pass it in the right
|
||||
// place naturally.
|
||||
if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
|
||||
// Treat an enum type as its underlying type.
|
||||
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
||||
Ty = EnumTy->getDecl()->getIntegerType();
|
||||
|
||||
return (Ty->isPromotableIntegerType() ?
|
||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||
}
|
||||
|
||||
return ABIArgInfo::getIndirect(0);
|
||||
}
|
||||
|
||||
ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
|
||||
ASTContext &Context) const {
|
||||
// If this is a scalar LLVM value then assume LLVM will pass it in the right
|
||||
|
@ -1084,10 +1099,16 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
|
|||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||
}
|
||||
|
||||
bool ByVal = !isRecordWithNonTrivialDestructorOrCopyConstructor(Ty);
|
||||
if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
|
||||
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
|
||||
|
||||
// FIXME: Set alignment correctly.
|
||||
return ABIArgInfo::getIndirect(0, ByVal);
|
||||
// Compute the byval alignment. We trust the back-end to honor the
|
||||
// minimum ABI alignment for byval, to make cleaner IR.
|
||||
const unsigned MinABIAlign = 8;
|
||||
unsigned Align = Context.getTypeAlign(Ty) / 8;
|
||||
if (Align > MinABIAlign)
|
||||
return ABIArgInfo::getIndirect(Align);
|
||||
return ABIArgInfo::getIndirect(0);
|
||||
}
|
||||
|
||||
ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
|
||||
|
@ -1115,7 +1136,7 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
|
|||
// AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via
|
||||
// hidden argument.
|
||||
case Memory:
|
||||
return getIndirectResult(RetTy, Context);
|
||||
return getIndirectReturnResult(RetTy, Context);
|
||||
|
||||
// AMD64-ABI 3.2.3p4: Rule 3. If the class is INTEGER, the next
|
||||
// available register of the sequence %rax, %rdx is used.
|
||||
|
|
|
@ -202,3 +202,15 @@ void f50(struct s50 a0) { }
|
|||
struct s51 { vvbp f0; int f1; };
|
||||
void f51(struct s51 a0) { }
|
||||
|
||||
// CHECK: define void @f52(%struct.s52* byval align 16 %x)
|
||||
struct s52 {
|
||||
long double a;
|
||||
};
|
||||
void f52(struct s52 x) {}
|
||||
|
||||
// CHECK: define void @f53(%struct.s53* byval align 32 %x)
|
||||
struct __attribute__((aligned(32))) s53 {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
void f53(struct s53 x) {}
|
||||
|
|
|
@ -60,7 +60,7 @@ struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} }
|
|||
struct s10 { int a; int b; int : 0; };
|
||||
void f10(struct s10 a0) {}
|
||||
|
||||
// CHECK: define void @f11(%union.anon* sret %agg.result)
|
||||
// CHECK: define void @f11(%struct.s19* sret %agg.result)
|
||||
union { long double a; float b; } f11() { while (1) {} }
|
||||
|
||||
// CHECK: define i64 @f12_0()
|
||||
|
@ -99,3 +99,17 @@ void f17(float a, float b, float c, float d, float e, float f, float g, float h,
|
|||
struct f18_s0 { int f0; };
|
||||
void f18(int a, struct f18_s0 f18_arg1) { while (1) {} }
|
||||
|
||||
// Check byval alignment.
|
||||
|
||||
// CHECK: define void @f19(%struct.s19* byval align 16 %x)
|
||||
struct s19 {
|
||||
long double a;
|
||||
};
|
||||
void f19(struct s19 x) {}
|
||||
|
||||
// CHECK: define void @f20(%struct.s20* byval align 32 %x)
|
||||
struct __attribute__((aligned(32))) s20 {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
void f20(struct s20 x) {}
|
||||
|
|
Loading…
Reference in New Issue