[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