xref: /llvm-project/llvm/test/CodeGen/X86/swift-return.ll (revision 86eff6be686a1e41e13c08ebfc2db4dd4d58e7c6)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
3; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-unknown-unknown -O0 | FileCheck --check-prefix=CHECK-O0 %s
4
5@var = dso_local global i32 0
6
7; Test how llvm handles return type of {i16, i8}. The return value will be
8; passed in %eax and %dl.
9define i16 @test(i32 %key) {
10; CHECK-LABEL: test:
11; CHECK:       # %bb.0: # %entry
12; CHECK-NEXT:    pushq %rax
13; CHECK-NEXT:    .cfi_def_cfa_offset 16
14; CHECK-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
15; CHECK-NEXT:    callq gen@PLT
16; CHECK-NEXT:    # kill: def $ax killed $ax def $eax
17; CHECK-NEXT:    movsbl %dl, %ecx
18; CHECK-NEXT:    addl %ecx, %eax
19; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
20; CHECK-NEXT:    popq %rcx
21; CHECK-NEXT:    .cfi_def_cfa_offset 8
22; CHECK-NEXT:    retq
23;
24; CHECK-O0-LABEL: test:
25; CHECK-O0:       # %bb.0: # %entry
26; CHECK-O0-NEXT:    pushq %rax
27; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
28; CHECK-O0-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
29; CHECK-O0-NEXT:    movl {{[0-9]+}}(%rsp), %edi
30; CHECK-O0-NEXT:    callq gen@PLT
31; CHECK-O0-NEXT:    cwtl
32; CHECK-O0-NEXT:    movsbl %dl, %ecx
33; CHECK-O0-NEXT:    addl %ecx, %eax
34; CHECK-O0-NEXT:    # kill: def $ax killed $ax killed $eax
35; CHECK-O0-NEXT:    popq %rcx
36; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
37; CHECK-O0-NEXT:    retq
38entry:
39  %key.addr = alloca i32, align 4
40  store i32 %key, ptr %key.addr, align 4
41  %0 = load i32, ptr %key.addr, align 4
42  %call = call swiftcc { i16, i8 } @gen(i32 %0)
43  %v3 = extractvalue { i16, i8 } %call, 0
44  %v1 = sext i16 %v3 to i32
45  %v5 = extractvalue { i16, i8 } %call, 1
46  %v2 = sext i8 %v5 to i32
47  %add = add nsw i32 %v1, %v2
48  %conv = trunc i32 %add to i16
49  ret i16 %conv
50}
51
52declare swiftcc { i16, i8 } @gen(i32)
53
54; If we can't pass every return value in register, we will pass everything
55; in memroy. The caller provides space for the return value and passes
56; the address in %rax. The first input argument will be in %rdi.
57define dso_local i32 @test2(i32 %key) #0 {
58; CHECK-LABEL: test2:
59; CHECK:       # %bb.0: # %entry
60; CHECK-NEXT:    subq $24, %rsp
61; CHECK-NEXT:    .cfi_def_cfa_offset 32
62; CHECK-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
63; CHECK-NEXT:    movq %rsp, %rax
64; CHECK-NEXT:    callq gen2@PLT
65; CHECK-NEXT:    movl (%rsp), %eax
66; CHECK-NEXT:    addl {{[0-9]+}}(%rsp), %eax
67; CHECK-NEXT:    addl {{[0-9]+}}(%rsp), %eax
68; CHECK-NEXT:    addl {{[0-9]+}}(%rsp), %eax
69; CHECK-NEXT:    addl {{[0-9]+}}(%rsp), %eax
70; CHECK-NEXT:    addq $24, %rsp
71; CHECK-NEXT:    .cfi_def_cfa_offset 8
72; CHECK-NEXT:    retq
73;
74; CHECK-O0-LABEL: test2:
75; CHECK-O0:       # %bb.0: # %entry
76; CHECK-O0-NEXT:    subq $24, %rsp
77; CHECK-O0-NEXT:    .cfi_def_cfa_offset 32
78; CHECK-O0-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
79; CHECK-O0-NEXT:    movl {{[0-9]+}}(%rsp), %edi
80; CHECK-O0-NEXT:    movq %rsp, %rax
81; CHECK-O0-NEXT:    callq gen2@PLT
82; CHECK-O0-NEXT:    movl {{[0-9]+}}(%rsp), %ecx
83; CHECK-O0-NEXT:    movl {{[0-9]+}}(%rsp), %edx
84; CHECK-O0-NEXT:    movl {{[0-9]+}}(%rsp), %esi
85; CHECK-O0-NEXT:    movl (%rsp), %eax
86; CHECK-O0-NEXT:    movl {{[0-9]+}}(%rsp), %edi
87; CHECK-O0-NEXT:    addl %edi, %eax
88; CHECK-O0-NEXT:    addl %esi, %eax
89; CHECK-O0-NEXT:    addl %edx, %eax
90; CHECK-O0-NEXT:    addl %ecx, %eax
91; CHECK-O0-NEXT:    addq $24, %rsp
92; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
93; CHECK-O0-NEXT:    retq
94entry:
95  %key.addr = alloca i32, align 4
96  store i32 %key, ptr %key.addr, align 4
97  %0 = load i32, ptr %key.addr, align 4
98  %call = call swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %0)
99
100  %v3 = extractvalue { i32, i32, i32, i32, i32 } %call, 0
101  %v5 = extractvalue { i32, i32, i32, i32, i32 } %call, 1
102  %v6 = extractvalue { i32, i32, i32, i32, i32 } %call, 2
103  %v7 = extractvalue { i32, i32, i32, i32, i32 } %call, 3
104  %v8 = extractvalue { i32, i32, i32, i32, i32 } %call, 4
105
106  %add = add nsw i32 %v3, %v5
107  %add1 = add nsw i32 %add, %v6
108  %add2 = add nsw i32 %add1, %v7
109  %add3 = add nsw i32 %add2, %v8
110  ret i32 %add3
111}
112
113; The address of the return value is passed in %rax.
114; On return, we don't keep the address in %rax.
115define swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %key) {
116; CHECK-LABEL: gen2:
117; CHECK:       # %bb.0:
118; CHECK-NEXT:    movl %edi, 16(%rax)
119; CHECK-NEXT:    movl %edi, 12(%rax)
120; CHECK-NEXT:    movl %edi, 8(%rax)
121; CHECK-NEXT:    movl %edi, 4(%rax)
122; CHECK-NEXT:    movl %edi, (%rax)
123; CHECK-NEXT:    retq
124;
125; CHECK-O0-LABEL: gen2:
126; CHECK-O0:       # %bb.0:
127; CHECK-O0-NEXT:    movl %edi, 16(%rax)
128; CHECK-O0-NEXT:    movl %edi, 12(%rax)
129; CHECK-O0-NEXT:    movl %edi, 8(%rax)
130; CHECK-O0-NEXT:    movl %edi, 4(%rax)
131; CHECK-O0-NEXT:    movl %edi, (%rax)
132; CHECK-O0-NEXT:    retq
133  %Y = insertvalue { i32, i32, i32, i32, i32 } undef, i32 %key, 0
134  %Z = insertvalue { i32, i32, i32, i32, i32 } %Y, i32 %key, 1
135  %Z2 = insertvalue { i32, i32, i32, i32, i32 } %Z, i32 %key, 2
136  %Z3 = insertvalue { i32, i32, i32, i32, i32 } %Z2, i32 %key, 3
137  %Z4 = insertvalue { i32, i32, i32, i32, i32 } %Z3, i32 %key, 4
138  ret { i32, i32, i32, i32, i32 } %Z4
139}
140
141; The return value {i32, i32, i32, i32} will be returned via registers %eax,
142; %edx, %ecx, %r8d.
143define dso_local i32 @test3(i32 %key) #0 {
144; CHECK-LABEL: test3:
145; CHECK:       # %bb.0: # %entry
146; CHECK-NEXT:    pushq %rax
147; CHECK-NEXT:    .cfi_def_cfa_offset 16
148; CHECK-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
149; CHECK-NEXT:    callq gen3@PLT
150; CHECK-NEXT:    # kill: def $ecx killed $ecx def $rcx
151; CHECK-NEXT:    # kill: def $r8d killed $r8d def $r8
152; CHECK-NEXT:    addl %edx, %eax
153; CHECK-NEXT:    addl %r8d, %ecx
154; CHECK-NEXT:    addl %ecx, %eax
155; CHECK-NEXT:    popq %rcx
156; CHECK-NEXT:    .cfi_def_cfa_offset 8
157; CHECK-NEXT:    retq
158;
159; CHECK-O0-LABEL: test3:
160; CHECK-O0:       # %bb.0: # %entry
161; CHECK-O0-NEXT:    pushq %rax
162; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
163; CHECK-O0-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
164; CHECK-O0-NEXT:    movl {{[0-9]+}}(%rsp), %edi
165; CHECK-O0-NEXT:    callq gen3@PLT
166; CHECK-O0-NEXT:    addl %edx, %eax
167; CHECK-O0-NEXT:    addl %ecx, %eax
168; CHECK-O0-NEXT:    addl %r8d, %eax
169; CHECK-O0-NEXT:    popq %rcx
170; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
171; CHECK-O0-NEXT:    retq
172entry:
173  %key.addr = alloca i32, align 4
174  store i32 %key, ptr %key.addr, align 4
175  %0 = load i32, ptr %key.addr, align 4
176  %call = call swiftcc { i32, i32, i32, i32 } @gen3(i32 %0)
177
178  %v3 = extractvalue { i32, i32, i32, i32 } %call, 0
179  %v5 = extractvalue { i32, i32, i32, i32 } %call, 1
180  %v6 = extractvalue { i32, i32, i32, i32 } %call, 2
181  %v7 = extractvalue { i32, i32, i32, i32 } %call, 3
182
183  %add = add nsw i32 %v3, %v5
184  %add1 = add nsw i32 %add, %v6
185  %add2 = add nsw i32 %add1, %v7
186  ret i32 %add2
187}
188
189declare swiftcc { i32, i32, i32, i32 } @gen3(i32 %key)
190
191; The return value {float, float, float, float} will be returned via registers
192; %xmm0, %xmm1, %xmm2, %xmm3.
193define dso_local float @test4(float %key) #0 {
194; CHECK-LABEL: test4:
195; CHECK:       # %bb.0: # %entry
196; CHECK-NEXT:    pushq %rax
197; CHECK-NEXT:    .cfi_def_cfa_offset 16
198; CHECK-NEXT:    movss %xmm0, {{[0-9]+}}(%rsp)
199; CHECK-NEXT:    callq gen4@PLT
200; CHECK-NEXT:    addss %xmm1, %xmm0
201; CHECK-NEXT:    addss %xmm2, %xmm0
202; CHECK-NEXT:    addss %xmm3, %xmm0
203; CHECK-NEXT:    popq %rax
204; CHECK-NEXT:    .cfi_def_cfa_offset 8
205; CHECK-NEXT:    retq
206;
207; CHECK-O0-LABEL: test4:
208; CHECK-O0:       # %bb.0: # %entry
209; CHECK-O0-NEXT:    pushq %rax
210; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
211; CHECK-O0-NEXT:    movss %xmm0, {{[0-9]+}}(%rsp)
212; CHECK-O0-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
213; CHECK-O0-NEXT:    callq gen4@PLT
214; CHECK-O0-NEXT:    addss %xmm1, %xmm0
215; CHECK-O0-NEXT:    addss %xmm2, %xmm0
216; CHECK-O0-NEXT:    addss %xmm3, %xmm0
217; CHECK-O0-NEXT:    popq %rax
218; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
219; CHECK-O0-NEXT:    retq
220entry:
221  %key.addr = alloca float, align 4
222  store float %key, ptr %key.addr, align 4
223  %0 = load float, ptr %key.addr, align 4
224  %call = call swiftcc { float, float, float, float } @gen4(float %0)
225
226  %v3 = extractvalue { float, float, float, float } %call, 0
227  %v5 = extractvalue { float, float, float, float } %call, 1
228  %v6 = extractvalue { float, float, float, float } %call, 2
229  %v7 = extractvalue { float, float, float, float } %call, 3
230
231  %add = fadd float %v3, %v5
232  %add1 = fadd float %add, %v6
233  %add2 = fadd float %add1, %v7
234  ret float %add2
235}
236
237declare swiftcc { float, float, float, float } @gen4(float %key)
238
239define dso_local void @consume_i1_ret() {
240; CHECK-LABEL: consume_i1_ret:
241; CHECK:       # %bb.0:
242; CHECK-NEXT:    pushq %rax
243; CHECK-NEXT:    .cfi_def_cfa_offset 16
244; CHECK-NEXT:    callq produce_i1_ret@PLT
245; CHECK-NEXT:    movzbl %al, %eax
246; CHECK-NEXT:    andl $1, %eax
247; CHECK-NEXT:    movl %eax, var(%rip)
248; CHECK-NEXT:    movzbl %dl, %eax
249; CHECK-NEXT:    andl $1, %eax
250; CHECK-NEXT:    movl %eax, var(%rip)
251; CHECK-NEXT:    movzbl %cl, %eax
252; CHECK-NEXT:    andl $1, %eax
253; CHECK-NEXT:    movl %eax, var(%rip)
254; CHECK-NEXT:    movzbl %r8b, %eax
255; CHECK-NEXT:    andl $1, %eax
256; CHECK-NEXT:    movl %eax, var(%rip)
257; CHECK-NEXT:    popq %rax
258; CHECK-NEXT:    .cfi_def_cfa_offset 8
259; CHECK-NEXT:    retq
260;
261; CHECK-O0-LABEL: consume_i1_ret:
262; CHECK-O0:       # %bb.0:
263; CHECK-O0-NEXT:    pushq %rax
264; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
265; CHECK-O0-NEXT:    callq produce_i1_ret@PLT
266; CHECK-O0-NEXT:    andb $1, %al
267; CHECK-O0-NEXT:    movzbl %al, %eax
268; CHECK-O0-NEXT:    movl %eax, var
269; CHECK-O0-NEXT:    andb $1, %dl
270; CHECK-O0-NEXT:    movzbl %dl, %eax
271; CHECK-O0-NEXT:    movl %eax, var
272; CHECK-O0-NEXT:    andb $1, %cl
273; CHECK-O0-NEXT:    movzbl %cl, %eax
274; CHECK-O0-NEXT:    movl %eax, var
275; CHECK-O0-NEXT:    andb $1, %r8b
276; CHECK-O0-NEXT:    movzbl %r8b, %eax
277; CHECK-O0-NEXT:    movl %eax, var
278; CHECK-O0-NEXT:    popq %rax
279; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
280; CHECK-O0-NEXT:    retq
281  %call = call swiftcc { i1, i1, i1, i1 } @produce_i1_ret()
282  %v3 = extractvalue { i1, i1, i1, i1 } %call, 0
283  %v5 = extractvalue { i1, i1, i1, i1 } %call, 1
284  %v6 = extractvalue { i1, i1, i1, i1 } %call, 2
285  %v7 = extractvalue { i1, i1, i1, i1 } %call, 3
286  %val = zext i1 %v3 to i32
287  store volatile i32 %val, ptr @var
288  %val2 = zext i1 %v5 to i32
289  store volatile i32 %val2, ptr @var
290  %val3 = zext i1 %v6 to i32
291  store volatile i32 %val3, ptr @var
292  %val4 = zext i1 %v7 to i32
293  store i32 %val4, ptr @var
294  ret void
295}
296
297declare swiftcc { i1, i1, i1, i1 } @produce_i1_ret()
298
299define swiftcc void @foo(ptr sret(i64) %agg.result, i64 %val) {
300; CHECK-LABEL: foo:
301; CHECK:       # %bb.0:
302; CHECK-NEXT:    movq %rdi, (%rax)
303; CHECK-NEXT:    retq
304;
305; CHECK-O0-LABEL: foo:
306; CHECK-O0:       # %bb.0:
307; CHECK-O0-NEXT:    movq %rdi, (%rax)
308; CHECK-O0-NEXT:    retq
309  store i64 %val, ptr %agg.result
310  ret void
311}
312
313define swiftcc double @test5() #0 {
314; CHECK-LABEL: test5:
315; CHECK:       # %bb.0: # %entry
316; CHECK-NEXT:    pushq %rax
317; CHECK-NEXT:    .cfi_def_cfa_offset 16
318; CHECK-NEXT:    callq gen5@PLT
319; CHECK-NEXT:    addsd %xmm1, %xmm0
320; CHECK-NEXT:    addsd %xmm2, %xmm0
321; CHECK-NEXT:    addsd %xmm3, %xmm0
322; CHECK-NEXT:    popq %rax
323; CHECK-NEXT:    .cfi_def_cfa_offset 8
324; CHECK-NEXT:    retq
325;
326; CHECK-O0-LABEL: test5:
327; CHECK-O0:       # %bb.0: # %entry
328; CHECK-O0-NEXT:    pushq %rax
329; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
330; CHECK-O0-NEXT:    callq gen5@PLT
331; CHECK-O0-NEXT:    addsd %xmm1, %xmm0
332; CHECK-O0-NEXT:    addsd %xmm2, %xmm0
333; CHECK-O0-NEXT:    addsd %xmm3, %xmm0
334; CHECK-O0-NEXT:    popq %rax
335; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
336; CHECK-O0-NEXT:    retq
337entry:
338  %call = call swiftcc { double, double, double, double } @gen5()
339
340  %v3 = extractvalue { double, double, double, double } %call, 0
341  %v5 = extractvalue { double, double, double, double } %call, 1
342  %v6 = extractvalue { double, double, double, double } %call, 2
343  %v7 = extractvalue { double, double, double, double } %call, 3
344
345  %add = fadd double %v3, %v5
346  %add1 = fadd double %add, %v6
347  %add2 = fadd double %add1, %v7
348  ret double %add2
349}
350
351declare swiftcc { double, double, double, double } @gen5()
352
353
354define swiftcc { double, i64 } @test6() #0 {
355; CHECK-LABEL: test6:
356; CHECK:       # %bb.0: # %entry
357; CHECK-NEXT:    pushq %rax
358; CHECK-NEXT:    .cfi_def_cfa_offset 16
359; CHECK-NEXT:    callq gen6@PLT
360; CHECK-NEXT:    addsd %xmm1, %xmm0
361; CHECK-NEXT:    addsd %xmm2, %xmm0
362; CHECK-NEXT:    addsd %xmm3, %xmm0
363; CHECK-NEXT:    addq %rdx, %rax
364; CHECK-NEXT:    addq %r8, %rcx
365; CHECK-NEXT:    addq %rcx, %rax
366; CHECK-NEXT:    popq %rcx
367; CHECK-NEXT:    .cfi_def_cfa_offset 8
368; CHECK-NEXT:    retq
369;
370; CHECK-O0-LABEL: test6:
371; CHECK-O0:       # %bb.0: # %entry
372; CHECK-O0-NEXT:    pushq %rax
373; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
374; CHECK-O0-NEXT:    callq gen6@PLT
375; CHECK-O0-NEXT:    addsd %xmm1, %xmm0
376; CHECK-O0-NEXT:    addsd %xmm2, %xmm0
377; CHECK-O0-NEXT:    addsd %xmm3, %xmm0
378; CHECK-O0-NEXT:    addq %rdx, %rax
379; CHECK-O0-NEXT:    addq %rcx, %rax
380; CHECK-O0-NEXT:    addq %r8, %rax
381; CHECK-O0-NEXT:    popq %rcx
382; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
383; CHECK-O0-NEXT:    retq
384entry:
385  %call = call swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen6()
386
387  %v3 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 0
388  %v5 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 1
389  %v6 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 2
390  %v7 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 3
391  %v3.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 4
392  %v5.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 5
393  %v6.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 6
394  %v7.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 7
395
396  %add = fadd double %v3, %v5
397  %add1 = fadd double %add, %v6
398  %add2 = fadd double %add1, %v7
399
400  %add.i = add nsw i64 %v3.i, %v5.i
401  %add1.i = add nsw i64 %add.i, %v6.i
402  %add2.i = add nsw i64 %add1.i, %v7.i
403
404  %Y = insertvalue { double, i64 } undef, double %add2, 0
405  %Z = insertvalue { double, i64 } %Y, i64 %add2.i, 1
406  ret { double, i64} %Z
407}
408
409declare swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen6()
410
411define swiftcc { i32, i32, i32, i32 } @gen7(i32 %key) {
412; CHECK-LABEL: gen7:
413; CHECK:       # %bb.0:
414; CHECK-NEXT:    movl %edi, %eax
415; CHECK-NEXT:    movl %edi, %edx
416; CHECK-NEXT:    movl %edi, %ecx
417; CHECK-NEXT:    movl %edi, %r8d
418; CHECK-NEXT:    retq
419;
420; CHECK-O0-LABEL: gen7:
421; CHECK-O0:       # %bb.0:
422; CHECK-O0-NEXT:    movl %edi, %r8d
423; CHECK-O0-NEXT:    movl %r8d, %eax
424; CHECK-O0-NEXT:    movl %r8d, %edx
425; CHECK-O0-NEXT:    movl %r8d, %ecx
426; CHECK-O0-NEXT:    retq
427  %v0 = insertvalue { i32, i32, i32, i32 } undef, i32 %key, 0
428  %v1 = insertvalue { i32, i32, i32, i32 } %v0, i32 %key, 1
429  %v2 = insertvalue { i32, i32, i32, i32 } %v1, i32 %key, 2
430  %v3 = insertvalue { i32, i32, i32, i32 } %v2, i32 %key, 3
431  ret { i32, i32, i32, i32 } %v3
432}
433
434define swiftcc { i64, i64, i64, i64 } @gen8(i64 %key) {
435; CHECK-LABEL: gen8:
436; CHECK:       # %bb.0:
437; CHECK-NEXT:    movq %rdi, %rax
438; CHECK-NEXT:    movq %rdi, %rdx
439; CHECK-NEXT:    movq %rdi, %rcx
440; CHECK-NEXT:    movq %rdi, %r8
441; CHECK-NEXT:    retq
442;
443; CHECK-O0-LABEL: gen8:
444; CHECK-O0:       # %bb.0:
445; CHECK-O0-NEXT:    movq %rdi, %r8
446; CHECK-O0-NEXT:    movq %r8, %rax
447; CHECK-O0-NEXT:    movq %r8, %rdx
448; CHECK-O0-NEXT:    movq %r8, %rcx
449; CHECK-O0-NEXT:    retq
450  %v0 = insertvalue { i64, i64, i64, i64 } undef, i64 %key, 0
451  %v1 = insertvalue { i64, i64, i64, i64 } %v0, i64 %key, 1
452  %v2 = insertvalue { i64, i64, i64, i64 } %v1, i64 %key, 2
453  %v3 = insertvalue { i64, i64, i64, i64 } %v2, i64 %key, 3
454  ret { i64, i64, i64, i64 } %v3
455}
456
457define swiftcc { i8, i8, i8, i8 } @gen9(i8 %key) {
458; CHECK-LABEL: gen9:
459; CHECK:       # %bb.0:
460; CHECK-NEXT:    movl %edi, %eax
461; CHECK-NEXT:    movl %eax, %edx
462; CHECK-NEXT:    movl %eax, %ecx
463; CHECK-NEXT:    movl %eax, %r8d
464; CHECK-NEXT:    retq
465;
466; CHECK-O0-LABEL: gen9:
467; CHECK-O0:       # %bb.0:
468; CHECK-O0-NEXT:    movb %dil, %r8b
469; CHECK-O0-NEXT:    movb %r8b, %al
470; CHECK-O0-NEXT:    movb %r8b, %dl
471; CHECK-O0-NEXT:    movb %r8b, %cl
472; CHECK-O0-NEXT:    retq
473  %v0 = insertvalue { i8, i8, i8, i8 } undef, i8 %key, 0
474  %v1 = insertvalue { i8, i8, i8, i8 } %v0, i8 %key, 1
475  %v2 = insertvalue { i8, i8, i8, i8 } %v1, i8 %key, 2
476  %v3 = insertvalue { i8, i8, i8, i8 } %v2, i8 %key, 3
477  ret { i8, i8, i8, i8 } %v3
478}
479define swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen10(double %keyd, i64 %keyi) {
480; CHECK-LABEL: gen10:
481; CHECK:       # %bb.0:
482; CHECK-NEXT:    movq %rdi, %rax
483; CHECK-NEXT:    movaps %xmm0, %xmm1
484; CHECK-NEXT:    movaps %xmm0, %xmm2
485; CHECK-NEXT:    movaps %xmm0, %xmm3
486; CHECK-NEXT:    movq %rdi, %rdx
487; CHECK-NEXT:    movq %rdi, %rcx
488; CHECK-NEXT:    movq %rdi, %r8
489; CHECK-NEXT:    retq
490;
491; CHECK-O0-LABEL: gen10:
492; CHECK-O0:       # %bb.0:
493; CHECK-O0-NEXT:    movq %rdi, %r8
494; CHECK-O0-NEXT:    movaps %xmm0, %xmm3
495; CHECK-O0-NEXT:    movaps %xmm3, %xmm0
496; CHECK-O0-NEXT:    movaps %xmm3, %xmm1
497; CHECK-O0-NEXT:    movaps %xmm3, %xmm2
498; CHECK-O0-NEXT:    movq %r8, %rax
499; CHECK-O0-NEXT:    movq %r8, %rdx
500; CHECK-O0-NEXT:    movq %r8, %rcx
501; CHECK-O0-NEXT:    retq
502  %v0 = insertvalue { double, double, double, double, i64, i64, i64, i64 } undef, double %keyd, 0
503  %v1 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v0, double %keyd, 1
504  %v2 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v1, double %keyd, 2
505  %v3 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v2, double %keyd, 3
506  %v4 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v3, i64 %keyi, 4
507  %v5 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v4, i64 %keyi, 5
508  %v6 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v5, i64 %keyi, 6
509  %v7 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v6, i64 %keyi, 7
510  ret { double, double, double, double, i64, i64, i64, i64 } %v7
511}
512
513
514define swiftcc <4 x float> @test11() #0 {
515; CHECK-LABEL: test11:
516; CHECK:       # %bb.0: # %entry
517; CHECK-NEXT:    pushq %rax
518; CHECK-NEXT:    .cfi_def_cfa_offset 16
519; CHECK-NEXT:    callq gen11@PLT
520; CHECK-NEXT:    addps %xmm1, %xmm0
521; CHECK-NEXT:    addps %xmm2, %xmm0
522; CHECK-NEXT:    addps %xmm3, %xmm0
523; CHECK-NEXT:    popq %rax
524; CHECK-NEXT:    .cfi_def_cfa_offset 8
525; CHECK-NEXT:    retq
526;
527; CHECK-O0-LABEL: test11:
528; CHECK-O0:       # %bb.0: # %entry
529; CHECK-O0-NEXT:    pushq %rax
530; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
531; CHECK-O0-NEXT:    callq gen11@PLT
532; CHECK-O0-NEXT:    addps %xmm1, %xmm0
533; CHECK-O0-NEXT:    addps %xmm2, %xmm0
534; CHECK-O0-NEXT:    addps %xmm3, %xmm0
535; CHECK-O0-NEXT:    popq %rax
536; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
537; CHECK-O0-NEXT:    retq
538entry:
539  %call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11()
540
541  %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 0
542  %v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 1
543  %v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 2
544  %v7 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 3
545
546  %add = fadd <4 x float> %v3, %v5
547  %add1 = fadd <4 x float> %add, %v6
548  %add2 = fadd <4 x float> %add1, %v7
549  ret <4 x float> %add2
550}
551
552declare swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11()
553
554define swiftcc { <4 x float>, float } @test12() #0 {
555; CHECK-LABEL: test12:
556; CHECK:       # %bb.0: # %entry
557; CHECK-NEXT:    pushq %rax
558; CHECK-NEXT:    .cfi_def_cfa_offset 16
559; CHECK-NEXT:    callq gen12@PLT
560; CHECK-NEXT:    addps %xmm1, %xmm0
561; CHECK-NEXT:    addps %xmm2, %xmm0
562; CHECK-NEXT:    movaps %xmm3, %xmm1
563; CHECK-NEXT:    popq %rax
564; CHECK-NEXT:    .cfi_def_cfa_offset 8
565; CHECK-NEXT:    retq
566;
567; CHECK-O0-LABEL: test12:
568; CHECK-O0:       # %bb.0: # %entry
569; CHECK-O0-NEXT:    subq $24, %rsp
570; CHECK-O0-NEXT:    .cfi_def_cfa_offset 32
571; CHECK-O0-NEXT:    callq gen12@PLT
572; CHECK-O0-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
573; CHECK-O0-NEXT:    movaps %xmm3, %xmm1
574; CHECK-O0-NEXT:    movaps (%rsp), %xmm3 # 16-byte Reload
575; CHECK-O0-NEXT:    addps %xmm3, %xmm0
576; CHECK-O0-NEXT:    addps %xmm2, %xmm0
577; CHECK-O0-NEXT:    addq $24, %rsp
578; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
579; CHECK-O0-NEXT:    retq
580entry:
581  %call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12()
582
583  %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 0
584  %v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 1
585  %v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 2
586  %v8 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 3
587
588  %add = fadd <4 x float> %v3, %v5
589  %add1 = fadd <4 x float> %add, %v6
590  %res.0 = insertvalue { <4 x float>, float } undef, <4 x float> %add1, 0
591  %res = insertvalue { <4 x float>, float } %res.0, float %v8, 1
592  ret { <4 x float>, float } %res
593}
594
595declare swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12()
596