Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit d2bc2dd

Browse files
committed
Merging r308950:
------------------------------------------------------------------------ r308950 | mstorsjo | 2017-07-24 22:20:01 -0700 (Mon, 24 Jul 2017) | 22 lines [AArch64] Reserve a 16 byte aligned amount of fixed stack for win64 varargs 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 registers on the stack. Differential Revision: https://reviews.llvm.org/D35720 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@309132 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 2ac73a1 commit d2bc2dd

File tree

3 files changed

+70
-13
lines changed

3 files changed

+70
-13
lines changed

lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2889,9 +2889,12 @@ void AArch64TargetLowering::saveVarArgRegisters(CCState &CCInfo,
28892889
unsigned GPRSaveSize = 8 * (NumGPRArgRegs - FirstVariadicGPR);
28902890
int GPRIdx = 0;
28912891
if (GPRSaveSize != 0) {
2892-
if (IsWin64)
2892+
if (IsWin64) {
28932893
GPRIdx = MFI.CreateFixedObject(GPRSaveSize, -(int)GPRSaveSize, false);
2894-
else
2894+
if (GPRSaveSize & 15)
2895+
// The extra size here, if triggered, will always be 8.
2896+
MFI.CreateFixedObject(16 - (GPRSaveSize & 15), -(int)alignTo(GPRSaveSize, 16), false);
2897+
} else
28952898
GPRIdx = MFI.CreateStackObject(GPRSaveSize, 8, false);
28962899

28972900
SDValue FIN = DAG.getFrameIndex(GPRIdx, PtrVT);

test/CodeGen/AArch64/aarch64_win64cc_vararg.ll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,12 @@ entry:
5959
}
6060

6161
; CHECK-LABEL: f7:
62-
; CHECK: sub sp, sp, #16
63-
; CHECK: add x8, sp, #8
64-
; CHECK: add x0, sp, #8
65-
; CHECK: stp x8, x7, [sp], #16
62+
; CHECK: sub sp, sp, #32
63+
; CHECK: add x8, sp, #24
64+
; CHECK: str x7, [sp, #24]
65+
; CHECK: add x0, sp, #24
66+
; CHECK: str x8, [sp, #8]
67+
; CHECK: add sp, sp, #32
6668
; CHECK: ret
6769
define win64cc i8* @f7(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, ...) nounwind {
6870
entry:

test/CodeGen/AArch64/win64_vararg.ll

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,12 @@ entry:
5959
}
6060

6161
; CHECK-LABEL: f7:
62-
; CHECK: sub sp, sp, #16
63-
; CHECK: add x8, sp, #8
64-
; CHECK: add x0, sp, #8
65-
; CHECK: stp x8, x7, [sp], #16
62+
; CHECK: sub sp, sp, #32
63+
; CHECK: add x8, sp, #24
64+
; CHECK: str x7, [sp, #24]
65+
; CHECK: add x0, sp, #24
66+
; CHECK: str x8, [sp, #8]
67+
; CHECK: add sp, sp, #32
6668
; CHECK: ret
6769
define i8* @f7(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, ...) nounwind {
6870
entry:
@@ -79,9 +81,8 @@ entry:
7981
; CHECK: stp x6, x7, [sp, #64]
8082
; CHECK: stp x4, x5, [sp, #48]
8183
; CHECK: stp x2, x3, [sp, #32]
82-
; CHECK: stp x8, x1, [sp, #16]
83-
; CHECK: str x8, [sp, #8]
84-
; CHECK: add sp, sp, #80
84+
; CHECK: str x1, [sp, #24]
85+
; CHECK: stp x8, x8, [sp], #80
8586
; CHECK: ret
8687
define void @copy1(i64 %a0, ...) nounwind {
8788
entry:
@@ -93,3 +94,54 @@ entry:
9394
call void @llvm.va_copy(i8* %cp1, i8* %ap1)
9495
ret void
9596
}
97+
98+
declare void @llvm.va_end(i8*)
99+
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
100+
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
101+
102+
declare i32 @__stdio_common_vsprintf(i64, i8*, i64, i8*, i8*, i8*) local_unnamed_addr #3
103+
declare i64* @__local_stdio_printf_options() local_unnamed_addr #4
104+
105+
; CHECK-LABEL: snprintf
106+
; CHECK: sub sp, sp, #96
107+
; CHECK: stp x21, x20, [sp, #16]
108+
; CHECK: stp x19, x30, [sp, #32]
109+
; CHECK: add x8, sp, #56
110+
; CHECK: mov x19, x2
111+
; CHECK: mov x20, x1
112+
; CHECK: mov x21, x0
113+
; CHECK: stp x6, x7, [sp, #80]
114+
; CHECK: stp x4, x5, [sp, #64]
115+
; CHECK: str x3, [sp, #56]
116+
; CHECK: str x8, [sp, #8]
117+
; CHECK: bl __local_stdio_printf_options
118+
; CHECK: ldr x8, [x0]
119+
; CHECK: add x5, sp, #56
120+
; CHECK: mov x1, x21
121+
; CHECK: mov x2, x20
122+
; CHECK: orr x0, x8, #0x2
123+
; CHECK: mov x3, x19
124+
; CHECK: mov x4, xzr
125+
; CHECK: bl __stdio_common_vsprintf
126+
; CHECK: ldp x19, x30, [sp, #32]
127+
; CHECK: ldp x21, x20, [sp, #16]
128+
; CHECK: cmp w0, #0
129+
; CHECK: csinv w0, w0, wzr, ge
130+
; CHECK: add sp, sp, #96
131+
; CHECK: ret
132+
define i32 @snprintf(i8*, i64, i8*, ...) local_unnamed_addr #5 {
133+
%4 = alloca i8*, align 8
134+
%5 = bitcast i8** %4 to i8*
135+
call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %5) #2
136+
call void @llvm.va_start(i8* nonnull %5)
137+
%6 = load i8*, i8** %4, align 8
138+
%7 = call i64* @__local_stdio_printf_options() #2
139+
%8 = load i64, i64* %7, align 8
140+
%9 = or i64 %8, 2
141+
%10 = call i32 @__stdio_common_vsprintf(i64 %9, i8* %0, i64 %1, i8* %2, i8* null, i8* %6) #2
142+
%11 = icmp sgt i32 %10, -1
143+
%12 = select i1 %11, i32 %10, i32 -1
144+
call void @llvm.va_end(i8* nonnull %5)
145+
call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %5) #2
146+
ret i32 %12
147+
}

0 commit comments

Comments
 (0)