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