]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/AMDGPU/rewrite-out-arguments.ll
Vendor import of llvm trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / test / CodeGen / AMDGPU / rewrite-out-arguments.ll
1 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-rewrite-out-arguments < %s | FileCheck %s
2
3 ; CHECK: %void_one_out_arg_i32_1_use = type { i32 }
4 ; CHECK: %void_one_out_arg_i32_1_use_align = type { i32 }
5 ; CHECK: %void_one_out_arg_i32_2_use = type { i32 }
6 ; CHECK: %void_one_out_arg_i32_2_stores = type { i32 }
7 ; CHECK: %void_one_out_arg_i32_2_stores_clobber = type { i32 }
8 ; CHECK: %void_one_out_arg_i32_pre_call_may_clobber = type { i32 }
9 ; CHECK: %void_one_out_arg_v2i32_1_use = type { <2 x i32> }
10 ; CHECK: %void_one_out_arg_struct_1_use = type { %struct }
11 ; CHECK: %struct = type { i32, i8, float }
12 ; CHECK: %i32_one_out_arg_i32_1_use = type { i32, i32 }
13 ; CHECK: %unused_different_type = type { float }
14 ; CHECK: %multiple_same_return_noalias = type { i32, i32 }
15 ; CHECK: %multiple_same_return_mayalias = type { i32, i32 }
16 ; CHECK: %multiple_same_return_mayalias_order = type { i32, i32 }
17 ; CHECK: %i1_one_out_arg_i32_1_use = type { i1, i32 }
18 ; CHECK: %i1_zeroext_one_out_arg_i32_1_use = type { i1, i32 }
19 ; CHECK: %i1_signext_one_out_arg_i32_1_use = type { i1, i32 }
20 ; CHECK: %p1i32_noalias_one_out_arg_i32_1_use = type { i32 addrspace(1)*, i32 }
21 ; CHECK: %func_ptr_type = type { void ()* }
22 ; CHECK: %bitcast_func_ptr_type = type { void ()* }
23 ; CHECK: %out_arg_small_array = type { [4 x i32] }
24 ; CHECK: %num_regs_reach_limit = type { [15 x i32], i32 }
25 ; CHECK: %num_regs_reach_limit_leftover = type { [15 x i32], i32, i32 }
26 ; CHECK: %preserve_debug_info = type { i32 }
27 ; CHECK: %preserve_metadata = type { i32 }
28 ; CHECK: %bitcast_pointer_v4i32_v3i32 = type { <3 x i32> }
29 ; CHECK: %bitcast_pointer_v4i32_v3f32 = type { <3 x float> }
30 ; CHECK: %bitcast_pointer_i32_f32 = type { float }
31 ; CHECK: %bitcast_struct_v3f32_v3f32 = type { %struct.v3f32 }
32 ; CHECK: %struct.v3f32 = type { <3 x float> }
33 ; CHECK: %bitcast_struct_v3f32_v3i32 = type { %struct.v3f32 }
34 ; CHECK: %bitcast_struct_v4f32_v4f32 = type { %struct.v4f32 }
35 ; CHECK: %struct.v4f32 = type { <4 x float> }
36 ; CHECK: %bitcast_struct_v3f32_v4i32 = type { %struct.v3f32 }
37 ; CHECK: %bitcast_struct_v4f32_v3f32 = type { %struct.v4f32 }
38 ; CHECK: %struct.v3f32.f32 = type { <3 x float>, float }
39 ; CHECK: %bitcast_struct_i128_v4f32 = type { %struct.i128 }
40 ; CHECK: %struct.i128 = type { i128 }
41 ; CHECK: %multi_return_bitcast_struct_v3f32_v3f32 = type { %struct.v3f32 }
42
43 ; CHECK-LABEL: define void @no_ret_blocks() #0 {
44 ; CHECK-NEXT: unreachable
45 define void @no_ret_blocks() #0 {
46   unreachable
47 }
48
49 ; CHECK-LABEL: @void_one_out_arg_i32_no_use(
50 ; CHECK-NEXT: ret void
51 define void @void_one_out_arg_i32_no_use(i32* %val) #0 {
52   ret void
53 }
54
55 ; CHECK-NOT: define
56 ; CHECK-LABEL: define void @skip_byval_arg(
57 ; CHECK-NEXT: store i32 0, i32* %val
58 ; CHECK-NEXT: ret void
59 define void @skip_byval_arg(i32* byval %val) #0 {
60   store i32 0, i32* %val
61   ret void
62 }
63
64 ; CHECK-NOT: define
65 ; CHECK-LABEL: define void @skip_optnone(
66 ; CHECK-NEXT: store i32 0, i32* %val
67 ; CHECK-NEXT: ret void
68 define void @skip_optnone(i32* byval %val) #1 {
69   store i32 0, i32* %val
70   ret void
71 }
72
73 ; CHECK-NOT: define
74 ; CHECK-LABEL: define void @skip_volatile(
75 ; CHECK-NEXT: store volatile i32 0, i32* %val
76 ; CHECK-NEXT: ret void
77 define void @skip_volatile(i32* byval %val) #0 {
78   store volatile i32 0, i32* %val
79   ret void
80 }
81
82 ; CHECK-NOT: define
83 ; CHECK-LABEL: define void @skip_atomic(
84 ; CHECK-NEXT: store atomic i32 0, i32* %val
85 ; CHECK-NEXT: ret void
86 define void @skip_atomic(i32* byval %val) #0 {
87   store atomic i32 0, i32* %val seq_cst, align 4
88   ret void
89 }
90
91 ; CHECK-NOT: define
92 ; CHECK-LABEL: define void @skip_store_pointer_val(
93 ; CHECK-NEXT: store i32* %val, i32** undef
94 ; CHECK-NEXT: ret void
95 define void @skip_store_pointer_val(i32* %val) #0 {
96   store i32* %val, i32** undef
97   ret void
98 }
99
100 ; CHECK-NOT: define
101 ; CHECK-LABEL: define void @skip_store_gep(
102 ; CHECK-NEXT: %gep = getelementptr inbounds i32, i32* %val, i32 1
103 ; CHECK-NEXT: store i32 0, i32* %gep
104 ; CHECK-NEXT: ret void
105 define void @skip_store_gep(i32* %val) #0 {
106   %gep = getelementptr inbounds i32, i32* %val, i32 1
107   store i32 0, i32* %gep
108   ret void
109 }
110
111 ; CHECK-LABEL: define void @skip_sret(i32* sret %sret, i32* %out) #0 {
112 ; CHECK-NEXT: store
113 ; CHECK-NEXT: store
114 ; CHECK-NEXT: ret void
115 define void @skip_sret(i32* sret %sret, i32* %out) #0 {
116   store i32 1, i32* %sret
117   store i32 0, i32* %out
118   ret void
119 }
120
121 ; CHECK-LABEL: define private %void_one_out_arg_i32_1_use @void_one_out_arg_i32_1_use.body(i32* %val) #0 {
122 ; CHECK-NEXT: ret %void_one_out_arg_i32_1_use zeroinitializer
123
124 ; CHECK-LABEL: @void_one_out_arg_i32_1_use(
125 ; CHECK-NEXT: %2 = call %void_one_out_arg_i32_1_use @void_one_out_arg_i32_1_use.body(i32* undef)
126 ; CHECK-NEXT: %3 = extractvalue %void_one_out_arg_i32_1_use %2, 0
127 ; CHECK-NEXT: store i32 %3, i32* %0, align 4
128 ; CHECK-NEXT: ret void
129 define void @void_one_out_arg_i32_1_use(i32* %val) #0 {
130   store i32 0, i32* %val
131   ret void
132 }
133
134 ; CHECK-LABEL: define private %void_one_out_arg_i32_1_use_align @void_one_out_arg_i32_1_use_align.body(i32* align 8 %val) #0 {
135 ; CHECK-NEXT: ret %void_one_out_arg_i32_1_use_align zeroinitializer
136
137 ; CHECK-LABEL: @void_one_out_arg_i32_1_use_align(
138 ; CHECK-NEXT: %2 = call %void_one_out_arg_i32_1_use_align @void_one_out_arg_i32_1_use_align.body(i32* undef)
139 ; CHECK-NEXT: %3 = extractvalue %void_one_out_arg_i32_1_use_align %2, 0
140 ; CHECK-NEXT: store i32 %3, i32* %0, align 8
141 ; CHECK-NEXT: ret void
142 define void @void_one_out_arg_i32_1_use_align(i32* align 8 %val) #0 {
143   store i32 0, i32* %val, align 8
144   ret void
145 }
146
147 ; CHECK-LABEL: define private %void_one_out_arg_i32_2_use @void_one_out_arg_i32_2_use.body(i1 %arg0, i32* %val) #0 {
148 ; CHECK: br i1 %arg0, label %ret0, label %ret1
149
150 ; CHECK: ret0:
151 ; CHECK-NEXT: ret %void_one_out_arg_i32_2_use zeroinitializer
152
153 ; CHECK: ret1:
154 ; CHECK-NEXT: ret %void_one_out_arg_i32_2_use { i32 9 }
155
156 ; CHECK-LABEL: define void @void_one_out_arg_i32_2_use(i1, i32*) #2 {
157 ; CHECK-NEXT: %3 = call %void_one_out_arg_i32_2_use @void_one_out_arg_i32_2_use.body(i1 %0, i32* undef)
158 ; CHECK-NEXT: %4 = extractvalue %void_one_out_arg_i32_2_use %3, 0
159 ; CHECK-NEXT: store i32 %4, i32* %1, align 4
160 ; CHECK-NEXT: ret void
161 define void @void_one_out_arg_i32_2_use(i1 %arg0, i32* %val) #0 {
162   br i1 %arg0, label %ret0, label %ret1
163
164 ret0:
165   store i32 0, i32* %val
166   ret void
167
168 ret1:
169   store i32 9, i32* %val
170   ret void
171 }
172
173 declare void @may.clobber()
174
175 ; CHECK-LABEL: define private %void_one_out_arg_i32_2_stores @void_one_out_arg_i32_2_stores.body(i32* %val) #0 {
176 ; CHECK-NEXT: store i32 0, i32* %val
177 ; CHECK-NEXT: ret %void_one_out_arg_i32_2_stores { i32 1 }
178
179 ; CHECK-LABEL: define void @void_one_out_arg_i32_2_stores(i32*) #2 {
180 ; CHECK-NEXT: %2 = call %void_one_out_arg_i32_2_stores @void_one_out_arg_i32_2_stores.body(i32* undef)
181 ; CHECK-NEXT: %3 = extractvalue %void_one_out_arg_i32_2_stores %2, 0
182 ; CHECK-NEXT: store i32 %3, i32* %0, align 4
183 define void @void_one_out_arg_i32_2_stores(i32* %val) #0 {
184   store i32 0, i32* %val
185   store i32 1, i32* %val
186   ret void
187 }
188
189 ; CHECK-LABEL: define private %void_one_out_arg_i32_2_stores_clobber @void_one_out_arg_i32_2_stores_clobber.body(i32* %val) #0 {
190 ; CHECK-NEXT: store i32 0, i32* %val
191 ; CHECK-NEXT: call void @may.clobber()
192 ; CHECK-NEXT: ret %void_one_out_arg_i32_2_stores_clobber { i32 1 }
193
194 ; CHECK-LABEL: define void @void_one_out_arg_i32_2_stores_clobber(i32*) #2 {
195 ; CHECK-NEXT: %2 = call %void_one_out_arg_i32_2_stores_clobber @void_one_out_arg_i32_2_stores_clobber.body(i32* undef)
196 ; CHECK-NEXT: %3 = extractvalue %void_one_out_arg_i32_2_stores_clobber %2, 0
197 ; CHECK-NEXT: store i32 %3, i32* %0, align 4
198 ; CHECK-NEXT: ret void
199 define void @void_one_out_arg_i32_2_stores_clobber(i32* %val) #0 {
200   store i32 0, i32* %val
201   call void @may.clobber()
202   store i32 1, i32* %val
203   ret void
204 }
205
206 ; CHECK-NOT: define
207
208 ; CHECK-LABEL: define void @void_one_out_arg_i32_call_may_clobber(i32* %val) #0 {
209 ; CHECK-NEXT: store i32 0, i32* %val
210 ; CHECK-NEXT: call void @may.clobber()
211 ; CHECK-NEXT: ret void
212 define void @void_one_out_arg_i32_call_may_clobber(i32* %val) #0 {
213   store i32 0, i32* %val
214   call void @may.clobber()
215   ret void
216 }
217
218 ; CHECK-LABEL: define private %void_one_out_arg_i32_pre_call_may_clobber @void_one_out_arg_i32_pre_call_may_clobber.body(i32* %val) #0 {
219 ; CHECK-NEXT: call void @may.clobber()
220 ; CHECK-NEXT: ret %void_one_out_arg_i32_pre_call_may_clobber zeroinitializer
221
222 ; CHECK-LABEL: @void_one_out_arg_i32_pre_call_may_clobber(i32*) #2 {
223 ; CHECK-NEXT: %2 = call %void_one_out_arg_i32_pre_call_may_clobber @void_one_out_arg_i32_pre_call_may_clobber.body(i32* undef)
224 ; CHECK-NEXT: %3 = extractvalue %void_one_out_arg_i32_pre_call_may_clobber %2, 0
225 ; CHECK-NEXT: store i32 %3, i32* %0, align 4
226 ; CHECK-NEXT: ret void
227 define void @void_one_out_arg_i32_pre_call_may_clobber(i32* %val) #0 {
228   call void @may.clobber()
229   store i32 0, i32* %val
230   ret void
231 }
232
233 ; CHECK-LABEL: define void @void_one_out_arg_i32_reload(i32* %val) #0 {
234 ; CHECK: store i32 0, i32* %val
235 ; CHECK: %load = load i32, i32* %val, align 4
236 ; CHECK: ret void
237 define void @void_one_out_arg_i32_reload(i32* %val) #0 {
238   store i32 0, i32* %val
239   %load = load i32, i32* %val, align 4
240   ret void
241 }
242
243 ; CHECK-NOT: define
244 ; CHECK-LABEL: define void @void_one_out_arg_i32_store_in_different_block(
245 ; CHECK-NEXT: %load = load i32, i32 addrspace(1)* undef
246 ; CHECK-NEXT: store i32 0, i32* %out
247 ; CHECK-NEXT: br label %ret
248 ; CHECK: ret:
249 ; CHECK-NEXT: ret void
250 define void @void_one_out_arg_i32_store_in_different_block(i32* %out) #0 {
251   %load = load i32, i32 addrspace(1)* undef
252   store i32 0, i32* %out
253   br label %ret
254
255 ret:
256   ret void
257 }
258
259 ; CHECK-NOT: define
260 ; CHECK-LABEL: define void @unused_out_arg_one_branch(
261 ; CHECK: ret0:
262 ; CHECK-NEXT: ret void
263
264 ; CHECK: ret1:
265 ; CHECK-NEXT: store i32 9, i32* %val
266 ; CHECK-NEXT: ret void
267 define void @unused_out_arg_one_branch(i1 %arg0, i32* %val) #0 {
268   br i1 %arg0, label %ret0, label %ret1
269
270 ret0:
271   ret void
272
273 ret1:
274   store i32 9, i32* %val
275   ret void
276 }
277
278 ; CHECK-LABEL: define private %void_one_out_arg_v2i32_1_use @void_one_out_arg_v2i32_1_use.body(<2 x i32>* %val) #0 {
279 ; CHECK-NEXT: ret %void_one_out_arg_v2i32_1_use { <2 x i32> <i32 17, i32 9> }
280
281 ; CHECK-LABEL: define void @void_one_out_arg_v2i32_1_use(<2 x i32>*) #2 {
282 ; CHECK-NEXT: %2 = call %void_one_out_arg_v2i32_1_use @void_one_out_arg_v2i32_1_use.body(<2 x i32>* undef)
283 ; CHECK-NEXT: %3 = extractvalue %void_one_out_arg_v2i32_1_use %2, 0
284 ; CHECK-NEXT: store <2 x i32> %3, <2 x i32>* %0, align 8
285 ; CHCEK-NEXT: ret void
286 define void @void_one_out_arg_v2i32_1_use(<2 x i32>* %val) #0 {
287   store <2 x i32> <i32 17, i32 9>, <2 x i32>* %val
288   ret void
289 }
290
291 %struct = type { i32, i8, float }
292
293 ; CHECK-LABEL: define private %void_one_out_arg_struct_1_use @void_one_out_arg_struct_1_use.body(%struct* %out) #0 {
294 ; CHECK-NEXT: ret %void_one_out_arg_struct_1_use { %struct { i32 9, i8 99, float 4.000000e+00 } }
295
296 ; Normally this is split into element accesses which we don't handle.
297 ; CHECK-LABEL: define void @void_one_out_arg_struct_1_use(%struct*) #2 {
298 ; CHECK-NEXT: %2 = call %void_one_out_arg_struct_1_use @void_one_out_arg_struct_1_use.body(%struct* undef)
299 ; CHECK-NEXT: %3 = extractvalue %void_one_out_arg_struct_1_use %2, 0
300 ; CHECK-NEXT: store %struct %3, %struct* %0, align 4
301 ; CHECK-NEXT: ret void
302 define void @void_one_out_arg_struct_1_use(%struct* %out) #0 {
303   store %struct { i32 9, i8 99, float 4.0 }, %struct* %out
304   ret void
305 }
306
307 ; CHECK-LABEL: define private %i32_one_out_arg_i32_1_use @i32_one_out_arg_i32_1_use.body(i32* %val) #0 {
308 ; CHECK-NEXT: ret %i32_one_out_arg_i32_1_use { i32 9, i32 24 }
309
310 ; CHECK-LABEL: define i32 @i32_one_out_arg_i32_1_use(i32*) #2 {
311 ; CHECK-NEXT: %2 = call %i32_one_out_arg_i32_1_use @i32_one_out_arg_i32_1_use.body(i32* undef)
312 ; CHECK-NEXT: %3 = extractvalue %i32_one_out_arg_i32_1_use %2, 1
313 ; CHECK-NEXT: store i32 %3, i32* %0, align 4
314 ; CHECK-NEXT: %4 = extractvalue %i32_one_out_arg_i32_1_use %2, 0
315 ; CHECK-NEXT: ret i32 %4
316 define i32 @i32_one_out_arg_i32_1_use(i32* %val) #0 {
317   store i32 24, i32* %val
318   ret i32 9
319 }
320
321 ; CHECK-LABEL: define private %unused_different_type @unused_different_type.body(i32* %arg0, float* nocapture %arg1) #0 {
322 ; CHECK-NEXT: ret %unused_different_type { float 4.000000e+00 }
323
324 ; CHECK-LABEL: define void @unused_different_type(i32*, float* nocapture) #2 {
325 ; CHECK-NEXT: %3 = call %unused_different_type @unused_different_type.body(i32* %0, float* undef)
326 ; CHECK-NEXT: %4 = extractvalue %unused_different_type %3, 0
327 ; CHECK-NEXT: store float %4, float* %1, align 4
328 ; CHECK-NEXT  ret void
329 define void @unused_different_type(i32* %arg0, float* nocapture %arg1) #0 {
330   store float 4.0, float* %arg1, align 4
331   ret void
332 }
333
334 ; CHECK-LABEL: define private %multiple_same_return_noalias @multiple_same_return_noalias.body(i32* noalias %out0, i32* noalias %out1) #0 {
335 ; CHECK-NEXT: ret %multiple_same_return_noalias { i32 1, i32 2 }
336
337 ; CHECK-LABEL: define void @multiple_same_return_noalias(
338 ; CHECK-NEXT: %3 = call %multiple_same_return_noalias @multiple_same_return_noalias.body(i32* undef, i32* undef)
339 ; CHECK-NEXT: %4 = extractvalue %multiple_same_return_noalias %3, 0
340 ; CHECK-NEXT: store i32 %4, i32* %0, align 4
341 ; CHECK-NEXT: %5 = extractvalue %multiple_same_return_noalias %3, 1
342 ; CHECK-NEXT: store i32 %5, i32* %1, align 4
343 ; CHECK-NEXT: ret void
344 define void @multiple_same_return_noalias(i32* noalias %out0, i32* noalias %out1) #0 {
345   store i32 1, i32* %out0, align 4
346   store i32 2, i32* %out1, align 4
347   ret void
348 }
349
350 ; CHECK-LABEL: define private %multiple_same_return_mayalias @multiple_same_return_mayalias.body(i32* %out0, i32* %out1) #0 {
351 ; CHECK-NEXT: ret %multiple_same_return_mayalias { i32 2, i32 1 }
352
353 ; CHECK-LABEL: define void @multiple_same_return_mayalias(i32*, i32*) #2 {
354 ; CHECK-NEXT: %3 = call %multiple_same_return_mayalias @multiple_same_return_mayalias.body(i32* undef, i32* undef)
355 ; CHECK-NEXT: %4 = extractvalue %multiple_same_return_mayalias %3, 0
356 ; CHECK-NEXT: store i32 %4, i32* %0, align 4
357 ; CHECK-NEXT: %5 = extractvalue %multiple_same_return_mayalias %3, 1
358 ; CHECK-NEXT: store i32 %5, i32* %1, align 4
359 ; CHECK-NEXT: ret void
360 define void @multiple_same_return_mayalias(i32* %out0, i32* %out1) #0 {
361  store i32 1, i32* %out0, align 4
362  store i32 2, i32* %out1, align 4
363  ret void
364 }
365
366 ; CHECK-LABEL: define private %multiple_same_return_mayalias_order @multiple_same_return_mayalias_order.body(i32* %out0, i32* %out1) #0 {
367 ; CHECK-NEXT: ret %multiple_same_return_mayalias_order { i32 1, i32 2 }
368
369 ; CHECK-LABEL: define void @multiple_same_return_mayalias_order(i32*, i32*) #2 {
370 ; CHECK-NEXT: %3 = call %multiple_same_return_mayalias_order @multiple_same_return_mayalias_order.body(i32* undef, i32* undef)
371 ; CHECK-NEXT: %4 = extractvalue %multiple_same_return_mayalias_order %3, 0
372 ; CHECK-NEXT: store i32 %4, i32* %0, align 4
373 ; CHECK-NEXT: %5 = extractvalue %multiple_same_return_mayalias_order %3, 1
374 ; CHECK-NEXT: store i32 %5, i32* %1, align 4
375 ; CHECK-NEXT: ret void
376 define void @multiple_same_return_mayalias_order(i32* %out0, i32* %out1) #0 {
377  store i32 2, i32* %out1, align 4
378  store i32 1, i32* %out0, align 4
379  ret void
380 }
381
382 ; Currently this fails to convert because the store won't be found if
383 ; it isn't in the same block as the return.
384 ; CHECK-LABEL: define i32 @store_in_entry_block(i1 %arg0, i32* %out) #0 {
385 ; CHECK-NOT: call
386 define i32 @store_in_entry_block(i1 %arg0, i32* %out) #0 {
387 entry:
388   %val0 = load i32, i32 addrspace(1)* undef
389   store i32 %val0, i32* %out
390   br i1 %arg0, label %if, label %endif
391
392 if:
393   %val1 = load i32, i32 addrspace(1)* undef
394   br label %endif
395
396 endif:
397   %phi = phi i32 [ 0, %entry ], [ %val1, %if ]
398   ret i32 %phi
399 }
400
401 ; CHECK-LABEL: define private %i1_one_out_arg_i32_1_use @i1_one_out_arg_i32_1_use.body(i32* %val) #0 {
402 ; CHECK-NEXT: ret %i1_one_out_arg_i32_1_use { i1 true, i32 24 }
403
404 ; CHECK-LABEL: define i1 @i1_one_out_arg_i32_1_use(i32*) #2 {
405 ; CHECK: %2 = call %i1_one_out_arg_i32_1_use @i1_one_out_arg_i32_1_use.body(i32* undef)
406 ; CHECK: %3 = extractvalue %i1_one_out_arg_i32_1_use %2, 1
407 ; CHECK: store i32 %3, i32* %0, align 4
408 ; CHECK: %4 = extractvalue %i1_one_out_arg_i32_1_use %2, 0
409 ; CHECK: ret i1 %4
410 define i1 @i1_one_out_arg_i32_1_use(i32* %val) #0 {
411   store i32 24, i32* %val
412   ret i1 true
413 }
414
415 ; Make sure we don't leave around return attributes that are
416 ; incompatible with struct return types.
417
418 ; CHECK-LABEL: define private %i1_zeroext_one_out_arg_i32_1_use @i1_zeroext_one_out_arg_i32_1_use.body(i32* %val) #0 {
419 ; CHECK-NEXT: ret %i1_zeroext_one_out_arg_i32_1_use { i1 true, i32 24 }
420
421 ; CHECK-LABEL: define zeroext i1 @i1_zeroext_one_out_arg_i32_1_use(i32*) #2 {
422 ; CHECK-NEXT: %2 = call %i1_zeroext_one_out_arg_i32_1_use @i1_zeroext_one_out_arg_i32_1_use.body(i32* undef)
423 ; CHECK-NEXT: %3 = extractvalue %i1_zeroext_one_out_arg_i32_1_use %2, 1
424 ; CHECK-NEXT: store i32 %3, i32* %0, align 4
425 ; CHECK-NEXT: %4 = extractvalue %i1_zeroext_one_out_arg_i32_1_use %2, 0
426 ; CHECK-NEXT: ret i1 %4
427 define zeroext i1 @i1_zeroext_one_out_arg_i32_1_use(i32* %val) #0 {
428   store i32 24, i32* %val
429   ret i1 true
430 }
431
432 ; CHECK-LABEL: define private %i1_signext_one_out_arg_i32_1_use @i1_signext_one_out_arg_i32_1_use.body(i32* %val) #0 {
433 ; CHECK-NEXT: ret %i1_signext_one_out_arg_i32_1_use { i1 true, i32 24 }
434
435 ; CHECK-LABEL: define signext i1 @i1_signext_one_out_arg_i32_1_use(i32*) #2 {
436 ; CHECK-NEXT: %2 = call %i1_signext_one_out_arg_i32_1_use @i1_signext_one_out_arg_i32_1_use.body(i32* undef)
437 ; CHECK-NEXT: %3 = extractvalue %i1_signext_one_out_arg_i32_1_use %2, 1
438 ; CHECK-NEXT: store i32 %3, i32* %0, align 4
439 ; CHECK-NEXT: %4 = extractvalue %i1_signext_one_out_arg_i32_1_use %2, 0
440 ; CHECK-NEXT: ret i1 %4
441 define signext i1 @i1_signext_one_out_arg_i32_1_use(i32* %val) #0 {
442   store i32 24, i32* %val
443   ret i1 true
444 }
445
446 ; CHECK-LABEL: define private %p1i32_noalias_one_out_arg_i32_1_use @p1i32_noalias_one_out_arg_i32_1_use.body(i32* %val) #0 {
447 ; CHECK-NEXT: ret %p1i32_noalias_one_out_arg_i32_1_use { i32 addrspace(1)* null, i32 24 }
448
449 ; CHECK-LABEL: define noalias i32 addrspace(1)* @p1i32_noalias_one_out_arg_i32_1_use(i32*) #2 {
450 ; CHECK-NEXT: %2 = call %p1i32_noalias_one_out_arg_i32_1_use @p1i32_noalias_one_out_arg_i32_1_use.body(i32* undef)
451 ; CHECK-NEXT: %3 = extractvalue %p1i32_noalias_one_out_arg_i32_1_use %2, 1
452 ; CHECK-NEXT: store i32 %3, i32* %0, align 4
453 ; CHECK-NEXT: %4 = extractvalue %p1i32_noalias_one_out_arg_i32_1_use %2, 0
454 ; CHECK-NEXT: ret i32 addrspace(1)* %4
455 define noalias i32 addrspace(1)* @p1i32_noalias_one_out_arg_i32_1_use(i32* %val) #0 {
456   store i32 24, i32* %val
457   ret i32 addrspace(1)* null
458 }
459
460 ; CHECK-LABEL: define void @void_one_out_non_private_arg_i32_1_use(i32 addrspace(1)* %val) #0 {
461 ; CHECK-NEXT: store i32 0, i32 addrspace(1)* %val
462 ; CHECK-NEXT: ret void
463 define void @void_one_out_non_private_arg_i32_1_use(i32 addrspace(1)* %val) #0 {
464   store i32 0, i32 addrspace(1)* %val
465   ret void
466 }
467
468 ; CHECK-LABEL: define private %func_ptr_type @func_ptr_type.body(void ()** %out) #0 {
469 ; CHECK-LABEL: define void @func_ptr_type(void ()**) #2 {
470 ; CHECK: %2 = call %func_ptr_type @func_ptr_type.body(void ()** undef)
471 define void @func_ptr_type(void()** %out) #0 {
472   %func = load void()*, void()** undef
473   store void()* %func, void()** %out
474   ret void
475 }
476
477 ; CHECK-LABEL: define private %bitcast_func_ptr_type @bitcast_func_ptr_type.body(void ()** %out) #0 {
478 ; CHECK-LABEL: define void @bitcast_func_ptr_type(void ()**) #2 {
479 define void @bitcast_func_ptr_type(void()** %out) #0 {
480   %func = load i32()*, i32()** undef
481   %cast = bitcast void()** %out to i32()**
482   store i32()* %func, i32()** %cast
483   ret void
484 }
485
486 ; CHECK-LABEL: define private %out_arg_small_array @out_arg_small_array.body([4 x i32]* %val) #0 {
487 ; CHECK-NEXT: ret %out_arg_small_array { [4 x i32] [i32 0, i32 1, i32 2, i32 3] }
488
489 ; CHECK-LABEL: define void @out_arg_small_array([4 x i32]*) #2 {
490 define void @out_arg_small_array([4 x i32]* %val) #0 {
491   store [4 x i32] [i32 0, i32 1, i32 2, i32 3], [4 x i32]* %val
492   ret void
493 }
494
495 ; CHECK-NOT: define
496 ; CHECK-LABEL: define void @out_arg_large_array([17 x i32]* %val) #0 {
497 ; CHECK-NEXT: store [17 x i32] zeroinitializer, [17 x i32]* %val
498 ; CHECK-NEXT: ret void
499 define void @out_arg_large_array([17 x i32]* %val) #0 {
500   store [17 x i32] zeroinitializer, [17 x i32]* %val
501   ret void
502 }
503
504 ; CHECK-NOT: define
505 ; CHECK-LABEL: define <16 x i32> @num_regs_return_limit(i32* %out, i32 %val) #0 {
506 define <16 x i32> @num_regs_return_limit(i32* %out, i32 %val) #0 {
507   %load = load volatile <16 x i32>, <16 x i32> addrspace(1)* undef
508   store i32 %val, i32* %out
509   ret <16 x i32> %load
510 }
511
512 ; CHECK-LABEL: define private %num_regs_reach_limit @num_regs_reach_limit.body(i32* %out, i32 %val) #0 {
513 ; CHECK: define [15 x i32] @num_regs_reach_limit(i32*, i32) #2 {
514 ; CHECK-NEXT: call %num_regs_reach_limit @num_regs_reach_limit.body(i32* undef, i32 %1)
515 define [15 x i32] @num_regs_reach_limit(i32* %out, i32 %val) #0 {
516   %load = load volatile [15 x i32], [15 x i32] addrspace(1)* undef
517   store i32 %val, i32* %out
518   ret [15 x i32] %load
519 }
520
521 ; CHECK-LABEL: define private %num_regs_reach_limit_leftover @num_regs_reach_limit_leftover.body(i32* %out0, i32* %out1, i32 %val0) #0 {
522 ; CHECK-NEXT: %load0 = load volatile [15 x i32], [15 x i32] addrspace(1)* undef
523 ; CHECK-NEXT: %load1 = load volatile i32, i32 addrspace(1)* undef
524 ; CHECK-NEXT: %1 = insertvalue %num_regs_reach_limit_leftover undef, [15 x i32] %load0, 0
525 ; CHECK-NEXT: %2 = insertvalue %num_regs_reach_limit_leftover %1, i32 %load1, 1
526 ; CHECK-NEXT: %3 = insertvalue %num_regs_reach_limit_leftover %2, i32 %val0, 2
527 ; CHECK-NEXT: ret %num_regs_reach_limit_leftover %3
528
529 ; CHECK-LABEL: define [15 x i32] @num_regs_reach_limit_leftover(i32*, i32*, i32) #2 {
530 ; CHECK-NEXT: %4 = call %num_regs_reach_limit_leftover @num_regs_reach_limit_leftover.body(i32* undef, i32* undef, i32 %2)
531 ; CHECK-NEXT: %5 = extractvalue %num_regs_reach_limit_leftover %4, 1
532 ; CHECK-NEXT: store i32 %5, i32* %0, align 4
533 ; CHECK-NEXT: %6 = extractvalue %num_regs_reach_limit_leftover %4, 2
534 ; CHECK-NEXT: store i32 %6, i32* %1, align 4
535 ; CHECK-NEXT: %7 = extractvalue %num_regs_reach_limit_leftover %4, 0
536 ; CHECK-NEXT: ret [15 x i32] %7
537 define [15 x i32] @num_regs_reach_limit_leftover(i32* %out0, i32* %out1, i32 %val0) #0 {
538   %load0 = load volatile [15 x i32], [15 x i32] addrspace(1)* undef
539   %load1 = load volatile i32, i32 addrspace(1)* undef
540   store i32 %val0, i32* %out0
541   store i32 %load1, i32* %out1
542   ret [15 x i32] %load0
543 }
544
545 ; CHECK-LABEL: define private %preserve_debug_info @preserve_debug_info.body(i32 %arg0, i32* %val) #0 {
546 ; CHECK-NEXT: call void @may.clobber(), !dbg !5
547 ; CHECK-NEXT: %1 = insertvalue %preserve_debug_info undef, i32 %arg0, 0, !dbg !11
548 ; CHECK-NEXT: ret %preserve_debug_info %1, !dbg !11
549
550 ; CHECK-LABEL: define void @preserve_debug_info(i32, i32*) #2 !dbg !6 {
551 ; CHECK-NEXT: %3 = call %preserve_debug_info @preserve_debug_info.body(i32 %0, i32* undef){{$}}
552 ; CHECK-NEXT: %4 = extractvalue %preserve_debug_info %3, 0{{$}}
553 ; CHECK-NEXT: store i32 %4, i32* %1, align 4{{$}}
554 ; CHECK-NEXT: ret void
555 define void @preserve_debug_info(i32 %arg0, i32* %val) #0 !dbg !5 {
556   call void @may.clobber(), !dbg !10
557   store i32 %arg0, i32* %val, !dbg !11
558   ret void, !dbg !12
559 }
560
561 define void @preserve_metadata(i32 %arg0, i32* %val) #0 !kernel_arg_access_qual !13 {
562   call void @may.clobber()
563   store i32 %arg0, i32* %val
564   ret void
565 }
566
567 ; Clang emits this pattern for 3-vectors for some reason.
568 ; CHECK-LABEL: define private %bitcast_pointer_v4i32_v3i32 @bitcast_pointer_v4i32_v3i32.body(<3 x i32>* %out) #0 {
569 ; CHECK-NEXT: %load = load volatile <4 x i32>, <4 x i32> addrspace(1)* undef
570 ; CHECK-NEXT: %bitcast = bitcast <3 x i32>* %out to <4 x i32>*
571 ; CHECK-NEXT: %1 = shufflevector <4 x i32> %load, <4 x i32> undef, <3 x i32> <i32 0, i32 1, i32 2>
572 ; CHECK-NEXT: %2 = insertvalue %bitcast_pointer_v4i32_v3i32 undef, <3 x i32> %1, 0
573 ; CHECK-NEXT: ret %bitcast_pointer_v4i32_v3i32 %2
574
575 ; CHECK-LABEL: define void @bitcast_pointer_v4i32_v3i32(<3 x i32>*) #2 {
576 ; CHECK-NEXT: %2 = call %bitcast_pointer_v4i32_v3i32 @bitcast_pointer_v4i32_v3i32.body(<3 x i32>* undef)
577 ; CHECK-NEXT: %3 = extractvalue %bitcast_pointer_v4i32_v3i32 %2, 0
578 ; CHECK-NEXT: store <3 x i32> %3, <3 x i32>* %0, align 16
579 ; CHECK-NEXT: ret void
580 define void @bitcast_pointer_v4i32_v3i32(<3 x i32>* %out) #0 {
581   %load = load volatile <4 x i32>, <4 x i32> addrspace(1)* undef
582   %bitcast = bitcast <3 x i32>* %out to <4 x i32>*
583   store <4 x i32> %load, <4 x i32>* %bitcast
584   ret void
585 }
586
587 ; CHECK-LABEL: define private %bitcast_pointer_v4i32_v3f32 @bitcast_pointer_v4i32_v3f32.body(<3 x float>* %out) #0 {
588 ; CHECK-NEXT: %load = load volatile <4 x i32>, <4 x i32> addrspace(1)* undef
589 ; CHECK-NEXT: %bitcast = bitcast <3 x float>* %out to <4 x i32>*
590 ; CHECK-NEXT: %1 = shufflevector <4 x i32> %load, <4 x i32> undef, <3 x i32> <i32 0, i32 1, i32 2>
591 ; CHECK-NEXT: %2 = bitcast <3 x i32> %1 to <3 x float>
592 ; CHECK-NEXT: %3 = insertvalue %bitcast_pointer_v4i32_v3f32 undef, <3 x float> %2, 0
593 ; CHECK-NEXT: ret %bitcast_pointer_v4i32_v3f32 %3
594 define void @bitcast_pointer_v4i32_v3f32(<3 x float>* %out) #0 {
595   %load = load volatile <4 x i32>, <4 x i32> addrspace(1)* undef
596   %bitcast = bitcast <3 x float>* %out to <4 x i32>*
597   store <4 x i32> %load, <4 x i32>* %bitcast
598   ret void
599 }
600
601
602 ; Try different element and bitwidths which could produce broken
603 ; casts.
604
605 ; CHECK-LABEL: define private %bitcast_pointer_i32_f32 @bitcast_pointer_i32_f32.body(float* %out) #0 {
606 ; CHECK-NEXT: %load = load volatile i32, i32 addrspace(1)* undef
607 ; CHECK-NEXT: %bitcast = bitcast float* %out to i32*
608 ; CHECK-NEXT: %1 = bitcast i32 %load to float
609 ; CHECK-NEXT: %2 = insertvalue %bitcast_pointer_i32_f32 undef, float %1, 0
610 ; CHECK-NEXT: ret %bitcast_pointer_i32_f32 %2
611
612 ; CHECK-LABEL: define void @bitcast_pointer_i32_f32(float*) #2 {
613 ; CHECK-NEXT: %2 = call %bitcast_pointer_i32_f32 @bitcast_pointer_i32_f32.body(float* undef)
614 ; CHECK-NEXT: %3 = extractvalue %bitcast_pointer_i32_f32 %2, 0
615 ; CHECK-NEXT: store float %3, float* %0, align 4
616 define void @bitcast_pointer_i32_f32(float* %out) #0 {
617   %load = load volatile i32, i32 addrspace(1)* undef
618   %bitcast = bitcast float* %out to i32*
619   store i32 %load, i32* %bitcast
620   ret void
621 }
622
623 ; CHECK-LABEL: define void @bitcast_pointer_i32_f16(half* %out) #0 {
624 ; CHECK-NOT: call
625 define void @bitcast_pointer_i32_f16(half* %out) #0 {
626   %load = load volatile i32, i32 addrspace(1)* undef
627   %bitcast = bitcast half* %out to i32*
628   store i32 %load, i32* %bitcast
629   ret void
630 }
631
632 ; CHECK-LABEL: define void @bitcast_pointer_f16_i32(i32* %out) #0 {
633 ; CHECK-NOT: call
634 define void @bitcast_pointer_f16_i32(i32* %out) #0 {
635   %load = load volatile half, half addrspace(1)* undef
636   %bitcast = bitcast i32* %out to half*
637   store half %load, half* %bitcast
638   ret void
639 }
640
641 %struct.i128 = type { i128 }
642 %struct.v2f32 = type { <2 x float> }
643 %struct.v3f32 = type { <3 x float> }
644 %struct.v3f32.f32 = type { <3 x float>, float }
645 %struct.v4f32 = type { <4 x float> }
646
647 ; CHECK-LABEL: define private %bitcast_struct_v3f32_v3f32 @bitcast_struct_v3f32_v3f32.body(%struct.v3f32* %out, <3 x float> %value) #0 {
648 ; CHECK-NEXT: %extractVec = shufflevector <3 x float> %value, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
649 ; CHECK-NEXT: %cast = bitcast %struct.v3f32* %out to <4 x float>*
650 ; CHECK-NEXT: %1 = shufflevector <4 x float> %extractVec, <4 x float> undef, <3 x i32> <i32 0, i32 1, i32 2>
651 ; CHECK-NEXT: %2 = insertvalue %struct.v3f32 undef, <3 x float> %1, 0
652 ; CHECK-NEXT: %3 = insertvalue %bitcast_struct_v3f32_v3f32 undef, %struct.v3f32 %2, 0
653 ; CHECK-NEXT: ret %bitcast_struct_v3f32_v3f32 %3
654
655 ; CHECK-LABEL: define void @bitcast_struct_v3f32_v3f32(%struct.v3f32*, <3 x float>) #2 {
656 ; CHECK-NEXT: %3 = call %bitcast_struct_v3f32_v3f32 @bitcast_struct_v3f32_v3f32.body(%struct.v3f32* undef, <3 x float> %1)
657 ; CHECK-NEXT: %4 = extractvalue %bitcast_struct_v3f32_v3f32 %3, 0
658 ; CHECK-NEXT: store %struct.v3f32 %4, %struct.v3f32* %0, align 16
659 ; CHECK-NEXT: ret void
660 define void @bitcast_struct_v3f32_v3f32(%struct.v3f32* %out, <3 x float> %value) #0 {
661   %extractVec = shufflevector <3 x float> %value, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
662   %cast = bitcast %struct.v3f32* %out to <4 x float>*
663   store <4 x float> %extractVec, <4 x float>* %cast, align 16
664   ret void
665 }
666
667 ; CHECK-LABEL: define private %bitcast_struct_v3f32_v3i32 @bitcast_struct_v3f32_v3i32.body(%struct.v3f32* %out, <3 x i32> %value) #0 {
668 ; CHECK-NEXT: %extractVec = shufflevector <3 x i32> %value, <3 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
669 ; CHECK-NEXT: %cast = bitcast %struct.v3f32* %out to <4 x i32>*
670 ; CHECK-NEXT: %1 = shufflevector <4 x i32> %extractVec, <4 x i32> undef, <3 x i32> <i32 0, i32 1, i32 2>
671 ; CHECK-NEXT: %2 = bitcast <3 x i32> %1 to <3 x float>
672 ; CHECK-NEXT: %3 = insertvalue %struct.v3f32 undef, <3 x float> %2, 0
673 ; CHECK-NEXT: %4 = insertvalue %bitcast_struct_v3f32_v3i32 undef, %struct.v3f32 %3, 0
674 ; CHECK-NEXT: ret %bitcast_struct_v3f32_v3i32 %4
675
676 ; CHECK-LABEL: define void @bitcast_struct_v3f32_v3i32(%struct.v3f32*, <3 x i32>) #2 {
677 ; CHECK-NEXT: %3 = call %bitcast_struct_v3f32_v3i32 @bitcast_struct_v3f32_v3i32.body(%struct.v3f32* undef, <3 x i32> %1)
678 ; CHECK-NEXT: %4 = extractvalue %bitcast_struct_v3f32_v3i32 %3, 0
679 ; CHECK-NEXT: store %struct.v3f32 %4, %struct.v3f32* %0, align 16
680 define void @bitcast_struct_v3f32_v3i32(%struct.v3f32* %out, <3 x i32> %value) #0 {
681   %extractVec = shufflevector <3 x i32> %value, <3 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
682   %cast = bitcast %struct.v3f32* %out to <4 x i32>*
683   store <4 x i32> %extractVec, <4 x i32>* %cast, align 16
684   ret void
685 }
686
687 ; CHECK-LABEL: define private %bitcast_struct_v4f32_v4f32 @bitcast_struct_v4f32_v4f32.body(%struct.v4f32* %out, <4 x float> %value) #0 {
688 ; CHECK-NEXT: %cast = bitcast %struct.v4f32* %out to <4 x float>*
689 ; CHECK-NEXT: %1 = insertvalue %struct.v4f32 undef, <4 x float> %value, 0
690 ; CHECK-NEXT: %2 = insertvalue %bitcast_struct_v4f32_v4f32 undef, %struct.v4f32 %1, 0
691 ; CHECK-NEXT: ret %bitcast_struct_v4f32_v4f32 %2
692
693 ; CHECK-LABEL: define void @bitcast_struct_v4f32_v4f32(%struct.v4f32*, <4 x float>) #2 {
694 ; CHECK-NEXT: %3 = call %bitcast_struct_v4f32_v4f32 @bitcast_struct_v4f32_v4f32.body(%struct.v4f32* undef, <4 x float> %1)
695 define void @bitcast_struct_v4f32_v4f32(%struct.v4f32* %out, <4 x float> %value) #0 {
696   %cast = bitcast %struct.v4f32* %out to <4 x float>*
697   store <4 x float> %value, <4 x float>* %cast, align 16
698   ret void
699 }
700
701 ; CHECK-LABEL: define private %bitcast_struct_v3f32_v4i32 @bitcast_struct_v3f32_v4i32.body(%struct.v3f32* %out, <4 x i32> %value) #0 {
702 ; CHECK-LABEL: define void @bitcast_struct_v3f32_v4i32(%struct.v3f32*, <4 x i32>) #2 {
703 define void @bitcast_struct_v3f32_v4i32(%struct.v3f32* %out, <4 x i32> %value) #0 {
704   %cast = bitcast %struct.v3f32* %out to <4 x i32>*
705   store <4 x i32> %value, <4 x i32>* %cast, align 16
706   ret void
707 }
708
709 ; CHECK-LABEL: define private %bitcast_struct_v4f32_v3f32 @bitcast_struct_v4f32_v3f32.body(%struct.v4f32* %out, <3 x float> %value) #0 {
710 ; CHECK-LABEL: define void @bitcast_struct_v4f32_v3f32(%struct.v4f32*, <3 x float>) #2 {
711 define void @bitcast_struct_v4f32_v3f32(%struct.v4f32* %out, <3 x float> %value) #0 {
712   %extractVec = shufflevector <3 x float> %value, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
713   %cast = bitcast %struct.v4f32* %out to <4 x float>*
714   store <4 x float> %extractVec, <4 x float>* %cast, align 16
715   ret void
716 }
717
718 ; CHECK-NOT: define
719 ; CHECK-LABEL: define void @bitcast_struct_v3f32_v2f32(%struct.v3f32* %out, <2 x float> %value) #0 {
720 ; CHECK-NOT: call
721 define void @bitcast_struct_v3f32_v2f32(%struct.v3f32* %out, <2 x float> %value) #0 {
722   %cast = bitcast %struct.v3f32* %out to <2 x float>*
723   store <2 x float> %value, <2 x float>* %cast, align 8
724   ret void
725 }
726
727 ; CHECK-NOT: define
728 ; CHECK-LABEL: define void @bitcast_struct_v3f32_f32_v3f32(%struct.v3f32.f32* %out, <3 x float> %value) #0 {
729 ; CHECK-NOT: call
730 define void @bitcast_struct_v3f32_f32_v3f32(%struct.v3f32.f32* %out, <3 x float> %value) #0 {
731   %extractVec = shufflevector <3 x float> %value, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
732   %cast = bitcast %struct.v3f32.f32* %out to <4 x float>*
733   store <4 x float> %extractVec, <4 x float>* %cast, align 16
734   ret void
735 }
736
737 ; CHECK-NOT: define
738 ; CHECK-LABEL: define void @bitcast_struct_v3f32_f32_v4f32(%struct.v3f32.f32* %out, <4 x float> %value) #0 {
739 ; CHECK-NOT: call
740 define void @bitcast_struct_v3f32_f32_v4f32(%struct.v3f32.f32* %out, <4 x float> %value) #0 {
741   %cast = bitcast %struct.v3f32.f32* %out to <4 x float>*
742   store <4 x float> %value, <4 x float>* %cast, align 16
743   ret void
744 }
745
746 ; CHECK-LABEL: define private %bitcast_struct_i128_v4f32 @bitcast_struct_i128_v4f32.body(%struct.i128* %out, <4 x float> %value) #0 {
747 ; CHECK-NEXT: %cast = bitcast %struct.i128* %out to <4 x float>*
748 ; CHECK-NEXT: %1 = bitcast <4 x float> %value to i128
749 ; CHECK-NEXT: %2 = insertvalue %struct.i128 undef, i128 %1, 0
750 ; CHECK-NEXT: %3 = insertvalue %bitcast_struct_i128_v4f32 undef, %struct.i128 %2, 0
751 ; CHECK-NEXT: ret %bitcast_struct_i128_v4f32 %3
752 define void @bitcast_struct_i128_v4f32(%struct.i128* %out, <4 x float> %value) #0 {
753   %cast = bitcast %struct.i128* %out to <4 x float>*
754   store <4 x float> %value, <4 x float>* %cast, align 16
755   ret void
756 }
757
758 ; CHECK-LABEL: define void @bitcast_struct_i128_v4f32(%struct.i128*, <4 x float>) #2 {
759 ; CHECK-NEXT: %3 = call %bitcast_struct_i128_v4f32 @bitcast_struct_i128_v4f32.body(%struct.i128* undef, <4 x float> %1)
760 define void @bitcast_array_v4i32_v4f32([4 x i32]* %out, [4 x float] %value) #0 {
761   %cast = bitcast [4 x i32]* %out to [4 x float]*
762   store [4 x float] %value, [4 x float]* %cast, align 4
763   ret void
764 }
765
766 ; CHECK-LABEL: define private %multi_return_bitcast_struct_v3f32_v3f32 @multi_return_bitcast_struct_v3f32_v3f32.body(i1 %cond, %struct.v3f32* %out, <3 x float> %value) #0 {
767 ; CHECK: ret0:
768 ; CHECK: %cast0 = bitcast %struct.v3f32* %out to <4 x float>*
769 ; CHECK: %0 = shufflevector <4 x float> %extractVec, <4 x float> undef, <3 x i32> <i32 0, i32 1, i32 2>
770 ; CHECK: %1 = insertvalue %struct.v3f32 undef, <3 x float> %0, 0
771 ; CHECK: %2 = insertvalue %multi_return_bitcast_struct_v3f32_v3f32 undef, %struct.v3f32 %1, 0
772 ; CHECK: ret %multi_return_bitcast_struct_v3f32_v3f32 %2
773
774 ; CHECK: ret1:
775 ; CHECK: %4 = insertvalue %struct.v3f32 undef, <3 x float> %3, 0
776 ; CHECK: %5 = insertvalue %multi_return_bitcast_struct_v3f32_v3f32 undef, %struct.v3f32 %4, 0
777 ; CHECK: ret %multi_return_bitcast_struct_v3f32_v3f32 %5
778 define void @multi_return_bitcast_struct_v3f32_v3f32(i1 %cond, %struct.v3f32* %out, <3 x float> %value) #0 {
779 entry:
780   br i1 %cond, label %ret0, label %ret1
781
782 ret0:
783   %extractVec = shufflevector <3 x float> %value, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
784   %cast0 = bitcast %struct.v3f32* %out to <4 x float>*
785   store <4 x float> %extractVec, <4 x float>* %cast0, align 16
786   ret void
787
788 ret1:
789   %cast1 = bitcast %struct.v3f32* %out to <4 x float>*
790   %load = load <4 x float>, <4 x float> addrspace(1)* undef
791   store <4 x float> %load, <4 x float>* %cast1, align 16
792   ret void
793 }
794
795 ; CHECK-LABEL: define void @bitcast_v3f32_struct_v3f32(<3 x float>* %out, %struct.v3f32 %value) #0 {
796 ; CHECK-NOT: call
797 define void @bitcast_v3f32_struct_v3f32(<3 x float>* %out, %struct.v3f32 %value) #0 {
798   %cast = bitcast <3 x float>* %out to %struct.v3f32*
799   store %struct.v3f32 %value, %struct.v3f32* %cast, align 4
800   ret void
801 }
802
803 attributes #0 = { nounwind }
804 attributes #1 = { nounwind noinline optnone }
805 attributes #2 = { alwaysinline nounwind }
806
807 !llvm.dbg.cu = !{!0}
808 !llvm.module.flags = !{!3, !4}
809
810 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 5.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
811 !1 = !DIFile(filename: "code-object-metadata-kernel-debug-props.cl", directory: "/some/random/directory")
812 !2 = !{}
813 !3 = !{i32 2, !"Dwarf Version", i32 2}
814 !4 = !{i32 2, !"Debug Info Version", i32 3}
815 !5 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 1, type: !6, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
816 !6 = !DISubroutineType(types: !7)
817 !7 = !{null, !8}
818 !8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64)
819 !9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
820 !10 = !DILocation(line: 2, column: 3, scope: !5)
821 !11 = !DILocation(line: 2, column: 8, scope: !5)
822 !12 = !DILocation(line: 3, column: 3, scope: !5)
823 !13 = !{!"none"}