Home | History | Annotate | Download | only in llvm2ice_tests
      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 
     18 define 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) {
     21 entry:
     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 
     42 define 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) {
     45 entry:
     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 
     68 define 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) {
     71 entry:
     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 
     94 define 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) {
     97 entry:
     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 
    120 define 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) {
    123 entry:
    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 
    149 define 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) {
    154 entry:
    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 
    177 define 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) {
    182 entry:
    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 
    205 define 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) {
    210 entry:
    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 
    233 define 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) {
    238 entry:
    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 
    262 define 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) {
    267 entry:
    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 
    291 declare void @VectorArgs(<4 x float>, <4 x float>, <4 x float>, <4 x float>,
    292                          <4 x float>, <4 x float>)
    293 
    294 declare void @killXmmRegisters()
    295 
    296 define 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) {
    300 entry:
    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 
    401 declare 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 
    405 define 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) {
    409 entry:
    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 
    532 declare <4 x float> @VectorReturn(<4 x float> %arg0)
    533 
    534 define internal void @test_receiving_vectors(<4 x float> %arg0) {
    535 entry:
    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