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, i32* %key.addr, align 4
41  %0 = load i32, i32* %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, i32* %key.addr, align 4
97  %0 = load i32, i32* %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:    addl %edx, %eax
151; CHECK-NEXT:    addl %ecx, %eax
152; CHECK-NEXT:    addl %r8d, %eax
153; CHECK-NEXT:    popq %rcx
154; CHECK-NEXT:    .cfi_def_cfa_offset 8
155; CHECK-NEXT:    retq
156;
157; CHECK-O0-LABEL: test3:
158; CHECK-O0:       # %bb.0: # %entry
159; CHECK-O0-NEXT:    pushq %rax
160; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
161; CHECK-O0-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
162; CHECK-O0-NEXT:    movl {{[0-9]+}}(%rsp), %edi
163; CHECK-O0-NEXT:    callq gen3@PLT
164; CHECK-O0-NEXT:    addl %edx, %eax
165; CHECK-O0-NEXT:    addl %ecx, %eax
166; CHECK-O0-NEXT:    addl %r8d, %eax
167; CHECK-O0-NEXT:    popq %rcx
168; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
169; CHECK-O0-NEXT:    retq
170entry:
171  %key.addr = alloca i32, align 4
172  store i32 %key, i32* %key.addr, align 4
173  %0 = load i32, i32* %key.addr, align 4
174  %call = call swiftcc { i32, i32, i32, i32 } @gen3(i32 %0)
175
176  %v3 = extractvalue { i32, i32, i32, i32 } %call, 0
177  %v5 = extractvalue { i32, i32, i32, i32 } %call, 1
178  %v6 = extractvalue { i32, i32, i32, i32 } %call, 2
179  %v7 = extractvalue { i32, i32, i32, i32 } %call, 3
180
181  %add = add nsw i32 %v3, %v5
182  %add1 = add nsw i32 %add, %v6
183  %add2 = add nsw i32 %add1, %v7
184  ret i32 %add2
185}
186
187declare swiftcc { i32, i32, i32, i32 } @gen3(i32 %key)
188
189; The return value {float, float, float, float} will be returned via registers
190; %xmm0, %xmm1, %xmm2, %xmm3.
191define dso_local float @test4(float %key) #0 {
192; CHECK-LABEL: test4:
193; CHECK:       # %bb.0: # %entry
194; CHECK-NEXT:    pushq %rax
195; CHECK-NEXT:    .cfi_def_cfa_offset 16
196; CHECK-NEXT:    movss %xmm0, {{[0-9]+}}(%rsp)
197; CHECK-NEXT:    callq gen4@PLT
198; CHECK-NEXT:    addss %xmm1, %xmm0
199; CHECK-NEXT:    addss %xmm2, %xmm0
200; CHECK-NEXT:    addss %xmm3, %xmm0
201; CHECK-NEXT:    popq %rax
202; CHECK-NEXT:    .cfi_def_cfa_offset 8
203; CHECK-NEXT:    retq
204;
205; CHECK-O0-LABEL: test4:
206; CHECK-O0:       # %bb.0: # %entry
207; CHECK-O0-NEXT:    pushq %rax
208; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
209; CHECK-O0-NEXT:    movss %xmm0, {{[0-9]+}}(%rsp)
210; CHECK-O0-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
211; CHECK-O0-NEXT:    callq gen4@PLT
212; CHECK-O0-NEXT:    addss %xmm1, %xmm0
213; CHECK-O0-NEXT:    addss %xmm2, %xmm0
214; CHECK-O0-NEXT:    addss %xmm3, %xmm0
215; CHECK-O0-NEXT:    popq %rax
216; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
217; CHECK-O0-NEXT:    retq
218entry:
219  %key.addr = alloca float, align 4
220  store float %key, float* %key.addr, align 4
221  %0 = load float, float* %key.addr, align 4
222  %call = call swiftcc { float, float, float, float } @gen4(float %0)
223
224  %v3 = extractvalue { float, float, float, float } %call, 0
225  %v5 = extractvalue { float, float, float, float } %call, 1
226  %v6 = extractvalue { float, float, float, float } %call, 2
227  %v7 = extractvalue { float, float, float, float } %call, 3
228
229  %add = fadd float %v3, %v5
230  %add1 = fadd float %add, %v6
231  %add2 = fadd float %add1, %v7
232  ret float %add2
233}
234
235declare swiftcc { float, float, float, float } @gen4(float %key)
236
237define dso_local void @consume_i1_ret() {
238; CHECK-LABEL: consume_i1_ret:
239; CHECK:       # %bb.0:
240; CHECK-NEXT:    pushq %rax
241; CHECK-NEXT:    .cfi_def_cfa_offset 16
242; CHECK-NEXT:    callq produce_i1_ret@PLT
243; CHECK-NEXT:    movzbl %al, %eax
244; CHECK-NEXT:    andl $1, %eax
245; CHECK-NEXT:    movl %eax, var(%rip)
246; CHECK-NEXT:    movzbl %dl, %eax
247; CHECK-NEXT:    andl $1, %eax
248; CHECK-NEXT:    movl %eax, var(%rip)
249; CHECK-NEXT:    movzbl %cl, %eax
250; CHECK-NEXT:    andl $1, %eax
251; CHECK-NEXT:    movl %eax, var(%rip)
252; CHECK-NEXT:    movzbl %r8b, %eax
253; CHECK-NEXT:    andl $1, %eax
254; CHECK-NEXT:    movl %eax, var(%rip)
255; CHECK-NEXT:    popq %rax
256; CHECK-NEXT:    .cfi_def_cfa_offset 8
257; CHECK-NEXT:    retq
258;
259; CHECK-O0-LABEL: consume_i1_ret:
260; CHECK-O0:       # %bb.0:
261; CHECK-O0-NEXT:    pushq %rax
262; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
263; CHECK-O0-NEXT:    callq produce_i1_ret@PLT
264; CHECK-O0-NEXT:    andb $1, %al
265; CHECK-O0-NEXT:    movzbl %al, %eax
266; CHECK-O0-NEXT:    movl %eax, var
267; CHECK-O0-NEXT:    andb $1, %dl
268; CHECK-O0-NEXT:    movzbl %dl, %eax
269; CHECK-O0-NEXT:    movl %eax, var
270; CHECK-O0-NEXT:    andb $1, %cl
271; CHECK-O0-NEXT:    movzbl %cl, %eax
272; CHECK-O0-NEXT:    movl %eax, var
273; CHECK-O0-NEXT:    andb $1, %r8b
274; CHECK-O0-NEXT:    movzbl %r8b, %eax
275; CHECK-O0-NEXT:    movl %eax, var
276; CHECK-O0-NEXT:    popq %rax
277; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
278; CHECK-O0-NEXT:    retq
279  %call = call swiftcc { i1, i1, i1, i1 } @produce_i1_ret()
280  %v3 = extractvalue { i1, i1, i1, i1 } %call, 0
281  %v5 = extractvalue { i1, i1, i1, i1 } %call, 1
282  %v6 = extractvalue { i1, i1, i1, i1 } %call, 2
283  %v7 = extractvalue { i1, i1, i1, i1 } %call, 3
284  %val = zext i1 %v3 to i32
285  store volatile i32 %val, i32* @var
286  %val2 = zext i1 %v5 to i32
287  store volatile i32 %val2, i32* @var
288  %val3 = zext i1 %v6 to i32
289  store volatile i32 %val3, i32* @var
290  %val4 = zext i1 %v7 to i32
291  store i32 %val4, i32* @var
292  ret void
293}
294
295declare swiftcc { i1, i1, i1, i1 } @produce_i1_ret()
296
297define swiftcc void @foo(i64* sret(i64) %agg.result, i64 %val) {
298; CHECK-LABEL: foo:
299; CHECK:       # %bb.0:
300; CHECK-NEXT:    movq %rdi, (%rax)
301; CHECK-NEXT:    retq
302;
303; CHECK-O0-LABEL: foo:
304; CHECK-O0:       # %bb.0:
305; CHECK-O0-NEXT:    movq %rdi, (%rax)
306; CHECK-O0-NEXT:    retq
307  store i64 %val, i64* %agg.result
308  ret void
309}
310
311define swiftcc double @test5() #0 {
312; CHECK-LABEL: test5:
313; CHECK:       # %bb.0: # %entry
314; CHECK-NEXT:    pushq %rax
315; CHECK-NEXT:    .cfi_def_cfa_offset 16
316; CHECK-NEXT:    callq gen5@PLT
317; CHECK-NEXT:    addsd %xmm1, %xmm0
318; CHECK-NEXT:    addsd %xmm2, %xmm0
319; CHECK-NEXT:    addsd %xmm3, %xmm0
320; CHECK-NEXT:    popq %rax
321; CHECK-NEXT:    .cfi_def_cfa_offset 8
322; CHECK-NEXT:    retq
323;
324; CHECK-O0-LABEL: test5:
325; CHECK-O0:       # %bb.0: # %entry
326; CHECK-O0-NEXT:    pushq %rax
327; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
328; CHECK-O0-NEXT:    callq gen5@PLT
329; CHECK-O0-NEXT:    addsd %xmm1, %xmm0
330; CHECK-O0-NEXT:    addsd %xmm2, %xmm0
331; CHECK-O0-NEXT:    addsd %xmm3, %xmm0
332; CHECK-O0-NEXT:    popq %rax
333; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
334; CHECK-O0-NEXT:    retq
335entry:
336  %call = call swiftcc { double, double, double, double } @gen5()
337
338  %v3 = extractvalue { double, double, double, double } %call, 0
339  %v5 = extractvalue { double, double, double, double } %call, 1
340  %v6 = extractvalue { double, double, double, double } %call, 2
341  %v7 = extractvalue { double, double, double, double } %call, 3
342
343  %add = fadd double %v3, %v5
344  %add1 = fadd double %add, %v6
345  %add2 = fadd double %add1, %v7
346  ret double %add2
347}
348
349declare swiftcc { double, double, double, double } @gen5()
350
351
352define swiftcc { double, i64 } @test6() #0 {
353; CHECK-LABEL: test6:
354; CHECK:       # %bb.0: # %entry
355; CHECK-NEXT:    pushq %rax
356; CHECK-NEXT:    .cfi_def_cfa_offset 16
357; CHECK-NEXT:    callq gen6@PLT
358; CHECK-NEXT:    addsd %xmm1, %xmm0
359; CHECK-NEXT:    addsd %xmm2, %xmm0
360; CHECK-NEXT:    addsd %xmm3, %xmm0
361; CHECK-NEXT:    addq %rdx, %rax
362; CHECK-NEXT:    addq %rcx, %rax
363; CHECK-NEXT:    addq %r8, %rax
364; CHECK-NEXT:    popq %rcx
365; CHECK-NEXT:    .cfi_def_cfa_offset 8
366; CHECK-NEXT:    retq
367;
368; CHECK-O0-LABEL: test6:
369; CHECK-O0:       # %bb.0: # %entry
370; CHECK-O0-NEXT:    pushq %rax
371; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
372; CHECK-O0-NEXT:    callq gen6@PLT
373; CHECK-O0-NEXT:    addsd %xmm1, %xmm0
374; CHECK-O0-NEXT:    addsd %xmm2, %xmm0
375; CHECK-O0-NEXT:    addsd %xmm3, %xmm0
376; CHECK-O0-NEXT:    addq %rdx, %rax
377; CHECK-O0-NEXT:    addq %rcx, %rax
378; CHECK-O0-NEXT:    addq %r8, %rax
379; CHECK-O0-NEXT:    popq %rcx
380; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
381; CHECK-O0-NEXT:    retq
382entry:
383  %call = call swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen6()
384
385  %v3 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 0
386  %v5 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 1
387  %v6 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 2
388  %v7 = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 3
389  %v3.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 4
390  %v5.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 5
391  %v6.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 6
392  %v7.i = extractvalue { double, double, double, double, i64, i64, i64, i64 } %call, 7
393
394  %add = fadd double %v3, %v5
395  %add1 = fadd double %add, %v6
396  %add2 = fadd double %add1, %v7
397
398  %add.i = add nsw i64 %v3.i, %v5.i
399  %add1.i = add nsw i64 %add.i, %v6.i
400  %add2.i = add nsw i64 %add1.i, %v7.i
401
402  %Y = insertvalue { double, i64 } undef, double %add2, 0
403  %Z = insertvalue { double, i64 } %Y, i64 %add2.i, 1
404  ret { double, i64} %Z
405}
406
407declare swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen6()
408
409define swiftcc { i32, i32, i32, i32 } @gen7(i32 %key) {
410; CHECK-LABEL: gen7:
411; CHECK:       # %bb.0:
412; CHECK-NEXT:    movl %edi, %eax
413; CHECK-NEXT:    movl %edi, %edx
414; CHECK-NEXT:    movl %edi, %ecx
415; CHECK-NEXT:    movl %edi, %r8d
416; CHECK-NEXT:    retq
417;
418; CHECK-O0-LABEL: gen7:
419; CHECK-O0:       # %bb.0:
420; CHECK-O0-NEXT:    movl %edi, %r8d
421; CHECK-O0-NEXT:    movl %r8d, %eax
422; CHECK-O0-NEXT:    movl %r8d, %edx
423; CHECK-O0-NEXT:    movl %r8d, %ecx
424; CHECK-O0-NEXT:    retq
425  %v0 = insertvalue { i32, i32, i32, i32 } undef, i32 %key, 0
426  %v1 = insertvalue { i32, i32, i32, i32 } %v0, i32 %key, 1
427  %v2 = insertvalue { i32, i32, i32, i32 } %v1, i32 %key, 2
428  %v3 = insertvalue { i32, i32, i32, i32 } %v2, i32 %key, 3
429  ret { i32, i32, i32, i32 } %v3
430}
431
432define swiftcc { i64, i64, i64, i64 } @gen8(i64 %key) {
433; CHECK-LABEL: gen8:
434; CHECK:       # %bb.0:
435; CHECK-NEXT:    movq %rdi, %rax
436; CHECK-NEXT:    movq %rdi, %rdx
437; CHECK-NEXT:    movq %rdi, %rcx
438; CHECK-NEXT:    movq %rdi, %r8
439; CHECK-NEXT:    retq
440;
441; CHECK-O0-LABEL: gen8:
442; CHECK-O0:       # %bb.0:
443; CHECK-O0-NEXT:    movq %rdi, %r8
444; CHECK-O0-NEXT:    movq %r8, %rax
445; CHECK-O0-NEXT:    movq %r8, %rdx
446; CHECK-O0-NEXT:    movq %r8, %rcx
447; CHECK-O0-NEXT:    retq
448  %v0 = insertvalue { i64, i64, i64, i64 } undef, i64 %key, 0
449  %v1 = insertvalue { i64, i64, i64, i64 } %v0, i64 %key, 1
450  %v2 = insertvalue { i64, i64, i64, i64 } %v1, i64 %key, 2
451  %v3 = insertvalue { i64, i64, i64, i64 } %v2, i64 %key, 3
452  ret { i64, i64, i64, i64 } %v3
453}
454
455define swiftcc { i8, i8, i8, i8 } @gen9(i8 %key) {
456; CHECK-LABEL: gen9:
457; CHECK:       # %bb.0:
458; CHECK-NEXT:    movl %edi, %eax
459; CHECK-NEXT:    movl %eax, %edx
460; CHECK-NEXT:    movl %eax, %ecx
461; CHECK-NEXT:    movl %eax, %r8d
462; CHECK-NEXT:    retq
463;
464; CHECK-O0-LABEL: gen9:
465; CHECK-O0:       # %bb.0:
466; CHECK-O0-NEXT:    movb %dil, %r8b
467; CHECK-O0-NEXT:    movb %r8b, %al
468; CHECK-O0-NEXT:    movb %r8b, %dl
469; CHECK-O0-NEXT:    movb %r8b, %cl
470; CHECK-O0-NEXT:    retq
471  %v0 = insertvalue { i8, i8, i8, i8 } undef, i8 %key, 0
472  %v1 = insertvalue { i8, i8, i8, i8 } %v0, i8 %key, 1
473  %v2 = insertvalue { i8, i8, i8, i8 } %v1, i8 %key, 2
474  %v3 = insertvalue { i8, i8, i8, i8 } %v2, i8 %key, 3
475  ret { i8, i8, i8, i8 } %v3
476}
477define swiftcc { double, double, double, double, i64, i64, i64, i64 } @gen10(double %keyd, i64 %keyi) {
478; CHECK-LABEL: gen10:
479; CHECK:       # %bb.0:
480; CHECK-NEXT:    movq %rdi, %rax
481; CHECK-NEXT:    movaps %xmm0, %xmm1
482; CHECK-NEXT:    movaps %xmm0, %xmm2
483; CHECK-NEXT:    movaps %xmm0, %xmm3
484; CHECK-NEXT:    movq %rdi, %rdx
485; CHECK-NEXT:    movq %rdi, %rcx
486; CHECK-NEXT:    movq %rdi, %r8
487; CHECK-NEXT:    retq
488;
489; CHECK-O0-LABEL: gen10:
490; CHECK-O0:       # %bb.0:
491; CHECK-O0-NEXT:    movq %rdi, %r8
492; CHECK-O0-NEXT:    movaps %xmm0, %xmm3
493; CHECK-O0-NEXT:    movaps %xmm3, %xmm0
494; CHECK-O0-NEXT:    movaps %xmm3, %xmm1
495; CHECK-O0-NEXT:    movaps %xmm3, %xmm2
496; CHECK-O0-NEXT:    movq %r8, %rax
497; CHECK-O0-NEXT:    movq %r8, %rdx
498; CHECK-O0-NEXT:    movq %r8, %rcx
499; CHECK-O0-NEXT:    retq
500  %v0 = insertvalue { double, double, double, double, i64, i64, i64, i64 } undef, double %keyd, 0
501  %v1 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v0, double %keyd, 1
502  %v2 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v1, double %keyd, 2
503  %v3 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v2, double %keyd, 3
504  %v4 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v3, i64 %keyi, 4
505  %v5 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v4, i64 %keyi, 5
506  %v6 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v5, i64 %keyi, 6
507  %v7 = insertvalue { double, double, double, double, i64, i64, i64, i64 } %v6, i64 %keyi, 7
508  ret { double, double, double, double, i64, i64, i64, i64 } %v7
509}
510
511
512define swiftcc <4 x float> @test11() #0 {
513; CHECK-LABEL: test11:
514; CHECK:       # %bb.0: # %entry
515; CHECK-NEXT:    pushq %rax
516; CHECK-NEXT:    .cfi_def_cfa_offset 16
517; CHECK-NEXT:    callq gen11@PLT
518; CHECK-NEXT:    addps %xmm1, %xmm0
519; CHECK-NEXT:    addps %xmm2, %xmm0
520; CHECK-NEXT:    addps %xmm3, %xmm0
521; CHECK-NEXT:    popq %rax
522; CHECK-NEXT:    .cfi_def_cfa_offset 8
523; CHECK-NEXT:    retq
524;
525; CHECK-O0-LABEL: test11:
526; CHECK-O0:       # %bb.0: # %entry
527; CHECK-O0-NEXT:    pushq %rax
528; CHECK-O0-NEXT:    .cfi_def_cfa_offset 16
529; CHECK-O0-NEXT:    callq gen11@PLT
530; CHECK-O0-NEXT:    addps %xmm1, %xmm0
531; CHECK-O0-NEXT:    addps %xmm2, %xmm0
532; CHECK-O0-NEXT:    addps %xmm3, %xmm0
533; CHECK-O0-NEXT:    popq %rax
534; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
535; CHECK-O0-NEXT:    retq
536entry:
537  %call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11()
538
539  %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 0
540  %v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 1
541  %v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 2
542  %v7 = extractvalue { <4 x float>, <4 x float>, <4 x float>, <4 x float> } %call, 3
543
544  %add = fadd <4 x float> %v3, %v5
545  %add1 = fadd <4 x float> %add, %v6
546  %add2 = fadd <4 x float> %add1, %v7
547  ret <4 x float> %add2
548}
549
550declare swiftcc { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @gen11()
551
552define swiftcc { <4 x float>, float } @test12() #0 {
553; CHECK-LABEL: test12:
554; CHECK:       # %bb.0: # %entry
555; CHECK-NEXT:    pushq %rax
556; CHECK-NEXT:    .cfi_def_cfa_offset 16
557; CHECK-NEXT:    callq gen12@PLT
558; CHECK-NEXT:    addps %xmm1, %xmm0
559; CHECK-NEXT:    addps %xmm2, %xmm0
560; CHECK-NEXT:    movaps %xmm3, %xmm1
561; CHECK-NEXT:    popq %rax
562; CHECK-NEXT:    .cfi_def_cfa_offset 8
563; CHECK-NEXT:    retq
564;
565; CHECK-O0-LABEL: test12:
566; CHECK-O0:       # %bb.0: # %entry
567; CHECK-O0-NEXT:    subq $24, %rsp
568; CHECK-O0-NEXT:    .cfi_def_cfa_offset 32
569; CHECK-O0-NEXT:    callq gen12@PLT
570; CHECK-O0-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
571; CHECK-O0-NEXT:    movaps %xmm3, %xmm1
572; CHECK-O0-NEXT:    movaps (%rsp), %xmm3 # 16-byte Reload
573; CHECK-O0-NEXT:    addps %xmm3, %xmm0
574; CHECK-O0-NEXT:    addps %xmm2, %xmm0
575; CHECK-O0-NEXT:    addq $24, %rsp
576; CHECK-O0-NEXT:    .cfi_def_cfa_offset 8
577; CHECK-O0-NEXT:    retq
578entry:
579  %call = call swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12()
580
581  %v3 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 0
582  %v5 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 1
583  %v6 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 2
584  %v8 = extractvalue { <4 x float>, <4 x float>, <4 x float>, float } %call, 3
585
586  %add = fadd <4 x float> %v3, %v5
587  %add1 = fadd <4 x float> %add, %v6
588  %res.0 = insertvalue { <4 x float>, float } undef, <4 x float> %add1, 0
589  %res = insertvalue { <4 x float>, float } %res.0, float %v8, 1
590  ret { <4 x float>, float } %res
591}
592
593declare swiftcc { <4 x float>, <4 x float>, <4 x float>, float } @gen12()
594