llvm.org GIT mirror llvm / 5012f1d
X86: Align the stack on word boundaries in LowerFormalArguments() The goal of the patch is to implement section 3.2.3 of the AMD64 ABI correctly. The controlling sentence is, "The size of each argument gets rounded up to eightbytes. Therefore the stack will always be eightbyte aligned." The equivalent sentence in the i386 ABI page 37 says, "At all times, the stack pointer should point to a word-aligned area." For both architectures, the stack pointer is not being rounded up to the nearest eightbyte or word between the last normal argument and the first variadic argument. Patch by Thomas Jablin! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216119 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 6 years ago
3 changed file(s) with 38 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
370370 return Reg;
371371 }
372372
373 /// AlignStack - Align the top of the stakc to the specified alignment.
374 void AlignStack(unsigned Align) {
375 assert(Align && ((Align - 1) & Align) == 0); // Align is power of 2.
376 StackOffset = ((StackOffset + Align - 1) & ~(Align - 1));
377 }
378
373379 /// AllocateStack - Allocate a chunk of stack space with the specified size
374380 /// and alignment.
375381 unsigned AllocateStack(unsigned Size, unsigned Align) {
376 assert(Align && ((Align-1) & Align) == 0); // Align is power of 2.
377 StackOffset = ((StackOffset + Align-1) & ~(Align-1));
382 AlignStack(Align);
378383 unsigned Result = StackOffset;
379384 StackOffset += Size;
380385 MF.getFrameInfo()->ensureMaxAlignment(Align);
22992299 CCInfo.AllocateStack(32, 8);
23002300
23012301 CCInfo.AnalyzeFormalArguments(Ins, CC_X86);
2302 CCInfo.AlignStack(Is64Bit ? 8 : 4);
23022303
23032304 unsigned LastVal = ~0U;
23042305 SDValue ArgValue;
0 ; RUN: llc < %s -march=x86-64 | FileCheck %s -check-prefix=X64
1 ; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32
2
3 %struct.Baz = type { [17 x i8] }
4 %struct.__va_list_tag = type { i32, i32, i8*, i8* }
5
6 ; Function Attrs: nounwind uwtable
7 define void @bar(%struct.Baz* byval nocapture readnone align 8 %x, ...) {
8 entry:
9 %va = alloca [1 x %struct.__va_list_tag], align 16
10 %arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag]* %va, i64 0, i64 0
11 %arraydecay1 = bitcast [1 x %struct.__va_list_tag]* %va to i8*
12 call void @llvm.va_start(i8* %arraydecay1)
13 %overflow_arg_area_p = getelementptr inbounds [1 x %struct.__va_list_tag]* %va, i64 0, i64 0, i32 2
14 %overflow_arg_area = load i8** %overflow_arg_area_p, align 8
15 %overflow_arg_area.next = getelementptr i8* %overflow_arg_area, i64 24
16 store i8* %overflow_arg_area.next, i8** %overflow_arg_area_p, align 8
17 ; X32: leal 68(%esp), [[REG:%.*]]
18 ; X32: movl [[REG]], 16(%esp)
19 ; X64: leaq 232(%rsp), [[REG:%.*]]
20 ; X64: movq [[REG]], 184(%rsp)
21 ; X64: leaq 176(%rsp), %rdi
22 call void @qux(%struct.__va_list_tag* %arraydecay)
23 ret void
24 }
25
26 ; Function Attrs: nounwind
27 declare void @llvm.va_start(i8*)
28
29 declare void @qux(%struct.__va_list_tag*)