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