[PATCH] D35720: [AArch64] Reserve a 16 byte aligned amount of fixed stack for win64 varargs

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 21 04:55:54 PDT 2017


mstorsjo created this revision.
Herald added subscribers: kristof.beyls, javed.absar, rengolin, aemerson.

Create a dummy 8 byte fixed object for the unused slot below the first stored vararg.

Alternative ideas tested but skipped: One could try to align the whole fixed object to 16, but I haven't found how to add an offset to the stack frame used in LowerWin64_VASTART.

If only the size of the fixed stack object size is padded but not the offset, via MFI.CreateFixedObject(alignTo(GPRSaveSize, 16), -(int)GPRSaveSize, false), PrologEpilogInserter crashes due to "Attempted to reset backwards range!".

This fixes misconceptions about where registers are spilled, since AArch64FrameLowering.cpp assumes the offset from fixed objects is aligned to 16 bytes (and the Win64 case there already manually aligns the offset to 16 bytes).

This fixes cases where local stack allocations could overwrite callee saved variables on the stack.


https://reviews.llvm.org/D35720

Files:
  lib/Target/AArch64/AArch64ISelLowering.cpp
  test/CodeGen/AArch64/aarch64_win64cc_vararg.ll
  test/CodeGen/AArch64/win64_vararg.ll


Index: test/CodeGen/AArch64/win64_vararg.ll
===================================================================
--- test/CodeGen/AArch64/win64_vararg.ll
+++ test/CodeGen/AArch64/win64_vararg.ll
@@ -59,10 +59,12 @@
 }
 
 ; CHECK-LABEL: f7:
-; CHECK: sub     sp, sp, #16
-; CHECK: add     x8, sp, #8
-; CHECK: add     x0, sp, #8
-; CHECK: stp     x8, x7, [sp], #16
+; CHECK: sub     sp, sp, #32
+; CHECK: add     x8, sp, #24
+; CHECK: str     x7, [sp, #24]
+; CHECK: add     x0, sp, #24
+; CHECK: str     x8, [sp, #8]
+; CHECK: add     sp, sp, #32
 ; CHECK: ret
 define i8* @f7(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, ...) nounwind {
 entry:
@@ -79,9 +81,8 @@
 ; CHECK: stp     x6, x7, [sp, #64]
 ; CHECK: stp     x4, x5, [sp, #48]
 ; CHECK: stp     x2, x3, [sp, #32]
-; CHECK: stp     x8, x1, [sp, #16]
-; CHECK: str     x8, [sp, #8]
-; CHECK: add     sp, sp, #80
+; CHECK: str     x1, [sp, #24]
+; CHECK: stp     x8, x8, [sp], #80
 ; CHECK: ret
 define void @copy1(i64 %a0, ...) nounwind {
 entry:
Index: test/CodeGen/AArch64/aarch64_win64cc_vararg.ll
===================================================================
--- test/CodeGen/AArch64/aarch64_win64cc_vararg.ll
+++ test/CodeGen/AArch64/aarch64_win64cc_vararg.ll
@@ -59,10 +59,12 @@
 }
 
 ; CHECK-LABEL: f7:
-; CHECK: sub     sp, sp, #16
-; CHECK: add     x8, sp, #8
-; CHECK: add     x0, sp, #8
-; CHECK: stp     x8, x7, [sp], #16
+; CHECK: sub     sp, sp, #32
+; CHECK: add     x8, sp, #24
+; CHECK: str     x7, [sp, #24]
+; CHECK: add     x0, sp, #24
+; CHECK: str     x8, [sp, #8]
+; CHECK: add     sp, sp, #32
 ; CHECK: ret
 define win64cc i8* @f7(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, ...) nounwind {
 entry:
Index: lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- lib/Target/AArch64/AArch64ISelLowering.cpp
+++ lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2889,9 +2889,11 @@
   unsigned GPRSaveSize = 8 * (NumGPRArgRegs - FirstVariadicGPR);
   int GPRIdx = 0;
   if (GPRSaveSize != 0) {
-    if (IsWin64)
+    if (IsWin64) {
       GPRIdx = MFI.CreateFixedObject(GPRSaveSize, -(int)GPRSaveSize, false);
-    else
+      if (GPRSaveSize & 15)
+        MFI.CreateFixedObject(8, -(int)alignTo(GPRSaveSize, 16), false);
+    } else
       GPRIdx = MFI.CreateStackObject(GPRSaveSize, 8, false);
 
     SDValue FIN = DAG.getFrameIndex(GPRIdx, PtrVT);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D35720.107653.patch
Type: text/x-patch
Size: 2427 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170721/f8d3af45/attachment.bin>


More information about the llvm-commits mailing list