[PATCH] Use 16 byte stack alignment for NaCl on ARM, and fix a varargs bug

Mark Seaborn mseaborn at chromium.org
Tue Feb 11 14:35:07 PST 2014


  * Simplified to use OffsetToAlignment() so that this doesn't assume a power of 2.
  * Updated comments.

Hi sdyatkovskiy,

http://llvm-reviews.chandlerc.com/D2677

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D2677?vs=6832&id=7005#toc

Files:
  lib/Target/ARM/ARMISelLowering.cpp
  lib/Target/ARM/ARMMachineFunctionInfo.h
  lib/Target/ARM/ARMSubtarget.cpp
  test/CodeGen/ARM/varargs-spill-stack-align-nacl.ll

Index: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- lib/Target/ARM/ARMISelLowering.cpp
+++ lib/Target/ARM/ARMISelLowering.cpp
@@ -2756,11 +2756,11 @@
   ArgRegsSize = NumGPRs * 4;
 
   // If parameter is split between stack and GPRs...
-  if (NumGPRs && Align == 8 &&
+  if (NumGPRs && Align > 4 &&
       (ArgRegsSize < ArgSize ||
         InRegsParamRecordIdx >= CCInfo.getInRegsParamsCount())) {
-    // Add padding for part of param recovered from GPRs, so
-    // its last byte must be at address K*8 - 1.
+    // Add padding for part of param recovered from GPRs.  For example,
+    // if Align == 8, its last byte must be at address K*8 - 1.
     // We need to do it, since remained (stack) part of parameter has
     // stack alignment, and we need to "attach" "GPRs head" without gaps
     // to it:
@@ -2770,8 +2770,7 @@
     //
     ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
     unsigned Padding =
-        ((ArgRegsSize + AFI->getArgRegsSaveSize() + Align - 1) & ~(Align-1)) -
-        (ArgRegsSize + AFI->getArgRegsSaveSize());
+        OffsetToAlignment(ArgRegsSize + AFI->getArgRegsSaveSize(), Align);
     ArgRegsSaveSize = ArgRegsSize + Padding;
   } else
     // We don't need to extend regs save size for byval parameters if they
Index: lib/Target/ARM/ARMMachineFunctionInfo.h
===================================================================
--- lib/Target/ARM/ARMMachineFunctionInfo.h
+++ lib/Target/ARM/ARMMachineFunctionInfo.h
@@ -38,7 +38,7 @@
 
   /// StByValParamsPadding - For parameter that is split between
   /// GPRs and memory; while recovering GPRs part, when
-  /// StackAlignment == 8, and GPRs-part-size mod 8 != 0,
+  /// StackAlignment > 4, and GPRs-part-size mod StackAlignment != 0,
   /// we need to insert gap before parameter start address. It allows to
   /// "attach" GPR-part to the part that was passed via stack.
   unsigned StByValParamsPadding;
Index: lib/Target/ARM/ARMSubtarget.cpp
===================================================================
--- lib/Target/ARM/ARMSubtarget.cpp
+++ lib/Target/ARM/ARMSubtarget.cpp
@@ -210,6 +210,8 @@
 
   if (isAAPCS_ABI())
     stackAlignment = 8;
+  if (isTargetNaCl())
+    stackAlignment = 16;
 
   UseMovt = hasV6T2Ops() && ArmUseMOVT;
 
Index: test/CodeGen/ARM/varargs-spill-stack-align-nacl.ll
===================================================================
--- /dev/null
+++ test/CodeGen/ARM/varargs-spill-stack-align-nacl.ll
@@ -0,0 +1,31 @@
+; RUN: llc < %s -mtriple=arm-nacl-gnueabi | FileCheck %s
+
+declare void @llvm.va_start(i8*)
+declare void @external_func(i8*)
+
+ at va_list = external global i8*
+
+; On ARM, varargs arguments are passed in r0-r3 with the rest on the
+; stack.  A varargs function must therefore spill rN-r3 just below the
+; function's initial stack pointer.
+;
+; This test checks for a bug in which a gap was left between the spill
+; area and varargs arguments on the stack when using 16 byte stack
+; alignment.
+
+define void @varargs_func(i32 %arg1, ...) {
+  call void @llvm.va_start(i8* bitcast (i8** @va_list to i8*))
+  call void @external_func(i8* bitcast (i8** @va_list to i8*))
+  ret void
+}
+; CHECK-LABEL: varargs_func:
+; Reserve space for the varargs save area.  This currently reserves
+; more than enough (16 bytes rather than the 12 bytes needed).
+; CHECK: sub sp, sp, #16
+; CHECK: push {lr}
+; Align the stack pointer to a multiple of 16.
+; CHECK: sub sp, sp, #12
+; Calculate the address of the varargs save area and save varargs
+; arguments into it.
+; CHECK-NEXT: add r0, sp, #20
+; CHECK-NEXT: stm r0, {r1, r2, r3}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2677.2.patch
Type: text/x-patch
Size: 3655 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140211/2d1424ae/attachment.bin>


More information about the llvm-commits mailing list