r205981 - inalloca: Pad the struct *after* inserting each arg
Reid Kleckner
reid at kleckner.net
Thu Apr 10 12:09:43 PDT 2014
Author: rnk
Date: Thu Apr 10 14:09:43 2014
New Revision: 205981
URL: http://llvm.org/viewvc/llvm-project?rev=205981&view=rev
Log:
inalloca: Pad the struct *after* inserting each arg
This ensures that the overall struct size will be a multiple of 4, as
required by the ABI.
Modified:
cfe/trunk/lib/CodeGen/TargetInfo.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=205981&r1=205980&r2=205981&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Apr 10 14:09:43 2014
@@ -1013,24 +1013,22 @@ void
X86_32ABIInfo::addFieldToArgStruct(SmallVector<llvm::Type *, 6> &FrameFields,
unsigned &StackOffset,
ABIArgInfo &Info, QualType Type) const {
+ assert(StackOffset % 4U == 0 && "unaligned inalloca struct");
+ Info = ABIArgInfo::getInAlloca(FrameFields.size());
+ FrameFields.push_back(CGT.ConvertTypeForMem(Type));
+ StackOffset += getContext().getTypeSizeInChars(Type).getQuantity();
+
// Insert padding bytes to respect alignment. For x86_32, each argument is 4
// byte aligned.
- unsigned Align = 4U;
- if (Info.getKind() == ABIArgInfo::Indirect && Info.getIndirectByVal())
- Align = std::max(Align, Info.getIndirectAlign());
- if (StackOffset & (Align - 1)) {
+ if (StackOffset % 4U) {
unsigned OldOffset = StackOffset;
- StackOffset = llvm::RoundUpToAlignment(StackOffset, Align);
+ StackOffset = llvm::RoundUpToAlignment(StackOffset, 4U);
unsigned NumBytes = StackOffset - OldOffset;
assert(NumBytes);
llvm::Type *Ty = llvm::Type::getInt8Ty(getVMContext());
Ty = llvm::ArrayType::get(Ty, NumBytes);
FrameFields.push_back(Ty);
}
-
- Info = ABIArgInfo::getInAlloca(FrameFields.size());
- FrameFields.push_back(CGT.ConvertTypeForMem(Type));
- StackOffset += getContext().getTypeSizeInChars(Type).getQuantity();
}
void X86_32ABIInfo::rewriteWithInAlloca(CGFunctionInfo &FI) const {
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp?rev=205981&r1=205980&r2=205981&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp Thu Apr 10 14:09:43 2014
@@ -49,7 +49,7 @@ struct Big {
// WIN32: declare void @"{{.*take_bools_and_chars.*}}"
// WIN32: (<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor,
-// WIN32: i8, [3 x i8], i8, [3 x i8], i32, i8 }>* inalloca)
+// WIN32: i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>* inalloca)
void take_bools_and_chars(char a, char b, SmallWithDtor c, char d, bool e, int f, bool g);
void call_bools_and_chars() {
take_bools_and_chars('A', 'B', SmallWithDtor(), 'D', true, 13, false);
@@ -223,7 +223,7 @@ struct X {
};
void g(X) {
}
-// WIN32: define void @"\01?g@@YAXUX@@@Z"(<{ %struct.X }>* inalloca) {{.*}} {
+// WIN32: define void @"\01?g@@YAXUX@@@Z"(<{ %struct.X, [3 x i8] }>* inalloca) {{.*}} {
// WIN32: call x86_thiscallcc void @"\01??1X@@QAE at XZ"(%struct.X* {{.*}})
// WIN32: }
void f() {
@@ -264,6 +264,20 @@ void bar() {
}
+namespace test3 {
+
+// Check that we padded the inalloca struct to a multiple of 4.
+struct NonTrivial {
+ NonTrivial();
+ NonTrivial(const NonTrivial &o);
+ ~NonTrivial();
+ int a;
+};
+void foo(NonTrivial a, bool b) { }
+// WIN32-LABEL: define void @"\01?foo at test3@@YAXUNonTrivial at 1@_N at Z"(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>* inalloca)
+
+}
+
// We would crash here because the later definition of ForwardDeclare1 results
// in a different IR type for the value we want to store. However, the alloca's
// type will use the argument type selected by fn1.
More information about the cfe-commits
mailing list