summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/CodeGen/CallingConvLower.h9
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp1
-rw-r--r--llvm/test/CodeGen/X86/aligned-variadic.ll30
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*)
OpenPOWER on IntegriCloud