diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/CodeGen/CallingConvLower.h | 9 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 1 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/aligned-variadic.ll | 30 |
3 files changed, 38 insertions, 2 deletions
diff --git a/llvm/include/llvm/CodeGen/CallingConvLower.h b/llvm/include/llvm/CodeGen/CallingConvLower.h index 866b3c8c6bc..ffedd2e1410 100644 --- a/llvm/include/llvm/CodeGen/CallingConvLower.h +++ b/llvm/include/llvm/CodeGen/CallingConvLower.h @@ -371,11 +371,16 @@ public: return Reg; } + /// AlignStack - Align the top of the stakc to the specified alignment. + void AlignStack(unsigned Align) { + assert(Align && ((Align - 1) & Align) == 0); // Align is power of 2. + StackOffset = ((StackOffset + Align - 1) & ~(Align - 1)); + } + /// AllocateStack - Allocate a chunk of stack space with the specified size /// and alignment. unsigned AllocateStack(unsigned Size, unsigned Align) { - assert(Align && ((Align-1) & Align) == 0); // Align is power of 2. - StackOffset = ((StackOffset + Align-1) & ~(Align-1)); + AlignStack(Align); unsigned Result = StackOffset; StackOffset += Size; MF.getFrameInfo()->ensureMaxAlignment(Align); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 9cb9e6abbef..a10023df8a0 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2300,6 +2300,7 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain, CCInfo.AllocateStack(32, 8); CCInfo.AnalyzeFormalArguments(Ins, CC_X86); + CCInfo.AlignStack(Is64Bit ? 8 : 4); unsigned LastVal = ~0U; SDValue ArgValue; diff --git a/llvm/test/CodeGen/X86/aligned-variadic.ll b/llvm/test/CodeGen/X86/aligned-variadic.ll new file mode 100644 index 00000000000..68000e36bc6 --- /dev/null +++ b/llvm/test/CodeGen/X86/aligned-variadic.ll @@ -0,0 +1,30 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s -check-prefix=X64 +; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32 + +%struct.Baz = type { [17 x i8] } +%struct.__va_list_tag = type { i32, i32, i8*, i8* } + +; Function Attrs: nounwind uwtable +define void @bar(%struct.Baz* byval nocapture readnone align 8 %x, ...) { +entry: + %va = alloca [1 x %struct.__va_list_tag], align 16 + %arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag]* %va, i64 0, i64 0 + %arraydecay1 = bitcast [1 x %struct.__va_list_tag]* %va to i8* + call void @llvm.va_start(i8* %arraydecay1) + %overflow_arg_area_p = getelementptr inbounds [1 x %struct.__va_list_tag]* %va, i64 0, i64 0, i32 2 + %overflow_arg_area = load i8** %overflow_arg_area_p, align 8 + %overflow_arg_area.next = getelementptr i8* %overflow_arg_area, i64 24 + store i8* %overflow_arg_area.next, i8** %overflow_arg_area_p, align 8 +; X32: leal 68(%esp), [[REG:%.*]] +; X32: movl [[REG]], 16(%esp) +; X64: leaq 232(%rsp), [[REG:%.*]] +; X64: movq [[REG]], 184(%rsp) +; X64: leaq 176(%rsp), %rdi + call void @qux(%struct.__va_list_tag* %arraydecay) + ret void +} + +; Function Attrs: nounwind +declare void @llvm.va_start(i8*) + +declare void @qux(%struct.__va_list_tag*) |

