1; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s
2
3declare token @llvm.call.preallocated.setup(i32)
4declare i8* @llvm.call.preallocated.arg(token, i32)
5
6%Foo = type { i32, i32 }
7
8declare void @init(%Foo*)
9
10
11
12declare void @foo_p(%Foo* preallocated(%Foo))
13
14define void @one_preallocated() {
15; CHECK-LABEL: _one_preallocated:
16  %t = call token @llvm.call.preallocated.setup(i32 1)
17  %a = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo)
18  %b = bitcast i8* %a to %Foo*
19; CHECK: subl $8, %esp
20; CHECK: calll _foo_p
21  call void @foo_p(%Foo* preallocated(%Foo) %b) ["preallocated"(token %t)]
22  ret void
23}
24
25define void @one_preallocated_two_blocks() {
26; CHECK-LABEL: _one_preallocated_two_blocks:
27  %t = call token @llvm.call.preallocated.setup(i32 1)
28  br label %second
29second:
30  %a = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo)
31  %b = bitcast i8* %a to %Foo*
32; CHECK: subl $8, %esp
33; CHECK: calll _foo_p
34  call void @foo_p(%Foo* preallocated(%Foo) %b) ["preallocated"(token %t)]
35  ret void
36}
37
38define void @preallocated_with_store() {
39; CHECK-LABEL: _preallocated_with_store:
40; CHECK: subl $8, %esp
41  %t = call token @llvm.call.preallocated.setup(i32 1)
42; CHECK: leal (%esp), [[REGISTER:%[a-z]+]]
43  %a = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo)
44  %b = bitcast i8* %a to %Foo*
45  %p0 = getelementptr %Foo, %Foo* %b, i32 0, i32 0
46  %p1 = getelementptr %Foo, %Foo* %b, i32 0, i32 1
47  store i32 13, i32* %p0
48  store i32 42, i32* %p1
49; CHECK-DAG: movl $13, ([[REGISTER]])
50; CHECK-DAG: movl $42, 4([[REGISTER]])
51; CHECK-NOT: subl {{\$[0-9]+}}, %esp
52; CHECK-NOT: pushl
53; CHECK: calll _foo_p
54  call void @foo_p(%Foo* preallocated(%Foo) %b) ["preallocated"(token %t)]
55  ret void
56}
57
58define void @preallocated_with_init() {
59; CHECK-LABEL: _preallocated_with_init:
60; CHECK: subl $8, %esp
61  %t = call token @llvm.call.preallocated.setup(i32 1)
62; CHECK: leal (%esp), [[REGISTER:%[a-z]+]]
63  %a = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo)
64  %b = bitcast i8* %a to %Foo*
65; CHECK: pushl [[REGISTER]]
66; CHECK: calll _init
67  call void @init(%Foo* %b)
68; CHECK-NOT: subl {{\$[0-9]+}}, %esp
69; CHECK-NOT: pushl
70; CHECK: calll _foo_p
71  call void @foo_p(%Foo* preallocated(%Foo) %b) ["preallocated"(token %t)]
72  ret void
73}
74
75declare void @foo_p_p(%Foo* preallocated(%Foo), %Foo* preallocated(%Foo))
76
77define void @two_preallocated() {
78; CHECK-LABEL: _two_preallocated:
79  %t = call token @llvm.call.preallocated.setup(i32 2)
80  %a1 = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo)
81  %b1 = bitcast i8* %a1 to %Foo*
82  %a2 = call i8* @llvm.call.preallocated.arg(token %t, i32 1) preallocated(%Foo)
83  %b2 = bitcast i8* %a2 to %Foo*
84; CHECK: subl $16, %esp
85; CHECK: calll _foo_p_p
86  call void @foo_p_p(%Foo* preallocated(%Foo) %b1, %Foo* preallocated(%Foo) %b2) ["preallocated"(token %t)]
87  ret void
88}
89
90declare void @foo_p_int(%Foo* preallocated(%Foo), i32)
91
92define void @one_preallocated_one_normal() {
93; CHECK-LABEL: _one_preallocated_one_normal:
94; CHECK: subl $12, %esp
95  %t = call token @llvm.call.preallocated.setup(i32 1)
96; CHECK: leal (%esp), [[REGISTER:%[a-z]+]]
97  %a = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo)
98  %b = bitcast i8* %a to %Foo*
99; CHECK: pushl [[REGISTER]]
100; CHECK: calll _init
101  call void @init(%Foo* %b)
102; CHECK-NOT: subl {{\$[0-9]+}}, %esp
103; CHECK-NOT: pushl
104; CHECK: movl $2, 8(%esp)
105; CHECK: calll _foo_p_int
106  call void @foo_p_int(%Foo* preallocated(%Foo) %b, i32 2) ["preallocated"(token %t)]
107  ret void
108}
109
110declare void @foo_ret_p(%Foo* sret(%Foo), %Foo* preallocated(%Foo))
111
112define void @nested_with_init() {
113; CHECK-LABEL: _nested_with_init:
114  %tmp = alloca %Foo
115
116  %t1 = call token @llvm.call.preallocated.setup(i32 1)
117; CHECK: subl $12, %esp
118  %a1 = call i8* @llvm.call.preallocated.arg(token %t1, i32 0) preallocated(%Foo)
119  %b1 = bitcast i8* %a1 to %Foo*
120; CHECK: leal 4(%esp), [[REGISTER1:%[a-z]+]]
121
122  %t2 = call token @llvm.call.preallocated.setup(i32 1)
123; CHECK: subl $12, %esp
124  %a2 = call i8* @llvm.call.preallocated.arg(token %t2, i32 0) preallocated(%Foo)
125; CHECK: leal 4(%esp), [[REGISTER2:%[a-z]+]]
126  %b2 = bitcast i8* %a2 to %Foo*
127
128  call void @init(%Foo* %b2)
129; CHECK: pushl [[REGISTER2]]
130; CHECK: calll _init
131
132  call void @foo_ret_p(%Foo* %b1, %Foo* preallocated(%Foo) %b2) ["preallocated"(token %t2)]
133; CHECK-NOT: subl {{\$[0-9]+}}, %esp
134; CHECK-NOT: pushl
135; CHECK: calll _foo_ret_p
136  call void @foo_ret_p(%Foo* %tmp, %Foo* preallocated(%Foo) %b1) ["preallocated"(token %t1)]
137; CHECK-NOT: subl {{\$[0-9]+}}, %esp
138; CHECK-NOT: pushl
139; CHECK: calll _foo_ret_p
140  ret void
141}
142
143declare void @foo_inreg_p(i32 inreg, %Foo* preallocated(%Foo))
144
145define void @inreg() {
146; CHECK-LABEL: _inreg:
147  %t = call token @llvm.call.preallocated.setup(i32 1)
148  %a = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo)
149  %b = bitcast i8* %a to %Foo*
150; CHECK: subl $8, %esp
151; CHECK: movl $9, %eax
152; CHECK: calll _foo_inreg_p
153  call void @foo_inreg_p(i32 9, %Foo* preallocated(%Foo) %b) ["preallocated"(token %t)]
154  ret void
155}
156
157declare x86_thiscallcc void @foo_thiscall_p(i8*, %Foo* preallocated(%Foo))
158
159define void @thiscall() {
160; CHECK-LABEL: _thiscall:
161  %t = call token @llvm.call.preallocated.setup(i32 1)
162  %a = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo)
163  %b = bitcast i8* %a to %Foo*
164; CHECK: subl $8, %esp
165; CHECK: xorl %ecx, %ecx
166; CHECK: calll _foo_thiscall_p
167  call x86_thiscallcc void @foo_thiscall_p(i8* null, %Foo* preallocated(%Foo) %b) ["preallocated"(token %t)]
168  ret void
169}
170
171declare x86_stdcallcc void @foo_stdcall_p(%Foo* preallocated(%Foo))
172declare x86_stdcallcc void @i(i32)
173
174define void @stdcall() {
175; CHECK-LABEL: _stdcall:
176  %t = call token @llvm.call.preallocated.setup(i32 1)
177  %a = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo)
178  %b = bitcast i8* %a to %Foo*
179; CHECK: subl $8, %esp
180; CHECK: calll _foo_stdcall_p@8
181  call x86_stdcallcc void @foo_stdcall_p(%Foo* preallocated(%Foo) %b) ["preallocated"(token %t)]
182; CHECK-NOT: %esp
183; CHECK: pushl
184; CHECK: calll _i@4
185  call x86_stdcallcc void @i(i32 0)
186  ret void
187}
188