[llvm] r216119 - X86: Align the stack on word boundaries in LowerFormalArguments()

Duncan P. N. Exon Smith dexonsmith at apple.com
Wed Aug 20 12:40:59 PDT 2014


Author: dexonsmith
Date: Wed Aug 20 14:40:59 2014
New Revision: 216119

URL: http://llvm.org/viewvc/llvm-project?rev=216119&view=rev
Log:
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!

Added:
    llvm/trunk/test/CodeGen/X86/aligned-variadic.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/CallingConvLower.h
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Modified: llvm/trunk/include/llvm/CodeGen/CallingConvLower.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/CallingConvLower.h?rev=216119&r1=216118&r2=216119&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/CallingConvLower.h (original)
+++ llvm/trunk/include/llvm/CodeGen/CallingConvLower.h Wed Aug 20 14:40:59 2014
@@ -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);

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=216119&r1=216118&r2=216119&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Aug 20 14:40:59 2014
@@ -2300,6 +2300,7 @@ X86TargetLowering::LowerFormalArguments(
     CCInfo.AllocateStack(32, 8);
 
   CCInfo.AnalyzeFormalArguments(Ins, CC_X86);
+  CCInfo.AlignStack(Is64Bit ? 8 : 4);
 
   unsigned LastVal = ~0U;
   SDValue ArgValue;

Added: llvm/trunk/test/CodeGen/X86/aligned-variadic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/aligned-variadic.ll?rev=216119&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/aligned-variadic.ll (added)
+++ llvm/trunk/test/CodeGen/X86/aligned-variadic.ll Wed Aug 20 14:40:59 2014
@@ -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*)





More information about the llvm-commits mailing list