1; RUN: llc < %s -mcpu=generic -enable-misched=false -mtriple=x86_64-mingw32     | FileCheck %s -check-prefix=M64
2; RUN: llc < %s -mcpu=generic -enable-misched=false -mtriple=x86_64-win32       | FileCheck %s -check-prefix=W64
3; RUN: llc < %s -mcpu=generic -enable-misched=false -mtriple=x86_64-win32-macho | FileCheck %s -check-prefix=EFI
4; PR8777
5; PR8778
6
7define i64 @unaligned(i64 %n, i64 %x) nounwind {
8; M64-LABEL: unaligned:
9; W64-LABEL: unaligned:
10; EFI-LABEL: unaligned:
11entry:
12
13  %buf0 = alloca i8, i64 4096, align 1
14
15; ___chkstk must adjust %rsp.
16; M64: movq  %rsp, %rbp
17; M64:       $4096, %rax
18; M64: callq ___chkstk
19; M64-NOT:   %rsp
20
21; __chkstk does not adjust %rsp.
22; W64: movq  %rsp, %rbp
23; W64:       $4096, %rax
24; W64: callq __chkstk
25; W64: subq  %rax, %rsp
26
27; Freestanding
28; EFI: movq  %rsp, %rbp
29; EFI:       $[[B0OFS:4096|4104]], %rsp
30; EFI-NOT:   call
31
32  %buf1 = alloca i8, i64 %n, align 1
33
34; M64: leaq  15(%{{.*}}), %rax
35; M64: andq  $-16, %rax
36; M64: callq ___chkstk
37; M64-NOT:   %rsp
38; M64: movq  %rsp, %rax
39
40; W64: leaq  15(%{{.*}}), %rax
41; W64: andq  $-16, %rax
42; W64: callq __chkstk
43; W64: subq  %rax, %rsp
44; W64: movq  %rsp, %rax
45
46; EFI: leaq  15(%{{.*}}), [[R1:%r.*]]
47; EFI: andq  $-16, [[R1]]
48; EFI: movq  %rsp, [[R64:%r.*]]
49; EFI: subq  [[R1]], [[R64]]
50; EFI: movq  [[R64]], %rsp
51
52  %r = call i64 @bar(i64 %n, i64 %x, i64 %n, i8* %buf0, i8* %buf1) nounwind
53
54; M64: subq  $48, %rsp
55; M64: movq  %rax, 32(%rsp)
56; M64: leaq  -4096(%rbp), %r9
57; M64: callq bar
58
59; W64: subq  $48, %rsp
60; W64: movq  %rax, 32(%rsp)
61; W64: leaq  -4096(%rbp), %r9
62; W64: callq bar
63
64; EFI: subq  $48, %rsp
65; EFI: movq  [[R64]], 32(%rsp)
66; EFI: leaq  -[[B0OFS]](%rbp), %r9
67; EFI: callq _bar
68
69  ret i64 %r
70
71; M64: movq    %rbp, %rsp
72
73; W64: movq    %rbp, %rsp
74
75}
76
77define i64 @aligned(i64 %n, i64 %x) nounwind {
78; M64-LABEL: aligned:
79; W64-LABEL: aligned:
80; EFI-LABEL: aligned:
81entry:
82
83  %buf1 = alloca i8, i64 %n, align 128
84
85; M64: leaq  15(%{{.*}}), %rax
86; M64: andq  $-16, %rax
87; M64: callq ___chkstk
88; M64: movq  %rsp, [[R2:%r.*]]
89; M64: andq  $-128, [[R2]]
90; M64: movq  [[R2]], %rsp
91
92; W64: leaq  15(%{{.*}}), %rax
93; W64: andq  $-16, %rax
94; W64: callq __chkstk
95; W64: subq  %rax, %rsp
96; W64: movq  %rsp, [[R2:%r.*]]
97; W64: andq  $-128, [[R2]]
98; W64: movq  [[R2]], %rsp
99
100; EFI: leaq  15(%{{.*}}), [[R1:%r.*]]
101; EFI: andq  $-16, [[R1]]
102; EFI: movq  %rsp, [[R64:%r.*]]
103; EFI: subq  [[R1]], [[R64]]
104; EFI: andq  $-128, [[R64]]
105; EFI: movq  [[R64]], %rsp
106
107  %r = call i64 @bar(i64 %n, i64 %x, i64 %n, i8* undef, i8* %buf1) nounwind
108
109; M64: subq  $48, %rsp
110; M64: movq  [[R2]], 32(%rsp)
111; M64: callq bar
112
113; W64: subq  $48, %rsp
114; W64: movq  [[R2]], 32(%rsp)
115; W64: callq bar
116
117; EFI: subq  $48, %rsp
118; EFI: movq  [[R64]], 32(%rsp)
119; EFI: callq _bar
120
121  ret i64 %r
122}
123
124declare i64 @bar(i64, i64, i64, i8* nocapture, i8* nocapture) nounwind
125