• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; This file checks that Subzero generates code in accordance with the
2; calling convention for vectors.
3
4; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \
5; RUN:   -allow-externally-defined-symbols | FileCheck %s
6; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 \
7; RUN:   -allow-externally-defined-symbols | FileCheck --check-prefix=OPTM1 %s
8
9; RUN: %if --need=target_MIPS32 --need=allow_dump \
10; RUN:   --command %p2i --filetype=asm --assemble --disassemble --target \
11; RUN:   mips32 -i %s --args -O2 -allow-externally-defined-symbols \
12; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
13; RUN:   --command FileCheck --check-prefix MIPS32 %s
14
15; The first five functions test that vectors are moved from their
16; correct argument location to xmm0.
17
18define internal <4 x float> @test_returning_arg0(
19    <4 x float> %arg0, <4 x float> %arg1, <4 x float> %arg2, <4 x float> %arg3,
20    <4 x float> %arg4, <4 x float> %arg5) {
21entry:
22  ret <4 x float> %arg0
23; CHECK-LABEL: test_returning_arg0
24; CHECK-NOT: mov
25; CHECK: ret
26
27; OPTM1-LABEL: test_returning_arg0
28; OPTM1: movups XMMWORD PTR [[LOC:.*]],xmm0
29; OPTM1: movups xmm0,XMMWORD PTR [[LOC]]
30; OPTM1: ret
31; MIPS32-LABEL: test_returning_arg0
32; MIPS32: 	lw	v0,{{.*}}(sp)
33; MIPS32: 	lw	v1,{{.*}}(sp)
34; MIPS32: 	move	a1,a0
35; MIPS32: 	sw	a2,0(a1)
36; MIPS32: 	sw	a3,4(a1)
37; MIPS32: 	sw	v0,8(a1)
38; MIPS32: 	sw	v1,12(a1)
39; MIPS32: 	move	v0,a0
40}
41
42define internal <4 x float> @test_returning_arg1(
43    <4 x float> %arg0, <4 x float> %arg1, <4 x float> %arg2, <4 x float> %arg3,
44    <4 x float> %arg4, <4 x float> %arg5) {
45entry:
46  ret <4 x float> %arg1
47; CHECK-LABEL: test_returning_arg1
48; CHECK: movups xmm0,xmm1
49; CHECK: ret
50
51; OPTM1-LABEL: test_returning_arg1
52; OPTM1: movups XMMWORD PTR [[LOC:.*]],xmm1
53; OPTM1: movups xmm0,XMMWORD PTR [[LOC]]
54; OPTM1: ret
55; MIPS32-LABEL: test_returning_arg1
56; MIPS32: 	lw	v0,{{.*}}(sp)
57; MIPS32: 	lw	v1,{{.*}}(sp)
58; MIPS32: 	lw	a1,{{.*}}(sp)
59; MIPS32: 	lw	a2,{{.*}}(sp)
60; MIPS32: 	move	a3,a0
61; MIPS32: 	sw	v0,0(a3)
62; MIPS32: 	sw	v1,4(a3)
63; MIPS32: 	sw	a1,8(a3)
64; MIPS32: 	sw	a2,12(a3)
65; MIPS32: 	move	v0,a0
66}
67
68define internal <4 x float> @test_returning_arg2(
69    <4 x float> %arg0, <4 x float> %arg1, <4 x float> %arg2, <4 x float> %arg3,
70    <4 x float> %arg4, <4 x float> %arg5) {
71entry:
72  ret <4 x float> %arg2
73; CHECK-LABEL: test_returning_arg2
74; CHECK: movups xmm0,xmm2
75; CHECK: ret
76
77; OPTM1-LABEL: test_returning_arg2
78; OPTM1: movups XMMWORD PTR [[LOC:.*]],xmm2
79; OPTM1: movups xmm0,XMMWORD PTR [[LOC]]
80; OPTM1: ret
81; MIPS32-LABEL: test_returning_arg2
82; MIPS32: 	lw	v0,{{.*}}(sp)
83; MIPS32: 	lw	v1,{{.*}}(sp)
84; MIPS32: 	lw	a1,{{.*}}(sp)
85; MIPS32: 	lw	a2,{{.*}}(sp)
86; MIPS32: 	move	a3,a0
87; MIPS32: 	sw	v0,0(a3)
88; MIPS32: 	sw	v1,4(a3)
89; MIPS32: 	sw	a1,8(a3)
90; MIPS32: 	sw	a2,12(a3)
91; MIPS32: 	move	v0,a0
92}
93
94define internal <4 x float> @test_returning_arg3(
95    <4 x float> %arg0, <4 x float> %arg1, <4 x float> %arg2, <4 x float> %arg3,
96    <4 x float> %arg4, <4 x float> %arg5) {
97entry:
98  ret <4 x float> %arg3
99; CHECK-LABEL: test_returning_arg3
100; CHECK: movups xmm0,xmm3
101; CHECK: ret
102
103; OPTM1-LABEL: test_returning_arg3
104; OPTM1: movups XMMWORD PTR [[LOC:.*]],xmm3
105; OPTM1: movups xmm0,XMMWORD PTR [[LOC]]
106; OPTM1: ret
107; MIPS32-LABEL: test_returning_arg3
108; MIPS32: 	lw	v0,{{.*}}(sp)
109; MIPS32: 	lw	v1,{{.*}}(sp)
110; MIPS32: 	lw	a1,{{.*}}(sp)
111; MIPS32: 	lw	a2,{{.*}}(sp)
112; MIPS32: 	move	a3,a0
113; MIPS32: 	sw	v0,0(a3)
114; MIPS32: 	sw	v1,4(a3)
115; MIPS32: 	sw	a1,8(a3)
116; MIPS32: 	sw	a2,12(a3)
117; MIPS32: 	move	v0,a0
118}
119
120define internal <4 x float> @test_returning_arg4(
121    <4 x float> %arg0, <4 x float> %arg1, <4 x float> %arg2, <4 x float> %arg3,
122    <4 x float> %arg4, <4 x float> %arg5) {
123entry:
124  ret <4 x float> %arg4
125; CHECK-LABEL: test_returning_arg4
126; CHECK: movups xmm0,XMMWORD PTR [esp+0x4]
127; CHECK: ret
128
129; OPTM1-LABEL: test_returning_arg4
130; OPTM1: movups xmm0,XMMWORD PTR {{.*}}
131; OPTM1: ret
132; MIPS32-LABEL: test_returning_arg4
133; MIPS32: 	lw	v0,{{.*}}(sp)
134; MIPS32: 	lw	v1,{{.*}}(sp)
135; MIPS32: 	lw	a1,{{.*}}(sp)
136; MIPS32: 	lw	a2,{{.*}}(sp)
137; MIPS32: 	move	a3,a0
138; MIPS32: 	sw	v0,0(a3)
139; MIPS32: 	sw	v1,4(a3)
140; MIPS32: 	sw	a1,8(a3)
141; MIPS32: 	sw	a2,12(a3)
142; MIPS32: 	move	v0,a0
143}
144
145; The next five functions check that xmm arguments are handled
146; correctly when interspersed with stack arguments in the argument
147; list.
148
149define internal <4 x float> @test_returning_interspersed_arg0(
150    i32 %i32arg0, double %doublearg0, <4 x float> %arg0, <4 x float> %arg1,
151    i32 %i32arg1, <4 x float> %arg2, double %doublearg1, <4 x float> %arg3,
152    i32 %i32arg2, double %doublearg2, float %floatarg0, <4 x float> %arg4,
153     <4 x float> %arg5, float %floatarg1) {
154entry:
155  ret <4 x float> %arg0
156; CHECK-LABEL: test_returning_interspersed_arg0
157; CHECK-NOT: mov
158; CHECK: ret
159
160; OPTM1-LABEL: test_returning_interspersed_arg0
161; OPTM1: movups XMMWORD PTR [[LOC:.*]],xmm0
162; OPTM1: movups xmm0,XMMWORD PTR [[LOC]]
163; OPTM1: ret
164; MIPS32-LABEL: test_returning_interspersed_arg0
165; MIPS32: 	lw	v0,{{.*}}(sp)
166; MIPS32: 	lw	v1,{{.*}}(sp)
167; MIPS32: 	lw	a1,{{.*}}(sp)
168; MIPS32: 	lw	a2,{{.*}}(sp)
169; MIPS32: 	move	a3,a0
170; MIPS32: 	sw	v0,0(a3)
171; MIPS32: 	sw	v1,4(a3)
172; MIPS32: 	sw	a1,8(a3)
173; MIPS32: 	sw	a2,12(a3)
174; MIPS32: 	move	v0,a0
175}
176
177define internal <4 x float> @test_returning_interspersed_arg1(
178    i32 %i32arg0, double %doublearg0, <4 x float> %arg0, <4 x float> %arg1,
179    i32 %i32arg1, <4 x float> %arg2, double %doublearg1, <4 x float> %arg3,
180    i32 %i32arg2, double %doublearg2, float %floatarg0, <4 x float> %arg4,
181    <4 x float> %arg5, float %floatarg1) {
182entry:
183  ret <4 x float> %arg1
184; CHECK-LABEL: test_returning_interspersed_arg1
185; CHECK: movups xmm0,xmm1
186; CHECK: ret
187
188; OPTM1-LABEL: test_returning_interspersed_arg1
189; OPTM1: movups XMMWORD PTR [[LOC:.*]],xmm1
190; OPTM1: movups xmm0,XMMWORD PTR [[LOC]]
191; OPTM1: ret
192; MIPS32-LABEL: test_returning_interspersed_arg1
193; MIPS32: 	lw	v0,{{.*}}(sp)
194; MIPS32: 	lw	v1,{{.*}}(sp)
195; MIPS32: 	lw	a1,{{.*}}(sp)
196; MIPS32: 	lw	a2,{{.*}}(sp)
197; MIPS32: 	move	a3,a0
198; MIPS32: 	sw	v0,0(a3)
199; MIPS32: 	sw	v1,4(a3)
200; MIPS32: 	sw	a1,8(a3)
201; MIPS32: 	sw	a2,12(a3)
202; MIPS32: 	move	v0,a0
203}
204
205define internal <4 x float> @test_returning_interspersed_arg2(
206    i32 %i32arg0, double %doublearg0, <4 x float> %arg0, <4 x float> %arg1,
207    i32 %i32arg1, <4 x float> %arg2, double %doublearg1, <4 x float> %arg3,
208    i32 %i32arg2, double %doublearg2, float %floatarg0, <4 x float> %arg4,
209    <4 x float> %arg5, float %floatarg1) {
210entry:
211  ret <4 x float> %arg2
212; CHECK-LABEL: test_returning_interspersed_arg2
213; CHECK: movups xmm0,xmm2
214; CHECK: ret
215
216; OPTM1-LABEL: test_returning_interspersed_arg2
217; OPTM1: movups XMMWORD PTR [[LOC:.*]],xmm2
218; OPTM1: movups xmm0,XMMWORD PTR [[LOC]]
219; OPTM1: ret
220; MIPS32-LABEL: test_returning_interspersed_arg2
221; MIPS32: 	lw	v0,{{.*}}(sp)
222; MIPS32: 	lw	v1,{{.*}}(sp)
223; MIPS32: 	lw	a1,{{.*}}(sp)
224; MIPS32: 	lw	a2,{{.*}}(sp)
225; MIPS32: 	move	a3,a0
226; MIPS32: 	sw	v0,0(a3)
227; MIPS32: 	sw	v1,4(a3)
228; MIPS32: 	sw	a1,8(a3)
229; MIPS32: 	sw	a2,12(a3)
230; MIPS32: 	move	v0,a0
231}
232
233define internal <4 x float> @test_returning_interspersed_arg3(
234    i32 %i32arg0, double %doublearg0, <4 x float> %arg0, <4 x float> %arg1,
235    i32 %i32arg1, <4 x float> %arg2, double %doublearg1, <4 x float> %arg3,
236    i32 %i32arg2, double %doublearg2, float %floatarg0, <4 x float> %arg4,
237    <4 x float> %arg5, float %floatarg1) {
238entry:
239  ret <4 x float> %arg3
240; CHECK-LABEL: test_returning_interspersed_arg3
241; CHECK: movups xmm0,xmm3
242; CHECK: ret
243
244; OPTM1-LABEL: test_returning_interspersed_arg3
245; OPTM1: movups XMMWORD PTR [[LOC:.*]],xmm3
246; OPTM1: movups xmm0,XMMWORD PTR [[LOC]]
247; OPTM1: ret
248; MIPS32-LABEL: test_returning_interspersed_arg3
249; MIPS32: 	lw	v0,{{.*}}(sp)
250; MIPS32: 	lw	v1,{{.*}}(sp)
251; MIPS32: 	lw	a1,{{.*}}(sp)
252; MIPS32: 	lw	a2,{{.*}}(sp)
253; MIPS32: 	move	a3,a0
254; MIPS32: 	sw	v0,0(a3)
255; MIPS32: 	sw	v1,4(a3)
256; MIPS32: 	sw	a1,8(a3)
257; MIPS32: 	sw	a2,12(a3)
258; MIPS32: 	move	v0,a0
259
260}
261
262define internal <4 x float> @test_returning_interspersed_arg4(
263    i32 %i32arg0, double %doublearg0, <4 x float> %arg0, <4 x float> %arg1,
264    i32 %i32arg1, <4 x float> %arg2, double %doublearg1, <4 x float> %arg3,
265    i32 %i32arg2, double %doublearg2, float %floatarg0, <4 x float> %arg4,
266    <4 x float> %arg5, float %floatarg1) {
267entry:
268  ret <4 x float> %arg4
269; CHECK-LABEL: test_returning_interspersed_arg4
270; CHECK: movups xmm0,XMMWORD PTR [esp+0x34]
271; CHECK: ret
272
273; OPTM1-LABEL: test_returning_interspersed_arg4
274; OPTM1: movups xmm0,XMMWORD PTR {{.*}}
275; OPTM1: ret
276; MIPS32-LABEL: test_returning_interspersed_arg4
277; MIPS32: 	lw	v0,1{{.*}}(sp)
278; MIPS32: 	lw	v1,1{{.*}}(sp)
279; MIPS32: 	lw	a1,1{{.*}}(sp)
280; MIPS32: 	lw	a2,1{{.*}}(sp)
281; MIPS32: 	move	a3,a0
282; MIPS32: 	sw	v0,0(a3)
283; MIPS32: 	sw	v1,4(a3)
284; MIPS32: 	sw	a1,8(a3)
285; MIPS32: 	sw	a2,12(a3)
286; MIPS32: 	move	v0,a0
287}
288
289; Test that vectors are passed correctly as arguments to a function.
290
291declare void @VectorArgs(<4 x float>, <4 x float>, <4 x float>, <4 x float>,
292                         <4 x float>, <4 x float>)
293
294declare void @killXmmRegisters()
295
296define internal void @test_passing_vectors(
297    <4 x float> %arg0, <4 x float> %arg1, <4 x float> %arg2, <4 x float> %arg3,
298    <4 x float> %arg4, <4 x float> %arg5, <4 x float> %arg6, <4 x float> %arg7,
299    <4 x float> %arg8, <4 x float> %arg9) {
300entry:
301  ; Kills XMM registers so that no in-arg lowering code interferes
302  ; with the test.
303  call void @killXmmRegisters()
304  call void @VectorArgs(<4 x float> %arg9, <4 x float> %arg8, <4 x float> %arg7,
305                        <4 x float> %arg6, <4 x float> %arg5, <4 x float> %arg4)
306  ret void
307; CHECK-LABEL: test_passing_vectors
308; CHECK-NEXT: sub esp,0x2c
309; CHECK: movups  [[ARG5:.*]],XMMWORD PTR [esp+0x40]
310; CHECK: movups  XMMWORD PTR [esp],[[ARG5]]
311; CHECK: movups  [[ARG6:.*]],XMMWORD PTR [esp+0x30]
312; CHECK: movups  XMMWORD PTR [esp+0x10],[[ARG6]]
313; CHECK: movups  xmm0,XMMWORD PTR [esp+0x80]
314; CHECK: movups  xmm1,XMMWORD PTR [esp+0x70]
315; CHECK: movups  xmm2,XMMWORD PTR [esp+0x60]
316; CHECK: movups  xmm3,XMMWORD PTR [esp+0x50]
317; CHECK: call {{.*}} R_{{.*}} VectorArgs
318; CHECK-NEXT: add esp,0x2c
319
320; OPTM1-LABEL: test_passing_vectors
321; OPTM1: sub esp,0x6c
322; OPTM1: movups  [[ARG5:.*]],XMMWORD PTR {{.*}}
323; OPTM1: movups  XMMWORD PTR [esp],[[ARG5]]
324; OPTM1: movups  [[ARG6:.*]],XMMWORD PTR {{.*}}
325; OPTM1: movups  XMMWORD PTR [esp+0x10],[[ARG6]]
326; OPTM1: movups  xmm0,XMMWORD PTR {{.*}}
327; OPTM1: movups  xmm1,XMMWORD PTR {{.*}}
328; OPTM1: movups  xmm2,XMMWORD PTR {{.*}}
329; OPTM1: movups  xmm3,XMMWORD PTR {{.*}}
330; OPTM1: call {{.*}} R_{{.*}} VectorArgs
331; OPTM1-NEXT: add esp,0x6c
332; MIPS32-LABEL: test_passing_vectors
333; MIPS32: 	sw	s7,{{.*}}(sp)
334; MIPS32: 	sw	s6,{{.*}}(sp)
335; MIPS32: 	sw	s5,{{.*}}(sp)
336; MIPS32: 	sw	s4,{{.*}}(sp)
337; MIPS32: 	sw	s3,{{.*}}(sp)
338; MIPS32: 	sw	s2,{{.*}}(sp)
339; MIPS32: 	sw	s1,{{.*}}(sp)
340; MIPS32: 	sw	s0,{{.*}}(sp)
341; MIPS32: 	lw	s0,{{.*}}(sp)
342; MIPS32: 	lw	s1,{{.*}}(sp)
343; MIPS32: 	lw	s2,{{.*}}(sp)
344; MIPS32: 	lw	s3,{{.*}}(sp)
345; MIPS32: 	lw	s4,{{.*}}(sp)
346; MIPS32: 	lw	s5,{{.*}}(sp)
347; MIPS32: 	lw	s6,{{.*}}(sp)
348; MIPS32: 	lw	s7,{{.*}}(sp)
349; MIPS32: 	jal	0 <test_returning_arg0>	228: R_MIPS_26	killXmmRegisters
350; MIPS32: 	nop
351; MIPS32: 	lw	v0,{{.*}}(sp)
352; MIPS32: 	sw	v0,{{.*}}(sp)
353; MIPS32: 	lw	v0,{{.*}}(sp)
354; MIPS32: 	sw	v0,{{.*}}(sp)
355; MIPS32: 	lw	v0,{{.*}}(sp)
356; MIPS32: 	sw	v0,{{.*}}(sp)
357; MIPS32: 	lw	v0,{{.*}}(sp)
358; MIPS32: 	sw	v0,{{.*}}(sp)
359; MIPS32: 	lw	v0,{{.*}}(sp)
360; MIPS32: 	sw	v0,{{.*}}(sp)
361; MIPS32: 	lw	v0,{{.*}}(sp)
362; MIPS32: 	sw	v0,{{.*}}(sp)
363; MIPS32: 	lw	v0,{{.*}}(sp)
364; MIPS32: 	sw	v0,{{.*}}(sp)
365; MIPS32: 	lw	v0,{{.*}}(sp)
366; MIPS32: 	sw	v0,{{.*}}(sp)
367; MIPS32: 	lw	v0,{{.*}}(sp)
368; MIPS32: 	sw	v0,{{.*}}(sp)
369; MIPS32: 	lw	v0,{{.*}}(sp)
370; MIPS32: 	sw	v0,{{.*}}(sp)
371; MIPS32: 	lw	v0,{{.*}}(sp)
372; MIPS32: 	sw	v0,{{.*}}(sp)
373; MIPS32: 	lw	v0,{{.*}}(sp)
374; MIPS32: 	sw	v0,{{.*}}(sp)
375; MIPS32: 	sw	s4,{{.*}}(sp)
376; MIPS32: 	sw	s5,{{.*}}(sp)
377; MIPS32: 	sw	s6,{{.*}}(sp)
378; MIPS32: 	sw	s7,{{.*}}(sp)
379; MIPS32: 	sw	s0,{{.*}}(sp)
380; MIPS32: 	sw	s1,{{.*}}(sp)
381; MIPS32: 	sw	s2,{{.*}}(sp)
382; MIPS32: 	sw	s3,{{.*}}(sp)
383; MIPS32: 	lw	a0,{{.*}}(sp)
384; MIPS32: 	lw	a1,{{.*}}(sp)
385; MIPS32: 	lw	a2,{{.*}}(sp)
386; MIPS32: 	lw	a3,{{.*}}(sp)
387; MIPS32: 	jal	0 <test_returning_arg0>	2c0: R_MIPS_26	VectorArgs
388; MIPS32: 	nop
389; MIPS32: 	lw	s0,{{.*}}(sp)
390; MIPS32: 	lw	s1,{{.*}}(sp)
391; MIPS32: 	lw	s2,{{.*}}(sp)
392; MIPS32: 	lw	s3,{{.*}}(sp)
393; MIPS32: 	lw	s4,{{.*}}(sp)
394; MIPS32: 	lw	s5,{{.*}}(sp)
395; MIPS32: 	lw	s6,{{.*}}(sp)
396; MIPS32: 	lw	s7,{{.*}}(sp)
397; MIPS32: 	lw	ra,{{.*}}(sp)
398
399}
400
401declare void @InterspersedVectorArgs(
402    <4 x float>, i64, <4 x float>, i64, <4 x float>, float, <4 x float>,
403    double, <4 x float>, i32, <4 x float>)
404
405define internal void @test_passing_vectors_interspersed(
406    <4 x float> %arg0, <4 x float> %arg1, <4 x float> %arg2, <4 x float> %arg3,
407    <4 x float> %arg4, <4 x float> %arg5, <4 x float> %arg6, <4 x float> %arg7,
408    <4 x float> %arg8, <4 x float> %arg9) {
409entry:
410  ; Kills XMM registers so that no in-arg lowering code interferes
411  ; with the test.
412  call void @killXmmRegisters()
413  call void @InterspersedVectorArgs(<4 x float> %arg9, i64 0, <4 x float> %arg8,
414                                    i64 1, <4 x float> %arg7, float 2.000000e+00,
415                                    <4 x float> %arg6, double 3.000000e+00,
416                                    <4 x float> %arg5, i32 4, <4 x float> %arg4)
417  ret void
418; CHECK-LABEL: test_passing_vectors_interspersed
419; CHECK: sub esp,0x5c
420; CHECK: movups  [[ARG9:.*]],XMMWORD PTR [esp+0x70]
421; CHECK: movups  XMMWORD PTR [esp+0x20],[[ARG9]]
422; CHECK: movups  [[ARG11:.*]],XMMWORD PTR [esp+0x60]
423; CHECK: movups  XMMWORD PTR [esp+0x40],[[ARG11]]
424; CHECK: movups  xmm0,XMMWORD PTR [esp+0xb0]
425; CHECK: movups  xmm1,XMMWORD PTR [esp+0xa0]
426; CHECK: movups  xmm2,XMMWORD PTR [esp+0x90]
427; CHECK: movups  xmm3,XMMWORD PTR [esp+0x80]
428; CHECK: call {{.*}} R_{{.*}} InterspersedVectorArgs
429; CHECK-NEXT: add esp,0x5c
430; CHECK: ret
431
432; OPTM1-LABEL: test_passing_vectors_interspersed
433; OPTM1: sub esp,0x9c
434; OPTM1: movups  [[ARG9:.*]],XMMWORD PTR {{.*}}
435; OPTM1: movups  XMMWORD PTR [esp+0x20],[[ARG9]]
436; OPTM1: movups  [[ARG11:.*]],XMMWORD PTR {{.*}}
437; OPTM1: movups  XMMWORD PTR [esp+0x40],[[ARG11]]
438; OPTM1: movups  xmm0,XMMWORD PTR {{.*}}
439; OPTM1: movups  xmm1,XMMWORD PTR {{.*}}
440; OPTM1: movups  xmm2,XMMWORD PTR {{.*}}
441; OPTM1: movups  xmm3,XMMWORD PTR {{.*}}
442; OPTM1: call {{.*}} R_{{.*}} InterspersedVectorArgs
443; OPTM1-NEXT: add esp,0x9c
444; OPTM1: ret
445; MIPS32-LABEL: test_passing_vectors_interspersed
446; MIPS32: 	sw	s7,{{.*}}(sp)
447; MIPS32: 	sw	s6,{{.*}}(sp)
448; MIPS32: 	sw	s5,{{.*}}(sp)
449; MIPS32: 	sw	s4,{{.*}}(sp)
450; MIPS32: 	sw	s3,{{.*}}(sp)
451; MIPS32: 	sw	s2,{{.*}}(sp)
452; MIPS32: 	sw	s1,{{.*}}(sp)
453; MIPS32: 	sw	s0,{{.*}}(sp)
454; MIPS32: 	lw	s0,{{.*}}(sp)
455; MIPS32: 	lw	s1,{{.*}}(sp)
456; MIPS32: 	lw	s2,{{.*}}(sp)
457; MIPS32: 	lw	s3,{{.*}}(sp)
458; MIPS32: 	lw	s4,{{.*}}(sp)
459; MIPS32: 	lw	s5,{{.*}}(sp)
460; MIPS32: 	lw	s6,{{.*}}(sp)
461; MIPS32: 	lw	s7,{{.*}}(sp)
462; MIPS32: 	jal	0 <test_returning_arg0>	348: R_MIPS_26	killXmmRegisters
463; MIPS32: 	nop
464; MIPS32: 	li	v0,0
465; MIPS32: 	li	v1,0
466; MIPS32: 	sw	v0,{{.*}}(sp)
467; MIPS32: 	sw	v1,{{.*}}(sp)
468; MIPS32: 	lw	v0,{{.*}}(sp)
469; MIPS32: 	sw	v0,{{.*}}(sp)
470; MIPS32: 	lw	v0,{{.*}}(sp)
471; MIPS32: 	sw	v0,{{.*}}(sp)
472; MIPS32: 	lw	v0,{{.*}}(sp)
473; MIPS32: 	sw	v0,{{.*}}(sp)
474; MIPS32: 	lw	v0,{{.*}}(sp)
475; MIPS32: 	sw	v0,{{.*}}(sp)
476; MIPS32: 	li	v0,0
477; MIPS32: 	li	v1,1
478; MIPS32: 	sw	v0,{{.*}}(sp)
479; MIPS32: 	sw	v1,{{.*}}(sp)
480; MIPS32: 	lw	v0,{{.*}}(sp)
481; MIPS32: 	sw	v0,{{.*}}(sp)
482; MIPS32: 	lw	v0,{{.*}}(sp)
483; MIPS32: 	sw	v0,{{.*}}(sp)
484; MIPS32: 	lw	v0,{{.*}}(sp)
485; MIPS32: 	sw	v0,{{.*}}(sp)
486; MIPS32: 	lw	v0,{{.*}}(sp)
487; MIPS32: 	sw	v0,{{.*}}(sp)
488; MIPS32: 	lui	v0,0x0	    3b0: R_MIPS_HI16	.L$float$40000000
489; MIPS32: 	lwc1	$f0,0(v0)   3b4: R_MIPS_LO16	.L$float$40000000
490; MIPS32: 	swc1	$f0,{{.*}}(sp)
491; MIPS32: 	lw	v0,{{.*}}(sp)
492; MIPS32: 	sw	v0,{{.*}}(sp)
493; MIPS32: 	lw	v0,{{.*}}(sp)
494; MIPS32: 	sw	v0,{{.*}}(sp)
495; MIPS32: 	lw	v0,{{.*}}(sp)
496; MIPS32: 	sw	v0,{{.*}}(sp)
497; MIPS32: 	lw	v0,{{.*}}(sp)
498; MIPS32: 	sw	v0,{{.*}}(sp)
499; MIPS32: 	lui	v0,0x0	    3dc: R_MIPS_HI16  .L$double$4008000000000000
500; MIPS32: 	ldc1	$f0,0(v0)   3e0: R_MIPS_LO16  .L$double$4008000000000000
501; MIPS32: 	sdc1	$f0,{{.*}}(sp)
502; MIPS32: 	sw	s4,{{.*}}(sp)
503; MIPS32: 	sw	s5,{{.*}}(sp)
504; MIPS32: 	sw	s6,{{.*}}(sp)
505; MIPS32: 	sw	s7,{{.*}}(sp)
506; MIPS32: 	li	v0,4
507; MIPS32: 	sw	v0,{{.*}}(sp)
508; MIPS32: 	sw	s0,{{.*}}(sp)
509; MIPS32: 	sw	s1,{{.*}}(sp)
510; MIPS32: 	sw	s2,{{.*}}(sp)
511; MIPS32: 	sw	s3,{{.*}}(sp)
512; MIPS32: 	lw	a0,{{.*}}(sp)
513; MIPS32: 	lw	a1,{{.*}}(sp)
514; MIPS32: 	lw	a2,{{.*}}(sp)
515; MIPS32: 	lw	a3,{{.*}}(sp)
516; MIPS32: 	jal	0 <test_returning_arg0>	420: R_MIPS_26	InterspersedVectorArgs
517; MIPS32: 	nop
518; MIPS32: 	lw	s0,{{.*}}(sp)
519; MIPS32: 	lw	s1,{{.*}}(sp)
520; MIPS32: 	lw	s2,{{.*}}(sp)
521; MIPS32: 	lw	s3,{{.*}}(sp)
522; MIPS32: 	lw	s4,{{.*}}(sp)
523; MIPS32: 	lw	s5,{{.*}}(sp)
524; MIPS32: 	lw	s6,{{.*}}(sp)
525; MIPS32: 	lw	s7,{{.*}}(sp)
526; MIPS32: 	lw	ra,{{.*}}(sp)
527}
528
529; Test that a vector returned from a function is recognized to be in
530; xmm0.
531
532declare <4 x float> @VectorReturn(<4 x float> %arg0)
533
534define internal void @test_receiving_vectors(<4 x float> %arg0) {
535entry:
536  %result = call <4 x float> @VectorReturn(<4 x float> %arg0)
537  %result2 = call <4 x float> @VectorReturn(<4 x float> %result)
538  ret void
539; CHECK-LABEL: test_receiving_vectors
540; CHECK: call {{.*}} R_{{.*}} VectorReturn
541; CHECK-NOT: movups xmm0
542; CHECK: call {{.*}} R_{{.*}} VectorReturn
543; CHECK: ret
544
545; OPTM1-LABEL: test_receiving_vectors
546; OPTM1: call {{.*}} R_{{.*}} VectorReturn
547; OPTM1: movups {{.*}},xmm0
548; OPTM1: movups xmm0,{{.*}}
549; OPTM1: call {{.*}} R_{{.*}} VectorReturn
550; OPTM1: ret
551; MIPS32-LABEL: test_receiving_vectors
552; MIPS32: 	sw	s8,{{.*}}(sp)
553; MIPS32: 	sw	s0,{{.*}}(sp)
554; MIPS32: 	move	s8,sp
555; MIPS32: 	move	v0,a0
556; MIPS32: 	addiu	v1,sp,32
557; MIPS32: 	move	s0,v1
558; MIPS32: 	move	a0,s0
559; MIPS32: 	sw	a2,{{.*}}(sp)
560; MIPS32: 	sw	a3,{{.*}}(sp)
561; MIPS32: 	move	a2,v0
562; MIPS32: 	move	a3,a1
563; MIPS32: 	jal	0 <test_returning_arg0>	{{.*}} R_MIPS_26	VectorReturn
564; MIPS32: 	nop
565; MIPS32: 	lw	v0,0(s0)
566; MIPS32: 	lw	v1,4(s0)
567; MIPS32: 	lw	a0,8(s0)
568; MIPS32: 	move	a1,a0
569; MIPS32: 	lw	s0,12(s0)
570; MIPS32: 	addiu	a0,sp,48
571; MIPS32: 	sw	a1,{{.*}}(sp)
572; MIPS32: 	sw	s0,{{.*}}(sp)
573; MIPS32: 	move	a2,v0
574; MIPS32: 	move	a3,v1
575; MIPS32: 	jal	0 <test_returning_arg0>	{{.*}} R_MIPS_26	VectorReturn
576; MIPS32: 	nop
577; MIPS32: 	move	sp,s8
578; MIPS32: 	lw	s0,{{.*}}(sp)
579; MIPS32: 	lw	s8,{{.*}}(sp)
580; MIPS32: 	lw	ra,{{.*}}(sp)
581}
582