Mercurial > hg > CbC > CbC_llvm
comparison test/CodeGen/X86/sibcall.ll @ 147:c2174574ed3a
LLVM 10
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 16:55:33 +0900 |
parents | afa8332a0e37 |
children |
comparison
equal
deleted
inserted
replaced
134:3a76565eade5 | 147:c2174574ed3a |
---|---|
1 ; RUN: llc < %s -mtriple=i686-linux -mcpu=core2 -mattr=+sse2 -asm-verbose=false | FileCheck %s -check-prefix=32 | 1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
2 ; RUN: llc < %s -mtriple=x86_64-linux -mcpu=core2 -mattr=+sse2 -asm-verbose=false | FileCheck %s -check-prefix=64 | 2 ; RUN: llc -verify-machineinstrs < %s -mtriple=i686-linux -mcpu=core2 -mattr=+sse2 | FileCheck %s --check-prefix=X86 |
3 ; RUN: llc < %s -mtriple=x86_64-linux-gnux32 -mcpu=core2 -mattr=+sse2 -asm-verbose=false | FileCheck %s -check-prefix=X32ABI | 3 ; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-linux -mcpu=core2 -mattr=+sse2 | FileCheck %s --check-prefix=X64 |
4 ; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-linux-gnux32 -mcpu=core2 -mattr=+sse2 | FileCheck %s --check-prefix=X32 | |
4 | 5 |
5 define void @t1(i32 %x) nounwind ssp { | 6 define void @t1(i32 %x) nounwind ssp { |
6 entry: | 7 ; X86-LABEL: t1: |
7 ; 32-LABEL: t1: | 8 ; X86: # %bb.0: |
8 ; 32: jmp {{_?}}foo | 9 ; X86-NEXT: jmp foo # TAILCALL |
9 | 10 ; |
10 ; 64-LABEL: t1: | 11 ; X64-LABEL: t1: |
11 ; 64: jmp {{_?}}foo | 12 ; X64: # %bb.0: |
12 | 13 ; X64-NEXT: jmp foo # TAILCALL |
13 ; X32ABI-LABEL: t1: | 14 ; |
14 ; X32ABI: jmp {{_?}}foo | 15 ; X32-LABEL: t1: |
16 ; X32: # %bb.0: | |
17 ; X32-NEXT: jmp foo # TAILCALL | |
15 tail call void @foo() nounwind | 18 tail call void @foo() nounwind |
16 ret void | 19 ret void |
17 } | 20 } |
18 | 21 |
19 declare void @foo() | 22 declare void @foo() |
20 | 23 |
21 define void @t2() nounwind ssp { | 24 define void @t2() nounwind ssp { |
22 entry: | 25 ; X86-LABEL: t2: |
23 ; 32-LABEL: t2: | 26 ; X86: # %bb.0: |
24 ; 32: jmp {{_?}}foo2 | 27 ; X86-NEXT: jmp foo2 # TAILCALL |
25 | 28 ; |
26 ; 64-LABEL: t2: | 29 ; X64-LABEL: t2: |
27 ; 64: jmp {{_?}}foo2 | 30 ; X64: # %bb.0: |
28 | 31 ; X64-NEXT: jmp foo2 # TAILCALL |
29 ; X32ABI-LABEL: t2: | 32 ; |
30 ; X32ABI: jmp {{_?}}foo2 | 33 ; X32-LABEL: t2: |
31 %0 = tail call i32 @foo2() nounwind | 34 ; X32: # %bb.0: |
35 ; X32-NEXT: jmp foo2 # TAILCALL | |
36 %t0 = tail call i32 @foo2() nounwind | |
32 ret void | 37 ret void |
33 } | 38 } |
34 | 39 |
35 declare i32 @foo2() | 40 declare i32 @foo2() |
36 | 41 |
37 define void @t3() nounwind ssp { | 42 define void @t3() nounwind ssp { |
38 entry: | 43 ; X86-LABEL: t3: |
39 ; 32-LABEL: t3: | 44 ; X86: # %bb.0: |
40 ; 32: jmp {{_?}}foo3 | 45 ; X86-NEXT: jmp foo3 # TAILCALL |
41 | 46 ; |
42 ; 64-LABEL: t3: | 47 ; X64-LABEL: t3: |
43 ; 64: jmp {{_?}}foo3 | 48 ; X64: # %bb.0: |
44 | 49 ; X64-NEXT: jmp foo3 # TAILCALL |
45 ; X32ABI-LABEL: t3: | 50 ; |
46 ; X32ABI: jmp {{_?}}foo3 | 51 ; X32-LABEL: t3: |
47 %0 = tail call i32 @foo3() nounwind | 52 ; X32: # %bb.0: |
53 ; X32-NEXT: jmp foo3 # TAILCALL | |
54 %t0 = tail call i32 @foo3() nounwind | |
48 ret void | 55 ret void |
49 } | 56 } |
50 | 57 |
51 declare i32 @foo3() | 58 declare i32 @foo3() |
52 | 59 |
53 define void @t4(void (i32)* nocapture %x) nounwind ssp { | 60 define void @t4(void (i32)* nocapture %x) nounwind ssp { |
54 entry: | 61 ; X86-LABEL: t4: |
55 ; 32-LABEL: t4: | 62 ; X86: # %bb.0: |
56 ; 32: calll * | 63 ; X86-NEXT: subl $12, %esp |
57 ; FIXME: gcc can generate a tailcall for this. But it's tricky. | 64 ; X86-NEXT: movl $0, (%esp) |
58 | 65 ; X86-NEXT: calll *{{[0-9]+}}(%esp) |
59 ; 64-LABEL: t4: | 66 ; X86-NEXT: addl $12, %esp |
60 ; 64-NOT: call | 67 ; X86-NEXT: retl |
61 ; 64: jmpq * | 68 ; |
62 | 69 ; X64-LABEL: t4: |
63 ; X32ABI-LABEL: t4: | 70 ; X64: # %bb.0: |
64 ; X32ABI-NOT: call | 71 ; X64-NEXT: movq %rdi, %rax |
65 ; X32ABI: jmpq * | 72 ; X64-NEXT: xorl %edi, %edi |
73 ; X64-NEXT: jmpq *%rax # TAILCALL | |
74 ; | |
75 ; X32-LABEL: t4: | |
76 ; X32: # %bb.0: | |
77 ; X32-NEXT: movl %edi, %eax | |
78 ; X32-NEXT: xorl %edi, %edi | |
79 ; X32-NEXT: jmpq *%rax # TAILCALL | |
66 tail call void %x(i32 0) nounwind | 80 tail call void %x(i32 0) nounwind |
67 ret void | 81 ret void |
68 } | 82 } |
69 | 83 |
70 define void @t5(void ()* nocapture %x) nounwind ssp { | |
71 entry: | |
72 ; 32-LABEL: t5: | |
73 ; 32-NOT: call | |
74 ; 32: jmpl *4(%esp) | |
75 | |
76 ; 64-LABEL: t5: | |
77 ; 64-NOT: call | |
78 ; 64: jmpq *%rdi | |
79 | |
80 ; X32ABI-LABEL: t5: | |
81 ; X32ABI-NOT: call | |
82 ; FIXME: This isn't needed since x32 psABI specifies that callers must | 84 ; FIXME: This isn't needed since x32 psABI specifies that callers must |
83 ; zero-extend pointers passed in registers. | 85 ; zero-extend pointers passed in registers. |
84 ; X32ABI: movl %edi, %eax | 86 |
85 ; X32ABI: jmpq *%rax | 87 define void @t5(void ()* nocapture %x) nounwind ssp { |
88 ; X86-LABEL: t5: | |
89 ; X86: # %bb.0: | |
90 ; X86-NEXT: jmpl *{{[0-9]+}}(%esp) # TAILCALL | |
91 ; | |
92 ; X64-LABEL: t5: | |
93 ; X64: # %bb.0: | |
94 ; X64-NEXT: jmpq *%rdi # TAILCALL | |
95 ; | |
96 ; X32-LABEL: t5: | |
97 ; X32: # %bb.0: | |
98 ; X32-NEXT: movl %edi, %eax | |
99 ; X32-NEXT: jmpq *%rax # TAILCALL | |
86 tail call void %x() nounwind | 100 tail call void %x() nounwind |
87 ret void | 101 ret void |
88 } | 102 } |
89 | 103 |
104 ; Basically the same test as t5, except pass the function pointer on the stack | |
105 ; for x86_64. | |
106 | |
107 define void @t5_x64(i32, i32, i32, i32, i32, i32, void ()* nocapture %x) nounwind ssp { | |
108 ; X86-LABEL: t5_x64: | |
109 ; X86: # %bb.0: | |
110 ; X86-NEXT: jmpl *{{[0-9]+}}(%esp) # TAILCALL | |
111 ; | |
112 ; X64-LABEL: t5_x64: | |
113 ; X64: # %bb.0: | |
114 ; X64-NEXT: jmpq *{{[0-9]+}}(%rsp) # TAILCALL | |
115 ; | |
116 ; X32-LABEL: t5_x64: | |
117 ; X32: # %bb.0: | |
118 ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax | |
119 ; X32-NEXT: jmpq *%rax # TAILCALL | |
120 tail call void %x() nounwind | |
121 ret void | |
122 } | |
123 | |
124 | |
90 define i32 @t6(i32 %x) nounwind ssp { | 125 define i32 @t6(i32 %x) nounwind ssp { |
91 entry: | 126 ; X86-LABEL: t6: |
92 ; 32-LABEL: t6: | 127 ; X86: # %bb.0: |
93 ; 32: calll {{_?}}t6 | 128 ; X86-NEXT: subl $12, %esp |
94 ; 32: jmp {{_?}}bar | 129 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax |
95 | 130 ; X86-NEXT: cmpl $9, %eax |
96 ; 64-LABEL: t6: | 131 ; X86-NEXT: jg .LBB6_2 |
97 ; 64: jmp {{_?}}t6 | 132 ; X86-NEXT: # %bb.1: # %bb |
98 ; 64: jmp {{_?}}bar | 133 ; X86-NEXT: decl %eax |
99 | 134 ; X86-NEXT: movl %eax, (%esp) |
100 ; X32ABI-LABEL: t6: | 135 ; X86-NEXT: calll t6 |
101 ; X32ABI: jmp {{_?}}t6 | 136 ; X86-NEXT: addl $12, %esp |
102 ; X32ABI: jmp {{_?}}bar | 137 ; X86-NEXT: retl |
103 %0 = icmp slt i32 %x, 10 | 138 ; X86-NEXT: .LBB6_2: # %bb1 |
104 br i1 %0, label %bb, label %bb1 | 139 ; X86-NEXT: addl $12, %esp |
140 ; X86-NEXT: jmp bar # TAILCALL | |
141 ; | |
142 ; X64-LABEL: t6: | |
143 ; X64: # %bb.0: | |
144 ; X64-NEXT: cmpl $9, %edi | |
145 ; X64-NEXT: jg .LBB6_2 | |
146 ; X64-NEXT: # %bb.1: # %bb | |
147 ; X64-NEXT: decl %edi | |
148 ; X64-NEXT: jmp t6 # TAILCALL | |
149 ; X64-NEXT: .LBB6_2: # %bb1 | |
150 ; X64-NEXT: jmp bar # TAILCALL | |
151 ; | |
152 ; X32-LABEL: t6: | |
153 ; X32: # %bb.0: | |
154 ; X32-NEXT: cmpl $9, %edi | |
155 ; X32-NEXT: jg .LBB6_2 | |
156 ; X32-NEXT: # %bb.1: # %bb | |
157 ; X32-NEXT: decl %edi | |
158 ; X32-NEXT: jmp t6 # TAILCALL | |
159 ; X32-NEXT: .LBB6_2: # %bb1 | |
160 ; X32-NEXT: jmp bar # TAILCALL | |
161 %t0 = icmp slt i32 %x, 10 | |
162 br i1 %t0, label %bb, label %bb1 | |
105 | 163 |
106 bb: | 164 bb: |
107 %1 = add nsw i32 %x, -1 | 165 %t1 = add nsw i32 %x, -1 |
108 %2 = tail call i32 @t6(i32 %1) nounwind ssp | 166 %t2 = tail call i32 @t6(i32 %t1) nounwind ssp |
109 ret i32 %2 | 167 ret i32 %t2 |
110 | 168 |
111 bb1: | 169 bb1: |
112 %3 = tail call i32 @bar(i32 %x) nounwind | 170 %t3 = tail call i32 @bar(i32 %x) nounwind |
113 ret i32 %3 | 171 ret i32 %t3 |
114 } | 172 } |
115 | 173 |
116 declare i32 @bar(i32) | 174 declare i32 @bar(i32) |
117 | 175 |
118 define i32 @t7(i32 %a, i32 %b, i32 %c) nounwind ssp { | 176 define i32 @t7(i32 %a, i32 %b, i32 %c) nounwind ssp { |
119 entry: | 177 ; X86-LABEL: t7: |
120 ; 32-LABEL: t7: | 178 ; X86: # %bb.0: |
121 ; 32: jmp {{_?}}bar2 | 179 ; X86-NEXT: jmp bar2 # TAILCALL |
122 | 180 ; |
123 ; 64-LABEL: t7: | 181 ; X64-LABEL: t7: |
124 ; 64: jmp {{_?}}bar2 | 182 ; X64: # %bb.0: |
125 | 183 ; X64-NEXT: jmp bar2 # TAILCALL |
126 ; X32ABI-LABEL: t7: | 184 ; |
127 ; X32ABI: jmp {{_?}}bar2 | 185 ; X32-LABEL: t7: |
128 %0 = tail call i32 @bar2(i32 %a, i32 %b, i32 %c) nounwind | 186 ; X32: # %bb.0: |
129 ret i32 %0 | 187 ; X32-NEXT: jmp bar2 # TAILCALL |
188 %t0 = tail call i32 @bar2(i32 %a, i32 %b, i32 %c) nounwind | |
189 ret i32 %t0 | |
130 } | 190 } |
131 | 191 |
132 declare i32 @bar2(i32, i32, i32) | 192 declare i32 @bar2(i32, i32, i32) |
133 | 193 |
134 define signext i16 @t8() nounwind ssp { | 194 define signext i16 @t8() nounwind ssp { |
135 entry: | 195 ; X86-LABEL: t8: |
136 ; 32-LABEL: t8: | 196 ; X86: # %bb.0: # %entry |
137 ; 32: jmp {{_?}}bar3 | 197 ; X86-NEXT: jmp bar3 # TAILCALL |
138 | 198 ; |
139 ; 64-LABEL: t8: | 199 ; X64-LABEL: t8: |
140 ; 64: jmp {{_?}}bar3 | 200 ; X64: # %bb.0: # %entry |
141 | 201 ; X64-NEXT: jmp bar3 # TAILCALL |
142 ; X32ABI-LABEL: t8: | 202 ; |
143 ; X32ABI: jmp {{_?}}bar3 | 203 ; X32-LABEL: t8: |
204 ; X32: # %bb.0: # %entry | |
205 ; X32-NEXT: jmp bar3 # TAILCALL | |
206 entry: | |
144 %0 = tail call signext i16 @bar3() nounwind ; <i16> [#uses=1] | 207 %0 = tail call signext i16 @bar3() nounwind ; <i16> [#uses=1] |
145 ret i16 %0 | 208 ret i16 %0 |
146 } | 209 } |
147 | 210 |
148 declare signext i16 @bar3() | 211 declare signext i16 @bar3() |
149 | 212 |
150 define signext i16 @t9(i32 (i32)* nocapture %x) nounwind ssp { | 213 define signext i16 @t9(i32 (i32)* nocapture %x) nounwind ssp { |
151 entry: | 214 ; X86-LABEL: t9: |
152 ; 32-LABEL: t9: | 215 ; X86: # %bb.0: # %entry |
153 ; 32: calll * | 216 ; X86-NEXT: subl $12, %esp |
154 | 217 ; X86-NEXT: movl $0, (%esp) |
155 ; 64-LABEL: t9: | 218 ; X86-NEXT: calll *{{[0-9]+}}(%esp) |
156 ; 64: jmpq * | 219 ; X86-NEXT: addl $12, %esp |
157 | 220 ; X86-NEXT: retl |
158 ; X32ABI-LABEL: t9: | 221 ; |
159 ; X32ABI: jmpq * | 222 ; X64-LABEL: t9: |
223 ; X64: # %bb.0: # %entry | |
224 ; X64-NEXT: movq %rdi, %rax | |
225 ; X64-NEXT: xorl %edi, %edi | |
226 ; X64-NEXT: jmpq *%rax # TAILCALL | |
227 ; | |
228 ; X32-LABEL: t9: | |
229 ; X32: # %bb.0: # %entry | |
230 ; X32-NEXT: movl %edi, %eax | |
231 ; X32-NEXT: xorl %edi, %edi | |
232 ; X32-NEXT: jmpq *%rax # TAILCALL | |
233 entry: | |
160 %0 = bitcast i32 (i32)* %x to i16 (i32)* | 234 %0 = bitcast i32 (i32)* %x to i16 (i32)* |
161 %1 = tail call signext i16 %0(i32 0) nounwind | 235 %1 = tail call signext i16 %0(i32 0) nounwind |
162 ret i16 %1 | 236 ret i16 %1 |
163 } | 237 } |
164 | 238 |
165 define void @t10() nounwind ssp { | 239 define void @t10() nounwind ssp { |
166 entry: | 240 ; X86-LABEL: t10: |
167 ; 32-LABEL: t10: | 241 ; X86: # %bb.0: # %entry |
168 ; 32: calll | 242 ; X86-NEXT: subl $12, %esp |
169 | 243 ; X86-NEXT: calll foo4 |
170 ; 64-LABEL: t10: | 244 ; |
171 ; 64: callq | 245 ; X64-LABEL: t10: |
172 | 246 ; X64: # %bb.0: # %entry |
173 ; X32ABI-LABEL: t10: | 247 ; X64-NEXT: pushq %rax |
174 ; X32ABI: callq | 248 ; X64-NEXT: callq foo4 |
249 ; | |
250 ; X32-LABEL: t10: | |
251 ; X32: # %bb.0: # %entry | |
252 ; X32-NEXT: pushq %rax | |
253 ; X32-NEXT: callq foo4 | |
254 entry: | |
175 %0 = tail call i32 @foo4() noreturn nounwind | 255 %0 = tail call i32 @foo4() noreturn nounwind |
176 unreachable | 256 unreachable |
177 } | 257 } |
178 | 258 |
179 declare i32 @foo4() | 259 declare i32 @foo4() |
180 | 260 |
181 define i32 @t11(i32 %x, i32 %y, i32 %z.0, i32 %z.1, i32 %z.2) nounwind ssp { | |
182 ; In 32-bit mode, it's emitting a bunch of dead loads that are not being | 261 ; In 32-bit mode, it's emitting a bunch of dead loads that are not being |
183 ; eliminated currently. | 262 ; eliminated currently. |
184 | 263 |
185 ; 32-LABEL: t11: | 264 define i32 @t11(i32 %x, i32 %y, i32 %z.0, i32 %z.1, i32 %z.2) nounwind ssp { |
186 ; 32-NOT: subl ${{[0-9]+}}, %esp | 265 ; X86-LABEL: t11: |
187 ; 32: je | 266 ; X86: # %bb.0: # %entry |
188 ; 32-NOT: movl | 267 ; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp) |
189 ; 32-NOT: addl ${{[0-9]+}}, %esp | 268 ; X86-NEXT: je .LBB11_1 |
190 ; 32: jmp {{_?}}foo5 | 269 ; X86-NEXT: # %bb.2: # %bb |
191 | 270 ; X86-NEXT: jmp foo5 # TAILCALL |
192 ; 64-LABEL: t11: | 271 ; X86-NEXT: .LBB11_1: # %bb6 |
193 ; 64-NOT: subq ${{[0-9]+}}, %rsp | 272 ; X86-NEXT: xorl %eax, %eax |
194 ; 64-NOT: addq ${{[0-9]+}}, %rsp | 273 ; X86-NEXT: retl |
195 ; 64: jmp {{_?}}foo5 | 274 ; |
196 | 275 ; X64-LABEL: t11: |
197 ; X32ABI-LABEL: t11: | 276 ; X64: # %bb.0: # %entry |
198 ; X32ABI-NOT: subl ${{[0-9]+}}, %esp | 277 ; X64-NEXT: testl %edi, %edi |
199 ; X32ABI-NOT: addl ${{[0-9]+}}, %esp | 278 ; X64-NEXT: je .LBB11_1 |
200 ; X32ABI: jmp {{_?}}foo5 | 279 ; X64-NEXT: # %bb.2: # %bb |
280 ; X64-NEXT: jmp foo5 # TAILCALL | |
281 ; X64-NEXT: .LBB11_1: # %bb6 | |
282 ; X64-NEXT: xorl %eax, %eax | |
283 ; X64-NEXT: retq | |
284 ; | |
285 ; X32-LABEL: t11: | |
286 ; X32: # %bb.0: # %entry | |
287 ; X32-NEXT: testl %edi, %edi | |
288 ; X32-NEXT: je .LBB11_1 | |
289 ; X32-NEXT: # %bb.2: # %bb | |
290 ; X32-NEXT: jmp foo5 # TAILCALL | |
291 ; X32-NEXT: .LBB11_1: # %bb6 | |
292 ; X32-NEXT: xorl %eax, %eax | |
293 ; X32-NEXT: retq | |
201 entry: | 294 entry: |
202 %0 = icmp eq i32 %x, 0 | 295 %0 = icmp eq i32 %x, 0 |
203 br i1 %0, label %bb6, label %bb | 296 br i1 %0, label %bb6, label %bb |
204 | 297 |
205 bb: | 298 bb: |
213 declare i32 @foo5(i32, i32, i32, i32, i32) | 306 declare i32 @foo5(i32, i32, i32, i32, i32) |
214 | 307 |
215 %struct.t = type { i32, i32, i32, i32, i32 } | 308 %struct.t = type { i32, i32, i32, i32, i32 } |
216 | 309 |
217 define i32 @t12(i32 %x, i32 %y, %struct.t* byval align 4 %z) nounwind ssp { | 310 define i32 @t12(i32 %x, i32 %y, %struct.t* byval align 4 %z) nounwind ssp { |
218 ; 32-LABEL: t12: | 311 ; X86-LABEL: t12: |
219 ; 32-NOT: subl ${{[0-9]+}}, %esp | 312 ; X86: # %bb.0: # %entry |
220 ; 32-NOT: addl ${{[0-9]+}}, %esp | 313 ; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp) |
221 ; 32: jmp {{_?}}foo6 | 314 ; X86-NEXT: je .LBB12_1 |
222 | 315 ; X86-NEXT: # %bb.2: # %bb |
223 ; 64-LABEL: t12: | 316 ; X86-NEXT: jmp foo6 # TAILCALL |
224 ; 64-NOT: subq ${{[0-9]+}}, %rsp | 317 ; X86-NEXT: .LBB12_1: # %bb2 |
225 ; 64-NOT: addq ${{[0-9]+}}, %rsp | 318 ; X86-NEXT: xorl %eax, %eax |
226 ; 64: jmp {{_?}}foo6 | 319 ; X86-NEXT: retl |
227 | 320 ; |
228 ; X32ABI-LABEL: t12: | 321 ; X64-LABEL: t12: |
229 ; X32ABI-NOT: subl ${{[0-9]+}}, %esp | 322 ; X64: # %bb.0: # %entry |
230 ; X32ABI-NOT: addl ${{[0-9]+}}, %esp | 323 ; X64-NEXT: testl %edi, %edi |
231 ; X32ABI: jmp {{_?}}foo6 | 324 ; X64-NEXT: je .LBB12_1 |
325 ; X64-NEXT: # %bb.2: # %bb | |
326 ; X64-NEXT: jmp foo6 # TAILCALL | |
327 ; X64-NEXT: .LBB12_1: # %bb2 | |
328 ; X64-NEXT: xorl %eax, %eax | |
329 ; X64-NEXT: retq | |
330 ; | |
331 ; X32-LABEL: t12: | |
332 ; X32: # %bb.0: # %entry | |
333 ; X32-NEXT: testl %edi, %edi | |
334 ; X32-NEXT: je .LBB12_1 | |
335 ; X32-NEXT: # %bb.2: # %bb | |
336 ; X32-NEXT: jmp foo6 # TAILCALL | |
337 ; X32-NEXT: .LBB12_1: # %bb2 | |
338 ; X32-NEXT: xorl %eax, %eax | |
339 ; X32-NEXT: retq | |
232 entry: | 340 entry: |
233 %0 = icmp eq i32 %x, 0 | 341 %0 = icmp eq i32 %x, 0 |
234 br i1 %0, label %bb2, label %bb | 342 br i1 %0, label %bb2, label %bb |
235 | 343 |
236 bb: | 344 bb: |
246 ; rdar://r7717598 | 354 ; rdar://r7717598 |
247 %struct.ns = type { i32, i32 } | 355 %struct.ns = type { i32, i32 } |
248 %struct.cp = type { float, float, float, float, float } | 356 %struct.cp = type { float, float, float, float, float } |
249 | 357 |
250 define %struct.ns* @t13(%struct.cp* %yy) nounwind ssp { | 358 define %struct.ns* @t13(%struct.cp* %yy) nounwind ssp { |
251 ; 32-LABEL: t13: | 359 ; X86-LABEL: t13: |
252 ; 32-NOT: jmp | 360 ; X86: # %bb.0: # %entry |
253 ; 32: calll | 361 ; X86-NEXT: subl $28, %esp |
254 ; 32: ret | 362 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax |
255 | 363 ; X86-NEXT: movl 16(%eax), %ecx |
256 ; 64-LABEL: t13: | 364 ; X86-NEXT: movl %ecx, {{[0-9]+}}(%esp) |
257 ; 64-NOT: jmp | 365 ; X86-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero |
258 ; 64: callq | 366 ; X86-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero |
259 ; 64: ret | 367 ; X86-NEXT: movsd %xmm1, {{[0-9]+}}(%esp) |
260 | 368 ; X86-NEXT: movsd %xmm0, (%esp) |
261 ; X32ABI-LABEL: t13: | 369 ; X86-NEXT: xorl %ecx, %ecx |
262 ; X32ABI-NOT: jmp | 370 ; X86-NEXT: calll foo7 |
263 ; X32ABI: callq | 371 ; X86-NEXT: addl $28, %esp |
264 ; X32ABI: ret | 372 ; X86-NEXT: retl |
373 ; | |
374 ; X64-LABEL: t13: | |
375 ; X64: # %bb.0: # %entry | |
376 ; X64-NEXT: pushq %rax | |
377 ; X64-NEXT: subq $8, %rsp | |
378 ; X64-NEXT: movl 16(%rdi), %eax | |
379 ; X64-NEXT: movq (%rdi), %rcx | |
380 ; X64-NEXT: movq 8(%rdi), %rdx | |
381 ; X64-NEXT: xorl %edi, %edi | |
382 ; X64-NEXT: pushq %rax | |
383 ; X64-NEXT: pushq %rdx | |
384 ; X64-NEXT: pushq %rcx | |
385 ; X64-NEXT: callq foo7 | |
386 ; X64-NEXT: addq $32, %rsp | |
387 ; X64-NEXT: popq %rcx | |
388 ; X64-NEXT: retq | |
389 ; | |
390 ; X32-LABEL: t13: | |
391 ; X32: # %bb.0: # %entry | |
392 ; X32-NEXT: pushq %rax | |
393 ; X32-NEXT: subl $8, %esp | |
394 ; X32-NEXT: movl 16(%edi), %eax | |
395 ; X32-NEXT: movq (%edi), %rcx | |
396 ; X32-NEXT: movq 8(%edi), %rdx | |
397 ; X32-NEXT: xorl %edi, %edi | |
398 ; X32-NEXT: pushq %rax | |
399 ; X32-NEXT: pushq %rdx | |
400 ; X32-NEXT: pushq %rcx | |
401 ; X32-NEXT: callq foo7 | |
402 ; X32-NEXT: addl $32, %esp | |
403 ; X32-NEXT: popq %rcx | |
404 ; X32-NEXT: retq | |
265 entry: | 405 entry: |
266 %0 = tail call fastcc %struct.ns* @foo7(%struct.cp* byval align 4 %yy, i8 signext 0) nounwind | 406 %0 = tail call fastcc %struct.ns* @foo7(%struct.cp* byval align 4 %yy, i8 signext 0) nounwind |
267 ret %struct.ns* %0 | 407 ret %struct.ns* %0 |
268 } | 408 } |
269 | 409 |
275 %struct.__block_descriptor_withcopydispose = type { i64, i64, i8*, i8* } | 415 %struct.__block_descriptor_withcopydispose = type { i64, i64, i8*, i8* } |
276 %struct.__block_literal_1 = type { i8*, i32, i32, i8*, %struct.__block_descriptor* } | 416 %struct.__block_literal_1 = type { i8*, i32, i32, i8*, %struct.__block_descriptor* } |
277 %struct.__block_literal_2 = type { i8*, i32, i32, i8*, %struct.__block_descriptor_withcopydispose*, void ()* } | 417 %struct.__block_literal_2 = type { i8*, i32, i32, i8*, %struct.__block_descriptor_withcopydispose*, void ()* } |
278 | 418 |
279 define void @t14(%struct.__block_literal_2* nocapture %.block_descriptor) nounwind ssp { | 419 define void @t14(%struct.__block_literal_2* nocapture %.block_descriptor) nounwind ssp { |
280 entry: | 420 ; X86-LABEL: t14: |
281 ; 64-LABEL: t14: | 421 ; X86: # %bb.0: # %entry |
282 ; 64: movq 32(%rdi) | 422 ; X86-NEXT: subl $12, %esp |
283 ; 64-NOT: movq 16(%rdi) | 423 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax |
284 ; 64: jmpq *16({{%rdi|%rax}}) | 424 ; X86-NEXT: movl 20(%eax), %eax |
285 | 425 ; X86-NEXT: movl %eax, (%esp) |
286 ; X32ABI-LABEL: t14: | 426 ; X86-NEXT: calll *12(%eax) |
287 ; X32ABI: movl 20(%edi), %edi | 427 ; X86-NEXT: addl $12, %esp |
288 ; X32ABI-NEXT: movl 12(%edi), %eax | 428 ; X86-NEXT: retl |
289 ; X32ABI-NEXT: jmpq *%rax | 429 ; |
430 ; X64-LABEL: t14: | |
431 ; X64: # %bb.0: # %entry | |
432 ; X64-NEXT: movq 32(%rdi), %rdi | |
433 ; X64-NEXT: jmpq *16(%rdi) # TAILCALL | |
434 ; | |
435 ; X32-LABEL: t14: | |
436 ; X32: # %bb.0: # %entry | |
437 ; X32-NEXT: movl 20(%edi), %edi | |
438 ; X32-NEXT: movl 12(%edi), %eax | |
439 ; X32-NEXT: jmpq *%rax # TAILCALL | |
440 entry: | |
290 %0 = getelementptr inbounds %struct.__block_literal_2, %struct.__block_literal_2* %.block_descriptor, i64 0, i32 5 ; <void ()**> [#uses=1] | 441 %0 = getelementptr inbounds %struct.__block_literal_2, %struct.__block_literal_2* %.block_descriptor, i64 0, i32 5 ; <void ()**> [#uses=1] |
291 %1 = load void ()*, void ()** %0, align 8 ; <void ()*> [#uses=2] | 442 %1 = load void ()*, void ()** %0, align 8 ; <void ()*> [#uses=2] |
292 %2 = bitcast void ()* %1 to %struct.__block_literal_1* ; <%struct.__block_literal_1*> [#uses=1] | 443 %2 = bitcast void ()* %1 to %struct.__block_literal_1* ; <%struct.__block_literal_1*> [#uses=1] |
293 %3 = getelementptr inbounds %struct.__block_literal_1, %struct.__block_literal_1* %2, i64 0, i32 3 ; <i8**> [#uses=1] | 444 %3 = getelementptr inbounds %struct.__block_literal_1, %struct.__block_literal_1* %2, i64 0, i32 3 ; <i8**> [#uses=1] |
294 %4 = load i8*, i8** %3, align 8 ; <i8*> [#uses=1] | 445 %4 = load i8*, i8** %3, align 8 ; <i8*> [#uses=1] |
300 | 451 |
301 ; rdar://7726868 | 452 ; rdar://7726868 |
302 %struct.foo = type { [4 x i32] } | 453 %struct.foo = type { [4 x i32] } |
303 | 454 |
304 define void @t15(%struct.foo* noalias sret %agg.result) nounwind { | 455 define void @t15(%struct.foo* noalias sret %agg.result) nounwind { |
305 ; 32-LABEL: t15: | 456 ; X86-LABEL: t15: |
306 ; 32: calll {{_?}}f | 457 ; X86: # %bb.0: |
307 ; 32: retl $4 | 458 ; X86-NEXT: pushl %esi |
308 | 459 ; X86-NEXT: subl $8, %esp |
309 ; 64-LABEL: t15: | 460 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi |
310 ; 64: callq {{_?}}f | 461 ; X86-NEXT: movl %esi, %ecx |
311 ; 64: retq | 462 ; X86-NEXT: calll f |
312 | 463 ; X86-NEXT: movl %esi, %eax |
313 ; X32ABI-LABEL: t15: | 464 ; X86-NEXT: addl $8, %esp |
314 ; X32ABI: callq {{_?}}f | 465 ; X86-NEXT: popl %esi |
315 ; X32ABI: retq | 466 ; X86-NEXT: retl $4 |
467 ; | |
468 ; X64-LABEL: t15: | |
469 ; X64: # %bb.0: | |
470 ; X64-NEXT: pushq %rbx | |
471 ; X64-NEXT: movq %rdi, %rbx | |
472 ; X64-NEXT: callq f | |
473 ; X64-NEXT: movq %rbx, %rax | |
474 ; X64-NEXT: popq %rbx | |
475 ; X64-NEXT: retq | |
476 ; | |
477 ; X32-LABEL: t15: | |
478 ; X32: # %bb.0: | |
479 ; X32-NEXT: pushq %rbx | |
480 ; X32-NEXT: movl %edi, %ebx | |
481 ; X32-NEXT: callq f | |
482 ; X32-NEXT: movl %ebx, %eax | |
483 ; X32-NEXT: popq %rbx | |
484 ; X32-NEXT: retq | |
316 tail call fastcc void @f(%struct.foo* noalias sret %agg.result) nounwind | 485 tail call fastcc void @f(%struct.foo* noalias sret %agg.result) nounwind |
317 ret void | 486 ret void |
318 } | 487 } |
319 | 488 |
320 declare void @f(%struct.foo* noalias sret) nounwind | 489 declare void @f(%struct.foo* noalias sret) nounwind |
321 | 490 |
322 define void @t16() nounwind ssp { | 491 define void @t16() nounwind ssp { |
323 entry: | 492 ; X86-LABEL: t16: |
324 ; 32-LABEL: t16: | 493 ; X86: # %bb.0: # %entry |
325 ; 32: calll {{_?}}bar4 | 494 ; X86-NEXT: subl $12, %esp |
326 ; 32: fstp | 495 ; X86-NEXT: calll bar4 |
327 | 496 ; X86-NEXT: fstp %st(0) |
328 ; 64-LABEL: t16: | 497 ; X86-NEXT: addl $12, %esp |
329 ; 64: jmp {{_?}}bar4 | 498 ; X86-NEXT: retl |
330 | 499 ; |
331 ; X32ABI-LABEL: t16: | 500 ; X64-LABEL: t16: |
332 ; X32ABI: jmp {{_?}}bar4 | 501 ; X64: # %bb.0: # %entry |
502 ; X64-NEXT: jmp bar4 # TAILCALL | |
503 ; | |
504 ; X32-LABEL: t16: | |
505 ; X32: # %bb.0: # %entry | |
506 ; X32-NEXT: jmp bar4 # TAILCALL | |
507 entry: | |
333 %0 = tail call double @bar4() nounwind | 508 %0 = tail call double @bar4() nounwind |
334 ret void | 509 ret void |
335 } | 510 } |
336 | 511 |
337 declare double @bar4() | 512 declare double @bar4() |
338 | 513 |
339 ; rdar://6283267 | 514 ; rdar://6283267 |
340 define void @t17() nounwind ssp { | 515 define void @t17() nounwind ssp { |
341 entry: | 516 ; X86-LABEL: t17: |
342 ; 32-LABEL: t17: | 517 ; X86: # %bb.0: # %entry |
343 ; 32: jmp {{_?}}bar5 | 518 ; X86-NEXT: jmp bar5 # TAILCALL |
344 | 519 ; |
345 ; 64-LABEL: t17: | 520 ; X64-LABEL: t17: |
346 ; 64: xorl %eax, %eax | 521 ; X64: # %bb.0: # %entry |
347 ; 64: jmp {{_?}}bar5 | 522 ; X64-NEXT: xorl %eax, %eax |
348 | 523 ; X64-NEXT: jmp bar5 # TAILCALL |
349 ; X32ABI-LABEL: t17: | 524 ; |
350 ; X32ABI: xorl %eax, %eax | 525 ; X32-LABEL: t17: |
351 ; X32ABI: jmp {{_?}}bar5 | 526 ; X32: # %bb.0: # %entry |
527 ; X32-NEXT: xorl %eax, %eax | |
528 ; X32-NEXT: jmp bar5 # TAILCALL | |
529 entry: | |
352 tail call void (...) @bar5() nounwind | 530 tail call void (...) @bar5() nounwind |
353 ret void | 531 ret void |
354 } | 532 } |
355 | 533 |
356 declare void @bar5(...) | 534 declare void @bar5(...) |
357 | 535 |
358 ; rdar://7774847 | 536 ; rdar://7774847 |
359 define void @t18() nounwind ssp { | 537 define void @t18() nounwind ssp { |
360 entry: | 538 ; X86-LABEL: t18: |
361 ; 32-LABEL: t18: | 539 ; X86: # %bb.0: # %entry |
362 ; 32: calll {{_?}}bar6 | 540 ; X86-NEXT: subl $12, %esp |
363 ; 32: fstp %st(0) | 541 ; X86-NEXT: calll bar6 |
364 | 542 ; X86-NEXT: fstp %st(0) |
365 ; 64-LABEL: t18: | 543 ; X86-NEXT: addl $12, %esp |
366 ; 64: xorl %eax, %eax | 544 ; X86-NEXT: retl |
367 ; 64: jmp {{_?}}bar6 | 545 ; |
368 | 546 ; X64-LABEL: t18: |
369 ; X32ABI-LABEL: t18: | 547 ; X64: # %bb.0: # %entry |
370 ; X32ABI: xorl %eax, %eax | 548 ; X64-NEXT: xorl %eax, %eax |
371 ; X32ABI: jmp {{_?}}bar6 | 549 ; X64-NEXT: jmp bar6 # TAILCALL |
550 ; | |
551 ; X32-LABEL: t18: | |
552 ; X32: # %bb.0: # %entry | |
553 ; X32-NEXT: xorl %eax, %eax | |
554 ; X32-NEXT: jmp bar6 # TAILCALL | |
555 entry: | |
372 %0 = tail call double (...) @bar6() nounwind | 556 %0 = tail call double (...) @bar6() nounwind |
373 ret void | 557 ret void |
374 } | 558 } |
375 | 559 |
376 declare double @bar6(...) | 560 declare double @bar6(...) |
377 | 561 |
378 define void @t19() alignstack(32) nounwind { | 562 define void @t19() alignstack(32) nounwind { |
379 entry: | 563 ; X86-LABEL: t19: |
380 ; CHECK-LABEL: t19: | 564 ; X86: # %bb.0: # %entry |
381 ; CHECK: andl $-32 | 565 ; X86-NEXT: pushl %ebp |
382 ; CHECK: calll {{_?}}foo | 566 ; X86-NEXT: movl %esp, %ebp |
383 | 567 ; X86-NEXT: andl $-32, %esp |
384 ; X32ABI-LABEL: t19: | 568 ; X86-NEXT: subl $32, %esp |
385 ; X32ABI: andl $-32 | 569 ; X86-NEXT: calll foo |
386 ; X32ABI: callq {{_?}}foo | 570 ; X86-NEXT: movl %ebp, %esp |
571 ; X86-NEXT: popl %ebp | |
572 ; X86-NEXT: retl | |
573 ; | |
574 ; X64-LABEL: t19: | |
575 ; X64: # %bb.0: # %entry | |
576 ; X64-NEXT: pushq %rbp | |
577 ; X64-NEXT: movq %rsp, %rbp | |
578 ; X64-NEXT: andq $-32, %rsp | |
579 ; X64-NEXT: subq $32, %rsp | |
580 ; X64-NEXT: callq foo | |
581 ; X64-NEXT: movq %rbp, %rsp | |
582 ; X64-NEXT: popq %rbp | |
583 ; X64-NEXT: retq | |
584 ; | |
585 ; X32-LABEL: t19: | |
586 ; X32: # %bb.0: # %entry | |
587 ; X32-NEXT: pushq %rbp | |
588 ; X32-NEXT: movl %esp, %ebp | |
589 ; X32-NEXT: andl $-32, %esp | |
590 ; X32-NEXT: subl $32, %esp | |
591 ; X32-NEXT: callq foo | |
592 ; X32-NEXT: movl %ebp, %esp | |
593 ; X32-NEXT: popq %rbp | |
594 ; X32-NEXT: retq | |
595 entry: | |
387 tail call void @foo() nounwind | 596 tail call void @foo() nounwind |
388 ret void | 597 ret void |
389 } | 598 } |
390 | 599 |
391 ; If caller / callee calling convention mismatch then check if the return | 600 ; If caller / callee calling convention mismatch then check if the return |
392 ; values are returned in the same registers. | 601 ; values are returned in the same registers. |
393 ; rdar://7874780 | 602 ; rdar://7874780 |
394 | 603 |
395 define double @t20(double %x) nounwind { | 604 define double @t20(double %x) nounwind { |
396 entry: | 605 ; X86-LABEL: t20: |
397 ; 32-LABEL: t20: | 606 ; X86: # %bb.0: # %entry |
398 ; 32: calll {{_?}}foo20 | 607 ; X86-NEXT: subl $12, %esp |
399 ; 32: fldl (%esp) | 608 ; X86-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero |
400 | 609 ; X86-NEXT: calll foo20 |
401 ; 64-LABEL: t20: | 610 ; X86-NEXT: movsd %xmm0, (%esp) |
402 ; 64: jmp {{_?}}foo20 | 611 ; X86-NEXT: fldl (%esp) |
403 | 612 ; X86-NEXT: addl $12, %esp |
404 ; X32ABI-LABEL: t20: | 613 ; X86-NEXT: retl |
405 ; X32ABI: jmp {{_?}}foo20 | 614 ; |
615 ; X64-LABEL: t20: | |
616 ; X64: # %bb.0: # %entry | |
617 ; X64-NEXT: jmp foo20 # TAILCALL | |
618 ; | |
619 ; X32-LABEL: t20: | |
620 ; X32: # %bb.0: # %entry | |
621 ; X32-NEXT: jmp foo20 # TAILCALL | |
622 entry: | |
406 %0 = tail call fastcc double @foo20(double %x) nounwind | 623 %0 = tail call fastcc double @foo20(double %x) nounwind |
407 ret double %0 | 624 ret double %0 |
408 } | 625 } |
409 | 626 |
410 declare fastcc double @foo20(double) nounwind | 627 declare fastcc double @foo20(double) nounwind |
628 | |
629 ; bug 28417 | |
630 define fastcc void @t21_sret_to_sret(%struct.foo* noalias sret %agg.result) nounwind { | |
631 ; X86-LABEL: t21_sret_to_sret: | |
632 ; X86: # %bb.0: | |
633 ; X86-NEXT: pushl %esi | |
634 ; X86-NEXT: subl $8, %esp | |
635 ; X86-NEXT: movl %ecx, %esi | |
636 ; X86-NEXT: calll t21_f_sret | |
637 ; X86-NEXT: movl %esi, %eax | |
638 ; X86-NEXT: addl $8, %esp | |
639 ; X86-NEXT: popl %esi | |
640 ; X86-NEXT: retl | |
641 ; | |
642 ; X64-LABEL: t21_sret_to_sret: | |
643 ; X64: # %bb.0: | |
644 ; X64-NEXT: pushq %rbx | |
645 ; X64-NEXT: movq %rdi, %rbx | |
646 ; X64-NEXT: callq t21_f_sret | |
647 ; X64-NEXT: movq %rbx, %rax | |
648 ; X64-NEXT: popq %rbx | |
649 ; X64-NEXT: retq | |
650 ; | |
651 ; X32-LABEL: t21_sret_to_sret: | |
652 ; X32: # %bb.0: | |
653 ; X32-NEXT: pushq %rbx | |
654 ; X32-NEXT: movl %edi, %ebx | |
655 ; X32-NEXT: callq t21_f_sret | |
656 ; X32-NEXT: movl %ebx, %eax | |
657 ; X32-NEXT: popq %rbx | |
658 ; X32-NEXT: retq | |
659 tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %agg.result) nounwind | |
660 ret void | |
661 } | |
662 | |
663 define fastcc void @t21_sret_to_sret_alloca(%struct.foo* noalias sret %agg.result) nounwind { | |
664 ; X86-LABEL: t21_sret_to_sret_alloca: | |
665 ; X86: # %bb.0: | |
666 ; X86-NEXT: pushl %esi | |
667 ; X86-NEXT: subl $24, %esp | |
668 ; X86-NEXT: movl %ecx, %esi | |
669 ; X86-NEXT: leal {{[0-9]+}}(%esp), %ecx | |
670 ; X86-NEXT: calll t21_f_sret | |
671 ; X86-NEXT: movl %esi, %eax | |
672 ; X86-NEXT: addl $24, %esp | |
673 ; X86-NEXT: popl %esi | |
674 ; X86-NEXT: retl | |
675 ; | |
676 ; X64-LABEL: t21_sret_to_sret_alloca: | |
677 ; X64: # %bb.0: | |
678 ; X64-NEXT: pushq %rbx | |
679 ; X64-NEXT: subq $16, %rsp | |
680 ; X64-NEXT: movq %rdi, %rbx | |
681 ; X64-NEXT: movq %rsp, %rdi | |
682 ; X64-NEXT: callq t21_f_sret | |
683 ; X64-NEXT: movq %rbx, %rax | |
684 ; X64-NEXT: addq $16, %rsp | |
685 ; X64-NEXT: popq %rbx | |
686 ; X64-NEXT: retq | |
687 ; | |
688 ; X32-LABEL: t21_sret_to_sret_alloca: | |
689 ; X32: # %bb.0: | |
690 ; X32-NEXT: pushq %rbx | |
691 ; X32-NEXT: subl $16, %esp | |
692 ; X32-NEXT: movl %edi, %ebx | |
693 ; X32-NEXT: movl %esp, %edi | |
694 ; X32-NEXT: callq t21_f_sret | |
695 ; X32-NEXT: movl %ebx, %eax | |
696 ; X32-NEXT: addl $16, %esp | |
697 ; X32-NEXT: popq %rbx | |
698 ; X32-NEXT: retq | |
699 %a = alloca %struct.foo, align 8 | |
700 tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %a) nounwind | |
701 ret void | |
702 } | |
703 | |
704 define fastcc void @t21_sret_to_sret_more_args(%struct.foo* noalias sret %agg.result, i32 %a, i32 %b) nounwind { | |
705 ; X86-LABEL: t21_sret_to_sret_more_args: | |
706 ; X86: # %bb.0: | |
707 ; X86-NEXT: pushl %esi | |
708 ; X86-NEXT: subl $8, %esp | |
709 ; X86-NEXT: movl %ecx, %esi | |
710 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax | |
711 ; X86-NEXT: movl %eax, (%esp) | |
712 ; X86-NEXT: calll f_sret | |
713 ; X86-NEXT: movl %esi, %eax | |
714 ; X86-NEXT: addl $8, %esp | |
715 ; X86-NEXT: popl %esi | |
716 ; X86-NEXT: retl | |
717 ; | |
718 ; X64-LABEL: t21_sret_to_sret_more_args: | |
719 ; X64: # %bb.0: | |
720 ; X64-NEXT: pushq %rbx | |
721 ; X64-NEXT: movq %rdi, %rbx | |
722 ; X64-NEXT: callq f_sret | |
723 ; X64-NEXT: movq %rbx, %rax | |
724 ; X64-NEXT: popq %rbx | |
725 ; X64-NEXT: retq | |
726 ; | |
727 ; X32-LABEL: t21_sret_to_sret_more_args: | |
728 ; X32: # %bb.0: | |
729 ; X32-NEXT: pushq %rbx | |
730 ; X32-NEXT: movl %edi, %ebx | |
731 ; X32-NEXT: callq f_sret | |
732 ; X32-NEXT: movl %ebx, %eax | |
733 ; X32-NEXT: popq %rbx | |
734 ; X32-NEXT: retq | |
735 tail call fastcc void @f_sret(%struct.foo* noalias sret %agg.result, i32 %a, i32 %b) nounwind | |
736 ret void | |
737 } | |
738 | |
739 define fastcc void @t21_sret_to_sret_second_arg_sret(%struct.foo* noalias %agg.result, %struct.foo* noalias sret %ret) nounwind { | |
740 ; X86-LABEL: t21_sret_to_sret_second_arg_sret: | |
741 ; X86: # %bb.0: | |
742 ; X86-NEXT: pushl %esi | |
743 ; X86-NEXT: subl $8, %esp | |
744 ; X86-NEXT: movl %edx, %esi | |
745 ; X86-NEXT: movl %edx, %ecx | |
746 ; X86-NEXT: calll t21_f_sret | |
747 ; X86-NEXT: movl %esi, %eax | |
748 ; X86-NEXT: addl $8, %esp | |
749 ; X86-NEXT: popl %esi | |
750 ; X86-NEXT: retl | |
751 ; | |
752 ; X64-LABEL: t21_sret_to_sret_second_arg_sret: | |
753 ; X64: # %bb.0: | |
754 ; X64-NEXT: pushq %rbx | |
755 ; X64-NEXT: movq %rsi, %rbx | |
756 ; X64-NEXT: movq %rsi, %rdi | |
757 ; X64-NEXT: callq t21_f_sret | |
758 ; X64-NEXT: movq %rbx, %rax | |
759 ; X64-NEXT: popq %rbx | |
760 ; X64-NEXT: retq | |
761 ; | |
762 ; X32-LABEL: t21_sret_to_sret_second_arg_sret: | |
763 ; X32: # %bb.0: | |
764 ; X32-NEXT: pushq %rbx | |
765 ; X32-NEXT: movl %esi, %ebx | |
766 ; X32-NEXT: movl %esi, %edi | |
767 ; X32-NEXT: callq t21_f_sret | |
768 ; X32-NEXT: movl %ebx, %eax | |
769 ; X32-NEXT: popq %rbx | |
770 ; X32-NEXT: retq | |
771 tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %ret) nounwind | |
772 ret void | |
773 } | |
774 | |
775 define fastcc void @t21_sret_to_sret_more_args2(%struct.foo* noalias sret %agg.result, i32 %a, i32 %b) nounwind { | |
776 ; X86-LABEL: t21_sret_to_sret_more_args2: | |
777 ; X86: # %bb.0: | |
778 ; X86-NEXT: pushl %esi | |
779 ; X86-NEXT: subl $8, %esp | |
780 ; X86-NEXT: movl %ecx, %esi | |
781 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax | |
782 ; X86-NEXT: movl %edx, (%esp) | |
783 ; X86-NEXT: movl %eax, %edx | |
784 ; X86-NEXT: calll f_sret | |
785 ; X86-NEXT: movl %esi, %eax | |
786 ; X86-NEXT: addl $8, %esp | |
787 ; X86-NEXT: popl %esi | |
788 ; X86-NEXT: retl | |
789 ; | |
790 ; X64-LABEL: t21_sret_to_sret_more_args2: | |
791 ; X64: # %bb.0: | |
792 ; X64-NEXT: pushq %rbx | |
793 ; X64-NEXT: movl %esi, %eax | |
794 ; X64-NEXT: movq %rdi, %rbx | |
795 ; X64-NEXT: movl %edx, %esi | |
796 ; X64-NEXT: movl %eax, %edx | |
797 ; X64-NEXT: callq f_sret | |
798 ; X64-NEXT: movq %rbx, %rax | |
799 ; X64-NEXT: popq %rbx | |
800 ; X64-NEXT: retq | |
801 ; | |
802 ; X32-LABEL: t21_sret_to_sret_more_args2: | |
803 ; X32: # %bb.0: | |
804 ; X32-NEXT: pushq %rbx | |
805 ; X32-NEXT: movl %esi, %eax | |
806 ; X32-NEXT: movl %edi, %ebx | |
807 ; X32-NEXT: movl %edx, %esi | |
808 ; X32-NEXT: movl %eax, %edx | |
809 ; X32-NEXT: callq f_sret | |
810 ; X32-NEXT: movl %ebx, %eax | |
811 ; X32-NEXT: popq %rbx | |
812 ; X32-NEXT: retq | |
813 tail call fastcc void @f_sret(%struct.foo* noalias sret %agg.result, i32 %b, i32 %a) nounwind | |
814 ret void | |
815 } | |
816 | |
817 | |
818 define fastcc void @t21_sret_to_sret_args_mismatch(%struct.foo* noalias sret %agg.result, %struct.foo* noalias %ret) nounwind { | |
819 ; X86-LABEL: t21_sret_to_sret_args_mismatch: | |
820 ; X86: # %bb.0: | |
821 ; X86-NEXT: pushl %esi | |
822 ; X86-NEXT: subl $8, %esp | |
823 ; X86-NEXT: movl %ecx, %esi | |
824 ; X86-NEXT: movl %edx, %ecx | |
825 ; X86-NEXT: calll t21_f_sret | |
826 ; X86-NEXT: movl %esi, %eax | |
827 ; X86-NEXT: addl $8, %esp | |
828 ; X86-NEXT: popl %esi | |
829 ; X86-NEXT: retl | |
830 ; | |
831 ; X64-LABEL: t21_sret_to_sret_args_mismatch: | |
832 ; X64: # %bb.0: | |
833 ; X64-NEXT: pushq %rbx | |
834 ; X64-NEXT: movq %rdi, %rbx | |
835 ; X64-NEXT: movq %rsi, %rdi | |
836 ; X64-NEXT: callq t21_f_sret | |
837 ; X64-NEXT: movq %rbx, %rax | |
838 ; X64-NEXT: popq %rbx | |
839 ; X64-NEXT: retq | |
840 ; | |
841 ; X32-LABEL: t21_sret_to_sret_args_mismatch: | |
842 ; X32: # %bb.0: | |
843 ; X32-NEXT: pushq %rbx | |
844 ; X32-NEXT: movl %edi, %ebx | |
845 ; X32-NEXT: movl %esi, %edi | |
846 ; X32-NEXT: callq t21_f_sret | |
847 ; X32-NEXT: movl %ebx, %eax | |
848 ; X32-NEXT: popq %rbx | |
849 ; X32-NEXT: retq | |
850 tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %ret) nounwind | |
851 ret void | |
852 } | |
853 | |
854 define fastcc void @t21_sret_to_sret_args_mismatch2(%struct.foo* noalias sret %agg.result, %struct.foo* noalias %ret) nounwind { | |
855 ; X86-LABEL: t21_sret_to_sret_args_mismatch2: | |
856 ; X86: # %bb.0: | |
857 ; X86-NEXT: pushl %esi | |
858 ; X86-NEXT: subl $8, %esp | |
859 ; X86-NEXT: movl %ecx, %esi | |
860 ; X86-NEXT: movl %edx, %ecx | |
861 ; X86-NEXT: calll t21_f_sret | |
862 ; X86-NEXT: movl %esi, %eax | |
863 ; X86-NEXT: addl $8, %esp | |
864 ; X86-NEXT: popl %esi | |
865 ; X86-NEXT: retl | |
866 ; | |
867 ; X64-LABEL: t21_sret_to_sret_args_mismatch2: | |
868 ; X64: # %bb.0: | |
869 ; X64-NEXT: pushq %rbx | |
870 ; X64-NEXT: movq %rdi, %rbx | |
871 ; X64-NEXT: movq %rsi, %rdi | |
872 ; X64-NEXT: callq t21_f_sret | |
873 ; X64-NEXT: movq %rbx, %rax | |
874 ; X64-NEXT: popq %rbx | |
875 ; X64-NEXT: retq | |
876 ; | |
877 ; X32-LABEL: t21_sret_to_sret_args_mismatch2: | |
878 ; X32: # %bb.0: | |
879 ; X32-NEXT: pushq %rbx | |
880 ; X32-NEXT: movl %edi, %ebx | |
881 ; X32-NEXT: movl %esi, %edi | |
882 ; X32-NEXT: callq t21_f_sret | |
883 ; X32-NEXT: movl %ebx, %eax | |
884 ; X32-NEXT: popq %rbx | |
885 ; X32-NEXT: retq | |
886 tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %ret) nounwind | |
887 ret void | |
888 } | |
889 | |
890 define fastcc void @t21_sret_to_sret_arg_mismatch(%struct.foo* noalias sret %agg.result) nounwind { | |
891 ; X86-LABEL: t21_sret_to_sret_arg_mismatch: | |
892 ; X86: # %bb.0: | |
893 ; X86-NEXT: pushl %esi | |
894 ; X86-NEXT: subl $8, %esp | |
895 ; X86-NEXT: movl %ecx, %esi | |
896 ; X86-NEXT: calll ret_struct | |
897 ; X86-NEXT: movl %eax, %ecx | |
898 ; X86-NEXT: calll t21_f_sret | |
899 ; X86-NEXT: movl %esi, %eax | |
900 ; X86-NEXT: addl $8, %esp | |
901 ; X86-NEXT: popl %esi | |
902 ; X86-NEXT: retl | |
903 ; | |
904 ; X64-LABEL: t21_sret_to_sret_arg_mismatch: | |
905 ; X64: # %bb.0: | |
906 ; X64-NEXT: pushq %rbx | |
907 ; X64-NEXT: movq %rdi, %rbx | |
908 ; X64-NEXT: callq ret_struct | |
909 ; X64-NEXT: movq %rax, %rdi | |
910 ; X64-NEXT: callq t21_f_sret | |
911 ; X64-NEXT: movq %rbx, %rax | |
912 ; X64-NEXT: popq %rbx | |
913 ; X64-NEXT: retq | |
914 ; | |
915 ; X32-LABEL: t21_sret_to_sret_arg_mismatch: | |
916 ; X32: # %bb.0: | |
917 ; X32-NEXT: pushq %rbx | |
918 ; X32-NEXT: movl %edi, %ebx | |
919 ; X32-NEXT: callq ret_struct | |
920 ; X32-NEXT: movl %eax, %edi | |
921 ; X32-NEXT: callq t21_f_sret | |
922 ; X32-NEXT: movl %ebx, %eax | |
923 ; X32-NEXT: popq %rbx | |
924 ; X32-NEXT: retq | |
925 %a = call fastcc %struct.foo* @ret_struct() | |
926 tail call fastcc void @t21_f_sret(%struct.foo* noalias sret %a) nounwind | |
927 ret void | |
928 } | |
929 | |
930 define fastcc void @t21_sret_to_sret_structs_mismatch(%struct.foo* noalias sret %agg.result, %struct.foo* noalias %a) nounwind { | |
931 ; X86-LABEL: t21_sret_to_sret_structs_mismatch: | |
932 ; X86: # %bb.0: | |
933 ; X86-NEXT: pushl %edi | |
934 ; X86-NEXT: pushl %esi | |
935 ; X86-NEXT: pushl %eax | |
936 ; X86-NEXT: movl %edx, %esi | |
937 ; X86-NEXT: movl %ecx, %edi | |
938 ; X86-NEXT: calll ret_struct | |
939 ; X86-NEXT: movl %esi, %ecx | |
940 ; X86-NEXT: movl %eax, %edx | |
941 ; X86-NEXT: calll t21_f_sret2 | |
942 ; X86-NEXT: movl %edi, %eax | |
943 ; X86-NEXT: addl $4, %esp | |
944 ; X86-NEXT: popl %esi | |
945 ; X86-NEXT: popl %edi | |
946 ; X86-NEXT: retl | |
947 ; | |
948 ; X64-LABEL: t21_sret_to_sret_structs_mismatch: | |
949 ; X64: # %bb.0: | |
950 ; X64-NEXT: pushq %r14 | |
951 ; X64-NEXT: pushq %rbx | |
952 ; X64-NEXT: pushq %rax | |
953 ; X64-NEXT: movq %rsi, %rbx | |
954 ; X64-NEXT: movq %rdi, %r14 | |
955 ; X64-NEXT: callq ret_struct | |
956 ; X64-NEXT: movq %rbx, %rdi | |
957 ; X64-NEXT: movq %rax, %rsi | |
958 ; X64-NEXT: callq t21_f_sret2 | |
959 ; X64-NEXT: movq %r14, %rax | |
960 ; X64-NEXT: addq $8, %rsp | |
961 ; X64-NEXT: popq %rbx | |
962 ; X64-NEXT: popq %r14 | |
963 ; X64-NEXT: retq | |
964 ; | |
965 ; X32-LABEL: t21_sret_to_sret_structs_mismatch: | |
966 ; X32: # %bb.0: | |
967 ; X32-NEXT: pushq %rbp | |
968 ; X32-NEXT: pushq %rbx | |
969 ; X32-NEXT: pushq %rax | |
970 ; X32-NEXT: movl %esi, %ebx | |
971 ; X32-NEXT: movl %edi, %ebp | |
972 ; X32-NEXT: callq ret_struct | |
973 ; X32-NEXT: movl %ebx, %edi | |
974 ; X32-NEXT: movl %eax, %esi | |
975 ; X32-NEXT: callq t21_f_sret2 | |
976 ; X32-NEXT: movl %ebp, %eax | |
977 ; X32-NEXT: addl $8, %esp | |
978 ; X32-NEXT: popq %rbx | |
979 ; X32-NEXT: popq %rbp | |
980 ; X32-NEXT: retq | |
981 %b = call fastcc %struct.foo* @ret_struct() | |
982 tail call fastcc void @t21_f_sret2(%struct.foo* noalias sret %a, %struct.foo* noalias %b) nounwind | |
983 ret void | |
984 } | |
985 | |
986 declare ccc %struct.foo* @ret_struct() nounwind | |
987 | |
988 | |
989 define fastcc void @t21_sret_to_non_sret(%struct.foo* noalias sret %agg.result) nounwind { | |
990 ; X86-LABEL: t21_sret_to_non_sret: | |
991 ; X86: # %bb.0: | |
992 ; X86-NEXT: pushl %esi | |
993 ; X86-NEXT: subl $8, %esp | |
994 ; X86-NEXT: movl %ecx, %esi | |
995 ; X86-NEXT: calll t21_f_non_sret | |
996 ; X86-NEXT: movl %esi, %eax | |
997 ; X86-NEXT: addl $8, %esp | |
998 ; X86-NEXT: popl %esi | |
999 ; X86-NEXT: retl | |
1000 ; | |
1001 ; X64-LABEL: t21_sret_to_non_sret: | |
1002 ; X64: # %bb.0: | |
1003 ; X64-NEXT: pushq %rbx | |
1004 ; X64-NEXT: movq %rdi, %rbx | |
1005 ; X64-NEXT: callq t21_f_non_sret | |
1006 ; X64-NEXT: movq %rbx, %rax | |
1007 ; X64-NEXT: popq %rbx | |
1008 ; X64-NEXT: retq | |
1009 ; | |
1010 ; X32-LABEL: t21_sret_to_non_sret: | |
1011 ; X32: # %bb.0: | |
1012 ; X32-NEXT: pushq %rbx | |
1013 ; X32-NEXT: movl %edi, %ebx | |
1014 ; X32-NEXT: callq t21_f_non_sret | |
1015 ; X32-NEXT: movl %ebx, %eax | |
1016 ; X32-NEXT: popq %rbx | |
1017 ; X32-NEXT: retq | |
1018 tail call fastcc void @t21_f_non_sret(%struct.foo* %agg.result) nounwind | |
1019 ret void | |
1020 } | |
1021 | |
1022 | |
1023 define ccc void @t22_non_sret_to_sret(%struct.foo* %agg.result) nounwind { | |
1024 ; X86-LABEL: t22_non_sret_to_sret: | |
1025 ; X86: # %bb.0: | |
1026 ; X86-NEXT: subl $12, %esp | |
1027 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax | |
1028 ; X86-NEXT: movl %eax, (%esp) | |
1029 ; X86-NEXT: calll t22_f_sret | |
1030 ; X86-NEXT: addl $8, %esp | |
1031 ; X86-NEXT: retl | |
1032 ; | |
1033 ; X64-LABEL: t22_non_sret_to_sret: | |
1034 ; X64: # %bb.0: | |
1035 ; X64-NEXT: pushq %rax | |
1036 ; X64-NEXT: callq t22_f_sret | |
1037 ; X64-NEXT: popq %rax | |
1038 ; X64-NEXT: retq | |
1039 ; | |
1040 ; X32-LABEL: t22_non_sret_to_sret: | |
1041 ; X32: # %bb.0: | |
1042 ; X32-NEXT: pushq %rax | |
1043 ; X32-NEXT: callq t22_f_sret | |
1044 ; X32-NEXT: popq %rax | |
1045 ; X32-NEXT: retq | |
1046 tail call ccc void @t22_f_sret(%struct.foo* noalias sret %agg.result) nounwind | |
1047 ret void | |
1048 } | |
1049 | |
1050 declare fastcc void @t21_f_sret(%struct.foo* noalias sret) nounwind | |
1051 declare fastcc void @t21_f_sret2(%struct.foo* noalias sret, %struct.foo* noalias) nounwind | |
1052 declare fastcc void @t21_f_non_sret(%struct.foo*) nounwind | |
1053 | |
1054 declare ccc void @t22_f_sret(%struct.foo* noalias sret) nounwind | |
1055 | |
1056 declare ccc void @f_sret(%struct.foo* noalias sret, i32, i32) nounwind |