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