Home | History | Annotate | Download | only in llvm2ice_tests
      1 ; This checks support for insertelement and extractelement.
      2 
      3 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \
      4 ; RUN:   | FileCheck %s
      5 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 \
      6 ; RUN:   | FileCheck %s
      7 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 -mattr=sse4.1 \
      8 ; RUN:   | FileCheck --check-prefix=SSE41 %s
      9 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 -mattr=sse4.1 \
     10 ; RUN:   | FileCheck --check-prefix=SSE41 %s
     11 
     12 ; RUN: %if --need=target_MIPS32 --need=allow_dump \
     13 ; RUN:   --command %p2i --filetype=asm --assemble --disassemble --target mips32\
     14 ; RUN:   -i %s --args -O2 \
     15 ; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
     16 ; RUN:   --command FileCheck --check-prefix MIPS32 %s
     17 
     18 ; insertelement operations
     19 
     20 define internal <4 x float> @insertelement_v4f32_0(<4 x float> %vec,
     21                                                    float %elt) {
     22 entry:
     23   %res = insertelement <4 x float> %vec, float %elt, i32 0
     24   ret <4 x float> %res
     25 ; CHECK-LABEL: insertelement_v4f32_0
     26 ; CHECK: movss
     27 
     28 ; SSE41-LABEL: insertelement_v4f32_0
     29 ; SSE41: insertps {{.*}},{{.*}},0x0
     30 
     31 ; *** a0 - implicit return <4 x float>
     32 ; *** a1 - unused due to alignment of %vec
     33 ; *** a2:a3:sp[16]:s[20] - %vec
     34 ; *** sp[24] - %elt
     35 ; MIPS32-LABEL: insertelement_v4f32_0
     36 ; *** Load element 2 and 3 of %vec
     37 ; MIPS32: lw [[BV_E2:.*]],
     38 ; MIPS32: lw [[BV_E3:.*]],
     39 ; *** Load %elt
     40 ; MIPS32: lwc1 [[ELT:.*]],
     41 ; *** Insert %elt at %vec[0]
     42 ; MIPS32: mfc1 [[RV_E0:.*]],[[ELT]]
     43 ; MIPS32: move [[RET_PTR:.*]],a0
     44 ; MIPS32: sw [[RV_E0]],0([[RET_PTR]])
     45 ; MIPS32: sw a3,4([[RET_PTR]])
     46 ; MIPS32: sw [[BV_E2]],8([[RET_PTR]])
     47 ; MIPS32: sw [[BV_E3]],12([[RET_PTR]])
     48 }
     49 
     50 define internal <4 x i32> @insertelement_v4i32_0(<4 x i32> %vec, i32 %elt) {
     51 entry:
     52   %res = insertelement <4 x i32> %vec, i32 %elt, i32 0
     53   ret <4 x i32> %res
     54 ; CHECK-LABEL: insertelement_v4i32_0
     55 ; CHECK: movd xmm{{.*}},
     56 ; CHECK: movss
     57 
     58 ; SSE41-LABEL: insertelement_v4i32_0
     59 ; SSE41: pinsrd {{.*}},{{.*}},0x0
     60 
     61 ; *** a0:a1:a2:a3 - %vec
     62 ; *** sp[16] - %elt
     63 ; MIPS32-LABEL: insertelement_v4i32_0
     64 ; *** Load %elt
     65 ; MIPS32: lw v0,16(sp)
     66 ; MIPS32: move v1,a1
     67 ; MIPS32: move a0,a2
     68 ; MIPS32: move a1,a3
     69 }
     70 
     71 
     72 define internal <4 x float> @insertelement_v4f32_1(<4 x float> %vec,
     73                                                    float %elt) {
     74 entry:
     75   %res = insertelement <4 x float> %vec, float %elt, i32 1
     76   ret <4 x float> %res
     77 ; CHECK-LABEL: insertelement_v4f32_1
     78 ; CHECK: shufps
     79 ; CHECK: shufps
     80 
     81 ; SSE41-LABEL: insertelement_v4f32_1
     82 ; SSE41: insertps {{.*}},{{.*}},0x10
     83 
     84 ; MIPS32-LABEL: insertelement_v4f32_1
     85 ; MIPS32: lw [[VEC_E2:.*]],16(sp)
     86 ; MIPS32: lw [[VEC_E3:.*]],20(sp)
     87 ; MIPS32: lwc1 [[ELT:.*]],24(sp)
     88 ; MIPS32: mfc1 [[R_E1:.*]],[[ELT]]
     89 ; MIPS32: move [[PTR:.*]],a0
     90 ; MIPS32: sw a2,0([[PTR]])
     91 ; MIPS32: sw [[R_E1]],4([[PTR]])
     92 ; MIPS32: sw [[VEC_E2]],8([[PTR]])
     93 ; MIPS32: sw [[VEC_E3]],12([[PTR]])
     94 }
     95 
     96 define internal <4 x i32> @insertelement_v4i32_1(<4 x i32> %vec, i32 %elt) {
     97 entry:
     98   %res = insertelement <4 x i32> %vec, i32 %elt, i32 1
     99   ret <4 x i32> %res
    100 ; CHECK-LABEL: insertelement_v4i32_1
    101 ; CHECK: shufps
    102 ; CHECK: shufps
    103 
    104 ; SSE41-LABEL: insertelement_v4i32_1
    105 ; SSE41: pinsrd {{.*}},{{.*}},0x1
    106 
    107 ; MIPS32-LABEL: insertelement_v4i32_1
    108 ; MIPS32: lw [[ELT:.*]],16(sp)
    109 ; MIPS32: move v1,[[ELT]]
    110 ; MIPS32: move v0,a0
    111 ; MIPS32: move a0,a2
    112 ; MIPS32: move a1,a3
    113 }
    114 
    115 define internal <8 x i16> @insertelement_v8i16(<8 x i16> %vec, i32 %elt.arg) {
    116 entry:
    117   %elt = trunc i32 %elt.arg to i16
    118   %res = insertelement <8 x i16> %vec, i16 %elt, i32 1
    119   ret <8 x i16> %res
    120 ; CHECK-LABEL: insertelement_v8i16
    121 ; CHECK: pinsrw
    122 
    123 ; SSE41-LABEL: insertelement_v8i16
    124 ; SSE41: pinsrw
    125 
    126 ; MIPS32-LABEL: insertelement_v8i16
    127 ; MIPS32: lw [[ELT:.*]],16(sp)
    128 ; MIPS32: sll [[ELT]],[[ELT]],0x10
    129 ; MIPS32: sll a0,a0,0x10
    130 ; MIPS32: srl a0,a0,0x10
    131 ; MIPS32: or v0,[[ELT]],a0
    132 ; MIPS32: move v1,a1
    133 ; MIPS32: move a0,a2
    134 ; MIPS32: move a1,a3
    135 }
    136 
    137 define internal <16 x i8> @insertelement_v16i8(<16 x i8> %vec, i32 %elt.arg) {
    138 entry:
    139   %elt = trunc i32 %elt.arg to i8
    140   %res = insertelement <16 x i8> %vec, i8 %elt, i32 1
    141   ret <16 x i8> %res
    142 ; CHECK-LABEL: insertelement_v16i8
    143 ; CHECK: movups
    144 ; CHECK: lea
    145 ; CHECK: mov
    146 
    147 ; SSE41-LABEL: insertelement_v16i8
    148 ; SSE41: pinsrb
    149 
    150 ; MIPS32-LABEL: insertelement_v16i8
    151 ; MIPS32: lw [[ELT:.*]],16(sp)
    152 ; MIPS32: andi [[ELT]],[[ELT]],0xff
    153 ; MIPS32: sll [[ELT]],[[ELT]],0x8
    154 ; MIPS32: lui [[T:.*]],0xffff
    155 ; MIPS32: ori [[T]],[[T]],0xff
    156 ; MIPS32: and a0,a0,[[T]]
    157 ; MIPS32: or v0,v0,a0
    158 ; MIPS32: move v1,a1
    159 ; MIPS32: move a0,a2
    160 ; MIPS32: move a1,a3
    161 }
    162 
    163 define internal <4 x i1> @insertelement_v4i1_0(<4 x i1> %vec, i32 %elt.arg) {
    164 entry:
    165   %elt = trunc i32 %elt.arg to i1
    166   %res = insertelement <4 x i1> %vec, i1 %elt, i32 0
    167   ret <4 x i1> %res
    168 ; CHECK-LABEL: insertelement_v4i1_0
    169 ; CHECK: movss
    170 
    171 ; SSE41-LABEL: insertelement_v4i1_0
    172 ; SSE41: pinsrd {{.*}},{{.*}},0x0
    173 
    174 ; MIPS32-LABEL: insertelement_v4i1_0
    175 ; MIPS32: lw v0,16(sp)
    176 ; MIPS32: move v1,a1
    177 ; MIPS32: move a0,a2
    178 ; MIPS32: move a1,a3
    179 }
    180 
    181 define internal <4 x i1> @insertelement_v4i1_1(<4 x i1> %vec, i32 %elt.arg) {
    182 entry:
    183   %elt = trunc i32 %elt.arg to i1
    184   %res = insertelement <4 x i1> %vec, i1 %elt, i32 1
    185   ret <4 x i1> %res
    186 ; CHECK-LABEL: insertelement_v4i1_1
    187 ; CHECK: shufps
    188 ; CHECK: shufps
    189 
    190 ; SSE41-LABEL: insertelement_v4i1_1
    191 ; SSE41: pinsrd {{.*}},{{.*}},0x1
    192 
    193 ; MIPS32-LABEL: insertelement_v4i1_1
    194 ; MIPS32: lw [[ELT:.*]],16(sp)
    195 ; MIPS32: move v1,[[ELT]]
    196 ; MIPS32: move v0,a0
    197 ; MIPS32: move a0,a2
    198 ; MIPS32: move a1,a3
    199 }
    200 
    201 define internal <8 x i1> @insertelement_v8i1(<8 x i1> %vec, i32 %elt.arg) {
    202 entry:
    203   %elt = trunc i32 %elt.arg to i1
    204   %res = insertelement <8 x i1> %vec, i1 %elt, i32 1
    205   ret <8 x i1> %res
    206 ; CHECK-LABEL: insertelement_v8i1
    207 ; CHECK: pinsrw
    208 
    209 ; SSE41-LABEL: insertelement_v8i1
    210 ; SSE41: pinsrw
    211 
    212 ; MIPS32-LABEL: insertelement_v8i1
    213 ; MIPS32: lw [[ELT:.*]],16(sp)
    214 ; MIPS32: sll [[ELT]],[[ELT]],0x10
    215 ; MIPS32: sll a0,a0,0x10
    216 ; MIPS32: srl a0,a0,0x10
    217 ; MIPS32: or v0,[[ELT]],a0
    218 ; MIPS32: move v1,a1
    219 ; MIPS32: move a0,a2
    220 ; MIPS32: move a1,a3
    221 }
    222 
    223 define internal <16 x i1> @insertelement_v16i1(<16 x i1> %vec, i32 %elt.arg) {
    224 entry:
    225   %elt = trunc i32 %elt.arg to i1
    226   %res = insertelement <16 x i1> %vec, i1 %elt, i32 1
    227   ret <16 x i1> %res
    228 ; CHECK-LABEL: insertelement_v16i1
    229 ; CHECK: movups
    230 ; CHECK: lea
    231 ; CHECK: mov
    232 
    233 ; SSE41-LABEL: insertelement_v16i1
    234 ; SSE41: pinsrb
    235 
    236 ; MIPS32-LABEL: insertelement_v16i1
    237 ; MIPS32: lw [[ELT:.*]],16(sp)
    238 ; MIPS32: andi [[ELT]],[[ELT]],0xff
    239 ; MIPS32: sll [[ELT]],[[ELT]],0x8
    240 ; MIPS32: lui [[T:.*]],0xffff
    241 ; MIPS32: ori [[T]],[[T]],0xff
    242 ; MIPS32: and a0,a0,[[T]]
    243 ; MIPS32: or v0,[[ELT]],a0
    244 ; MIPS32: move v1,a1
    245 ; MIPS32: move a0,a2
    246 ; MIPS32: move a1,a3
    247 }
    248 
    249 ; extractelement operations
    250 
    251 define internal float @extractelement_v4f32(<4 x float> %vec) {
    252 entry:
    253   %res = extractelement <4 x float> %vec, i32 1
    254   ret float %res
    255 ; CHECK-LABEL: extractelement_v4f32
    256 ; CHECK: pshufd
    257 
    258 ; SSE41-LABEL: extractelement_v4f32
    259 ; SSE41: pshufd
    260 
    261 ; MIPS32-LABEL: extractelement_v4f32
    262 ; MIPS32: mtc1 a1,$f0
    263 }
    264 
    265 define internal i32 @extractelement_v4i32(<4 x i32> %vec) {
    266 entry:
    267   %res = extractelement <4 x i32> %vec, i32 1
    268   ret i32 %res
    269 ; CHECK-LABEL: extractelement_v4i32
    270 ; CHECK: pshufd
    271 ; CHECK: movd {{.*}},xmm
    272 
    273 ; SSE41-LABEL: extractelement_v4i32
    274 ; SSE41: pextrd
    275 
    276 ; MIPS32-LABEL: extractelement_v4i32
    277 ; MIPS32L move v0,a1
    278 }
    279 
    280 define internal i32 @extractelement_v8i16(<8 x i16> %vec) {
    281 entry:
    282   %res = extractelement <8 x i16> %vec, i32 1
    283   %res.ext = zext i16 %res to i32
    284   ret i32 %res.ext
    285 ; CHECK-LABEL: extractelement_v8i16
    286 ; CHECK: pextrw
    287 
    288 ; SSE41-LABEL: extractelement_v8i16
    289 ; SSE41: pextrw
    290 
    291 ; MIPS32-LABEL: extractelement_v8i16
    292 ; MIPS32: srl a0,a0,0x10
    293 ; MIPS32: andi a0,a0,0xffff
    294 ; MIPS32: move v0,a0
    295 }
    296 
    297 define internal i32 @extractelement_v16i8(<16 x i8> %vec) {
    298 entry:
    299   %res = extractelement <16 x i8> %vec, i32 1
    300   %res.ext = zext i8 %res to i32
    301   ret i32 %res.ext
    302 ; CHECK-LABEL: extractelement_v16i8
    303 ; CHECK: movups
    304 ; CHECK: lea
    305 ; CHECK: mov
    306 
    307 ; SSE41-LABEL: extractelement_v16i8
    308 ; SSE41: pextrb
    309 
    310 ; MIPS32-LABEL: extractelement_v16i8
    311 ; MIPS32: srl a0,a0,0x8
    312 ; MIPS32: andi a0,a0,0xff
    313 ; MIPS32: andi a0,a0,0xff
    314 ; MIPS32: move v0,a0
    315 }
    316 
    317 define internal i32 @extractelement_v4i1(<4 x i1> %vec) {
    318 entry:
    319   %res = extractelement <4 x i1> %vec, i32 1
    320   %res.ext = zext i1 %res to i32
    321   ret i32 %res.ext
    322 ; CHECK-LABEL: extractelement_v4i1
    323 ; CHECK: pshufd
    324 
    325 ; SSE41-LABEL: extractelement_v4i1
    326 ; SSE41: pextrd
    327 
    328 ; MIPS32-LABEL: extractelement_v4i1
    329 ; MIPS32: andi a1,a1,0x1
    330 ; MIPS32: andi a1,a1,0x1
    331 ; MIPS32: move v0,a1
    332 }
    333 
    334 define internal i32 @extractelement_v8i1(<8 x i1> %vec) {
    335 entry:
    336   %res = extractelement <8 x i1> %vec, i32 1
    337   %res.ext = zext i1 %res to i32
    338   ret i32 %res.ext
    339 ; CHECK-LABEL: extractelement_v8i1
    340 ; CHECK: pextrw
    341 
    342 ; SSE41-LABEL: extractelement_v8i1
    343 ; SSE41: pextrw
    344 
    345 ; MIPS32-LABEL: extractelement_v8i1
    346 ; MIPS32: srl a0,a0,0x10
    347 ; MIPS32: andi a0,a0,0x1
    348 ; MIPS32: andi a0,a0,0x1
    349 ; MIPS32: move v0,a0
    350 }
    351 
    352 define internal i32 @extractelement_v16i1(<16 x i1> %vec) {
    353 entry:
    354   %res = extractelement <16 x i1> %vec, i32 1
    355   %res.ext = zext i1 %res to i32
    356   ret i32 %res.ext
    357 ; CHECK-LABEL: extractelement_v16i1
    358 ; CHECK: movups
    359 ; CHECK: lea
    360 ; CHECK: mov
    361 
    362 ; SSE41-LABEL: extractelement_v16i1
    363 ; SSE41: pextrb
    364 
    365 ; MIPS32-LABEL: extractelement_v16i1
    366 ; MIPS32: srl a0,a0,0x8
    367 ; MIPS32: andi a0,a0,0xff
    368 ; MIPS32: andi a0,a0,0x1
    369 ; MIPS32: andi a0,a0,0x1
    370 ; MIPS32: move v0,a0
    371 }
    372