Home | History | Annotate | Download | only in ARM
      1 ; RUN: llc -mtriple armeb-eabi -mattr v7,neon -float-abi soft %s -o - | FileCheck %s -check-prefix CHECK -check-prefix SOFT
      2 ; RUN: llc -mtriple armeb-eabi -mattr v7,neon -float-abi hard %s -o - | FileCheck %s -check-prefix CHECK -check-prefix HARD
      3 
      4 ; CHECK-LABEL: test_i64_f64:
      5 define i64 @test_i64_f64(double %p) {
      6 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
      7 ; SOFT: vadd.f64 [[REG]]
      8 ; HARD: vadd.f64 d{{[0-9]+}}, d0
      9     %1 = fadd double %p, %p
     10     %2 = bitcast double %1 to i64
     11     %3 = add i64 %2, %2
     12     ret i64 %3
     13 ; CHECK: adds r1
     14 ; CHECK: adc r0
     15 }
     16 
     17 ; CHECK-LABEL: test_i64_v1i64:
     18 define i64 @test_i64_v1i64(<1 x i64> %p) {
     19 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
     20 ; SOFT: vadd.i64 [[REG]]
     21 ; HARD: vadd.i64 d{{[0-9]+}}, d0
     22     %1 = add <1 x i64> %p, %p
     23     %2 = bitcast <1 x i64> %1 to i64
     24     %3 = add i64 %2, %2
     25     ret i64 %3
     26 ; CHECK: adds r1
     27 ; CHECK: adc r0
     28 }
     29 
     30 ; CHECK-LABEL: test_i64_v2f32:
     31 define i64 @test_i64_v2f32(<2 x float> %p) {
     32 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
     33 ; SOFT: vrev64.32 [[REG]]
     34 ; HARD: vrev64.32 d{{[0-9]+}}, d0
     35     %1 = fadd <2 x float> %p, %p
     36     %2 = bitcast <2 x float> %1 to i64
     37     %3 = add i64 %2, %2
     38     ret i64 %3
     39 ; CHECK: adds r1
     40 ; CHECK: adc r0
     41 }
     42 
     43 ; CHECK-LABEL: test_i64_v2i32:
     44 define i64 @test_i64_v2i32(<2 x i32> %p) {
     45 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
     46 ; SOFT: vrev64.32 [[REG]]
     47 ; HARD: vrev64.32 d{{[0-9]+}}, d0
     48     %1 = add <2 x i32> %p, %p
     49     %2 = bitcast <2 x i32> %1 to i64
     50     %3 = add i64 %2, %2
     51     ret i64 %3
     52 ; CHECK: adds r1
     53 ; CHECK: adc r0
     54 }
     55 
     56 ; CHECK-LABEL: test_i64_v4i16:
     57 define i64 @test_i64_v4i16(<4 x i16> %p) {
     58 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
     59 ; SOFT: vrev64.16 [[REG]]
     60 ; HARD: vrev64.16 d{{[0-9]+}}, d0
     61     %1 = add <4 x i16> %p, %p
     62     %2 = bitcast <4 x i16> %1 to i64
     63     %3 = add i64 %2, %2
     64     ret i64 %3
     65 ; CHECK: adds r1
     66 ; CHECK: adc r0
     67 }
     68 
     69 ; CHECK-LABEL: test_i64_v8i8:
     70 define i64 @test_i64_v8i8(<8 x i8> %p) {
     71 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
     72 ; SOFT: vrev64.8 [[REG]]
     73 ; HARD: vrev64.8 d{{[0-9]+}}, d0
     74     %1 = add <8 x i8> %p, %p
     75     %2 = bitcast <8 x i8> %1 to i64
     76     %3 = add i64 %2, %2
     77     ret i64 %3
     78 ; CHECK: adds r1
     79 ; CHECK: adc r0
     80 }
     81 
     82 ; CHECK-LABEL: test_f64_i64:
     83 define double @test_f64_i64(i64 %p) {
     84 ; CHECK: adds r1
     85 ; CHECK: adc r0
     86     %1 = add i64 %p, %p
     87     %2 = bitcast i64 %1 to double
     88     %3 = fadd double %2, %2
     89     ret double %3
     90 ; SOFT: vadd.f64 [[REG:d[0-9]+]]
     91 ; SOFT: vmov r1, r0, [[REG]]
     92 ; HARD: vadd.f64 d0
     93 }
     94 
     95 ; CHECK-LABEL: test_f64_v1i64:
     96 define double @test_f64_v1i64(<1 x i64> %p) {
     97 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
     98 ; SOFT: vadd.i64 [[REG]]
     99 ; HARD: vadd.i64 d{{[0-9]+}}, d0
    100     %1 = add <1 x i64> %p, %p
    101     %2 = bitcast <1 x i64> %1 to double
    102     %3 = fadd double %2, %2
    103     ret double %3
    104 ; SOFT: vadd.f64 [[REG:d[0-9]+]]
    105 ; SOFT: vmov r1, r0, [[REG]]
    106 ; HARD: vadd.f64 d0
    107 }
    108 
    109 ; CHECK-LABEL: test_f64_v2f32:
    110 define double @test_f64_v2f32(<2 x float> %p) {
    111 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    112 ; SOFT: vrev64.32 [[REG]]
    113 ; HARD: vrev64.32 d{{[0-9]+}}, d0
    114     %1 = fadd <2 x float> %p, %p
    115     %2 = bitcast <2 x float> %1 to double
    116     %3 = fadd double %2, %2
    117     ret double %3
    118 ; SOFT: vadd.f64 [[REG:d[0-9]+]]
    119 ; SOFT: vmov r1, r0, [[REG]]
    120 ; HARD: vadd.f64 d0
    121 }
    122 
    123 ; CHECK-LABEL: test_f64_v2i32:
    124 define double @test_f64_v2i32(<2 x i32> %p) {
    125 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    126 ; SOFT: vrev64.32 [[REG]]
    127 ; HARD: vrev64.32 d{{[0-9]+}}, d0
    128     %1 = add <2 x i32> %p, %p
    129     %2 = bitcast <2 x i32> %1 to double
    130     %3 = fadd double %2, %2
    131     ret double %3
    132 ; SOFT: vadd.f64 [[REG:d[0-9]+]]
    133 ; SOFT: vmov r1, r0, [[REG]]
    134 ; HARD: vadd.f64 d0
    135 }
    136 
    137 ; CHECK-LABEL: test_f64_v4i16:
    138 define double @test_f64_v4i16(<4 x i16> %p) {
    139 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    140 ; SOFT: vrev64.16 [[REG]]
    141 ; HARD: vrev64.16 d{{[0-9]+}}, d0
    142     %1 = add <4 x i16> %p, %p
    143     %2 = bitcast <4 x i16> %1 to double
    144     %3 = fadd double %2, %2
    145     ret double %3
    146 ; SOFT: vadd.f64 [[REG:d[0-9]+]]
    147 ; SOFT: vmov r1, r0, [[REG]]
    148 ; HARD: vadd.f64 d0
    149 }
    150 
    151 ; CHECK-LABEL: test_f64_v8i8:
    152 define double @test_f64_v8i8(<8 x i8> %p) {
    153 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    154 ; SOFT: vrev64.8 [[REG]]
    155 ; HARD: vrev64.8 d{{[0-9]+}}, d0
    156     %1 = add <8 x i8> %p, %p
    157     %2 = bitcast <8 x i8> %1 to double
    158     %3 = fadd double %2, %2
    159     ret double %3
    160 ; SOFT: vadd.f64 [[REG:d[0-9]+]]
    161 ; SOFT: vmov r1, r0, [[REG]]
    162 ; HARD: vadd.f64 d0
    163 }
    164 
    165 ; CHECK-LABEL: test_v1i64_i64:
    166 define <1 x i64> @test_v1i64_i64(i64 %p) {
    167 ; CHECK: adds r1
    168 ; CHECK: adc r0
    169     %1 = add i64 %p, %p
    170     %2 = bitcast i64 %1 to <1 x i64>
    171     %3 = add <1 x i64> %2, %2
    172     ret <1 x i64> %3
    173 ; SOFT: vadd.i64 [[REG:d[0-9]+]]
    174 ; SOFT: vmov r1, r0, [[REG]]
    175 ; HARD: vadd.i64 d0
    176 }
    177 
    178 ; CHECK-LABEL: test_v1i64_f64:
    179 define <1 x i64> @test_v1i64_f64(double %p) {
    180 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    181 ; SOFT: vadd.f64 [[REG]]
    182 ; HARD: vadd.f64 d{{[0-9]+}}, d0
    183     %1 = fadd double %p, %p
    184     %2 = bitcast double %1 to <1 x i64>
    185     %3 = add <1 x i64> %2, %2
    186     ret <1 x i64> %3
    187 ; SOFT: vadd.i64 [[REG:d[0-9]+]]
    188 ; SOFT: vmov r1, r0, [[REG]]
    189 ; HARD: vadd.i64 d0
    190 }
    191 
    192 ; CHECK-LABEL: test_v1i64_v2f32:
    193 define <1 x i64> @test_v1i64_v2f32(<2 x float> %p) {
    194 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    195 ; SOFT: vrev64.32 [[REG]]
    196 ; HARD: vrev64.32 d{{[0-9]+}}, d0
    197     %1 = fadd <2 x float> %p, %p
    198     %2 = bitcast <2 x float> %1 to <1 x i64>
    199     %3 = add <1 x i64> %2, %2
    200     ret <1 x i64> %3
    201 ; SOFT: vadd.i64 [[REG:d[0-9]+]]
    202 ; SOFT: vmov r1, r0, [[REG]]
    203 ; HARD: vadd.i64 d0
    204 }
    205 
    206 ; CHECK-LABEL: test_v1i64_v2i32:
    207 define <1 x i64> @test_v1i64_v2i32(<2 x i32> %p) {
    208 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    209 ; SOFT: vrev64.32 [[REG]]
    210 ; HARD: vrev64.32 d{{[0-9]+}}, d0
    211     %1 = add <2 x i32> %p, %p
    212     %2 = bitcast <2 x i32> %1 to <1 x i64>
    213     %3 = add <1 x i64> %2, %2
    214     ret <1 x i64> %3
    215 ; SOFT: vadd.i64 [[REG:d[0-9]+]]
    216 ; SOFT: vmov r1, r0, [[REG]]
    217 ; HARD: vadd.i64 d0
    218 }
    219 
    220 ; CHECK-LABEL: test_v1i64_v4i16:
    221 define <1 x i64> @test_v1i64_v4i16(<4 x i16> %p) {
    222 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    223 ; SOFT: vrev64.16 [[REG]]
    224 ; HARD: vrev64.16 d{{[0-9]+}}, d0
    225     %1 = add <4 x i16> %p, %p
    226     %2 = bitcast <4 x i16> %1 to <1 x i64>
    227     %3 = add <1 x i64> %2, %2
    228     ret <1 x i64> %3
    229 ; SOFT: vadd.i64 [[REG:d[0-9]+]]
    230 ; SOFT: vmov r1, r0, [[REG]]
    231 ; HARD: vadd.i64 d0
    232 }
    233 
    234 ; CHECK-LABEL: test_v1i64_v8i8:
    235 define <1 x i64> @test_v1i64_v8i8(<8 x i8> %p) {
    236 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    237 ; SOFT: vrev64.8 [[REG]]
    238 ; HARD: vrev64.8 d{{[0-9]+}}, d0
    239     %1 = add <8 x i8> %p, %p
    240     %2 = bitcast <8 x i8> %1 to <1 x i64>
    241     %3 = add <1 x i64> %2, %2
    242     ret <1 x i64> %3
    243 ; SOFT: vadd.i64 [[REG:d[0-9]+]]
    244 ; SOFT: vmov r1, r0, [[REG]]
    245 ; HARD: vadd.i64 d0
    246 }
    247 
    248 ; CHECK-LABEL: test_v2f32_i64:
    249 define <2 x float> @test_v2f32_i64(i64 %p) {
    250 ; CHECK: adds r1
    251 ; CHECK: adc r0
    252     %1 = add i64 %p, %p
    253     %2 = bitcast i64 %1 to <2 x float>
    254     %3 = fadd <2 x float> %2, %2
    255     ret <2 x float> %3
    256 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    257 ; SOFT: vmov r1, r0, [[REG]]
    258 ; HARD: vrev64.32 d0
    259 }
    260 
    261 ; CHECK-LABEL: test_v2f32_f64:
    262 define <2 x float> @test_v2f32_f64(double %p) {
    263 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    264 ; SOFT: vadd.f64 [[REG]]
    265 ; HARD: vadd.f64 d{{[0-9]+}}, d0
    266     %1 = fadd double %p, %p
    267     %2 = bitcast double %1 to <2 x float>
    268     %3 = fadd <2 x float> %2, %2
    269     ret <2 x float> %3
    270 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    271 ; SOFT: vmov r1, r0, [[REG]]
    272 ; HARD: vrev64.32 d0
    273 }
    274 
    275 ; CHECK-LABEL: test_v2f32_v1i64:
    276 define <2 x float> @test_v2f32_v1i64(<1 x i64> %p) {
    277 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    278 ; SOFT: vadd.i64 [[REG]]
    279 ; HARD: vadd.i64 d{{[0-9]+}}, d0
    280     %1 = add <1 x i64> %p, %p
    281     %2 = bitcast <1 x i64> %1 to <2 x float>
    282     %3 = fadd <2 x float> %2, %2
    283     ret <2 x float> %3
    284 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    285 ; SOFT: vmov r1, r0, [[REG]]
    286 ; HARD: vrev64.32 d0
    287 }
    288 
    289 ; CHECK-LABEL: test_v2f32_v2i32:
    290 define <2 x float> @test_v2f32_v2i32(<2 x i32> %p) {
    291 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    292 ; SOFT: vrev64.32 [[REG]]
    293 ; HARD: vrev64.32 d{{[0-9]+}}, d0
    294     %1 = add <2 x i32> %p, %p
    295     %2 = bitcast <2 x i32> %1 to <2 x float>
    296     %3 = fadd <2 x float> %2, %2
    297     ret <2 x float> %3
    298 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    299 ; SOFT: vmov r1, r0, [[REG]]
    300 ; HARD: vrev64.32 d0
    301 }
    302 
    303 ; CHECK-LABEL: test_v2f32_v4i16:
    304 define <2 x float> @test_v2f32_v4i16(<4 x i16> %p) {
    305 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    306 ; SOFT: vrev64.16 [[REG]]
    307 ; HARD: vrev64.16 d{{[0-9]+}}, d0
    308     %1 = add <4 x i16> %p, %p
    309     %2 = bitcast <4 x i16> %1 to <2 x float>
    310     %3 = fadd <2 x float> %2, %2
    311     ret <2 x float> %3
    312 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    313 ; SOFT: vmov r1, r0, [[REG]]
    314 ; HARD: vrev64.32 d0
    315 }
    316 
    317 ; CHECK-LABEL: test_v2f32_v8i8:
    318 define <2 x float> @test_v2f32_v8i8(<8 x i8> %p) {
    319 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    320 ; SOFT: vrev64.8 [[REG]]
    321 ; HARD: vrev64.8 d{{[0-9]+}}, d0
    322     %1 = add <8 x i8> %p, %p
    323     %2 = bitcast <8 x i8> %1 to <2 x float>
    324     %3 = fadd <2 x float> %2, %2
    325     ret <2 x float> %3
    326 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    327 ; SOFT: vmov r1, r0, [[REG]]
    328 ; HARD: vrev64.32 d0
    329 }
    330 
    331 ; CHECK-LABEL: test_v2i32_i64:
    332 define <2 x i32> @test_v2i32_i64(i64 %p) {
    333 ; CHECK: adds r1
    334 ; CHECK: adc r0
    335     %1 = add i64 %p, %p
    336     %2 = bitcast i64 %1 to <2 x i32>
    337     %3 = add <2 x i32> %2, %2
    338     ret <2 x i32> %3
    339 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    340 ; SOFT: vmov r1, r0, [[REG]]
    341 ; HARD: vrev64.32 d0
    342 }
    343 
    344 ; CHECK-LABEL: test_v2i32_f64:
    345 define <2 x i32> @test_v2i32_f64(double %p) {
    346 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    347 ; SOFT: vadd.f64 [[REG]]
    348 ; HARD: vadd.f64 d{{[0-9]+}}, d0
    349     %1 = fadd double %p, %p
    350     %2 = bitcast double %1 to <2 x i32>
    351     %3 = add <2 x i32> %2, %2
    352     ret <2 x i32> %3
    353 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    354 ; SOFT: vmov r1, r0, [[REG]]
    355 ; HARD: vrev64.32 d0
    356 }
    357 
    358 ; CHECK-LABEL: test_v2i32_v1i64:
    359 define <2 x i32> @test_v2i32_v1i64(<1 x i64> %p) {
    360 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    361 ; SOFT: vadd.i64 [[REG]]
    362 ; HARD: vadd.i64 d{{[0-9]+}}, d0
    363     %1 = add <1 x i64> %p, %p
    364     %2 = bitcast <1 x i64> %1 to <2 x i32>
    365     %3 = add <2 x i32> %2, %2
    366     ret <2 x i32> %3
    367 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    368 ; SOFT: vmov r1, r0, [[REG]]
    369 ; HARD: vrev64.32 d0
    370 }
    371 
    372 ; CHECK-LABEL: test_v2i32_v2f32:
    373 define <2 x i32> @test_v2i32_v2f32(<2 x float> %p) {
    374 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    375 ; SOFT: vrev64.32 [[REG]]
    376 ; HARD: vrev64.32 d{{[0-9]+}}, d0
    377     %1 = fadd <2 x float> %p, %p
    378     %2 = bitcast <2 x float> %1 to <2 x i32>
    379     %3 = add <2 x i32> %2, %2
    380     ret <2 x i32> %3
    381 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    382 ; SOFT: vmov r1, r0, [[REG]]
    383 ; HARD: vrev64.32 d0
    384 }
    385 
    386 ; CHECK-LABEL: test_v2i32_v4i16:
    387 define <2 x i32> @test_v2i32_v4i16(<4 x i16> %p) {
    388 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    389 ; SOFT: vrev64.16 [[REG]]
    390 ; HARD: vrev64.16 d{{[0-9]+}}, d0
    391     %1 = add <4 x i16> %p, %p
    392     %2 = bitcast <4 x i16> %1 to <2 x i32>
    393     %3 = add <2 x i32> %2, %2
    394     ret <2 x i32> %3
    395 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    396 ; SOFT: vmov r1, r0, [[REG]]
    397 ; HARD: vrev64.32 d0
    398 }
    399 
    400 ; CHECK-LABEL: test_v2i32_v8i8:
    401 define <2 x i32> @test_v2i32_v8i8(<8 x i8> %p) {
    402 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    403 ; SOFT: vrev64.8 [[REG]]
    404 ; HARD: vrev64.8 d{{[0-9]+}}, d0
    405     %1 = add <8 x i8> %p, %p
    406     %2 = bitcast <8 x i8> %1 to <2 x i32>
    407     %3 = add <2 x i32> %2, %2
    408     ret <2 x i32> %3
    409 ; SOFT: vrev64.32 [[REG:d[0-9]+]]
    410 ; SOFT: vmov r1, r0, [[REG]]
    411 ; HARD: vrev64.32 d0
    412 }
    413 
    414 ; CHECK-LABEL: test_v4i16_i64:
    415 define <4 x i16> @test_v4i16_i64(i64 %p) {
    416 ; CHECK: adds r1
    417 ; CHECK: adc r0
    418     %1 = add i64 %p, %p
    419     %2 = bitcast i64 %1 to <4 x i16>
    420     %3 = add <4 x i16> %2, %2
    421     ret <4 x i16> %3
    422 ; SOFT: vrev64.16 [[REG:d[0-9]+]]
    423 ; SOFT: vmov r1, r0, [[REG]]
    424 ; HARD: vrev64.16 d0
    425 }
    426 
    427 ; CHECK-LABEL: test_v4i16_f64:
    428 define <4 x i16> @test_v4i16_f64(double %p) {
    429 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    430 ; SOFT: vadd.f64 [[REG]]
    431 ; HARD: vadd.f64 d{{[0-9]+}}, d0
    432     %1 = fadd double %p, %p
    433     %2 = bitcast double %1 to <4 x i16>
    434     %3 = add <4 x i16> %2, %2
    435     ret <4 x i16> %3
    436 ; SOFT: vrev64.16 [[REG:d[0-9]+]]
    437 ; SOFT: vmov r1, r0, [[REG]]
    438 ; HARD: vrev64.16 d0
    439 }
    440 
    441 ; CHECK-LABEL: test_v4i16_v1i64:
    442 define <4 x i16> @test_v4i16_v1i64(<1 x i64> %p) {
    443 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    444 ; SOFT: vadd.i64 [[REG]]
    445 ; HARD: vadd.i64 d{{[0-9]+}}, d0
    446     %1 = add <1 x i64> %p, %p
    447     %2 = bitcast <1 x i64> %1 to <4 x i16>
    448     %3 = add <4 x i16> %2, %2
    449     ret <4 x i16> %3
    450 ; SOFT: vrev64.16 [[REG:d[0-9]+]]
    451 ; SOFT: vmov r1, r0, [[REG]]
    452 ; HARD: vrev64.16 d0
    453 }
    454 
    455 ; CHECK-LABEL: test_v4i16_v2f32:
    456 define <4 x i16> @test_v4i16_v2f32(<2 x float> %p) {
    457 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    458 ; SOFT: vrev64.32 [[REG]]
    459 ; HARD: vrev64.32 d{{[0-9]+}}, d0
    460     %1 = fadd <2 x float> %p, %p
    461     %2 = bitcast <2 x float> %1 to <4 x i16>
    462     %3 = add <4 x i16> %2, %2
    463     ret <4 x i16> %3
    464 ; SOFT: vrev64.16 [[REG:d[0-9]+]]
    465 ; SOFT: vmov r1, r0, [[REG]]
    466 ; HARD: vrev64.16 d0
    467 }
    468 
    469 ; CHECK-LABEL: test_v4i16_v2i32:
    470 define <4 x i16> @test_v4i16_v2i32(<2 x i32> %p) {
    471 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    472 ; SOFT: vrev64.32 [[REG]]
    473 ; HARD: vrev64.32 d{{[0-9]+}}, d0
    474     %1 = add <2 x i32> %p, %p
    475     %2 = bitcast <2 x i32> %1 to <4 x i16>
    476     %3 = add <4 x i16> %2, %2
    477     ret <4 x i16> %3
    478 ; SOFT: vrev64.16 [[REG:d[0-9]+]]
    479 ; SOFT: vmov r1, r0, [[REG]]
    480 ; HARD: vrev64.16 d0
    481 }
    482 
    483 ; CHECK-LABEL: test_v4i16_v8i8:
    484 define <4 x i16> @test_v4i16_v8i8(<8 x i8> %p) {
    485 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    486 ; SOFT: vrev64.8 [[REG]]
    487 ; HARD: vrev64.8 d{{[0-9]+}}, d0
    488     %1 = add <8 x i8> %p, %p
    489     %2 = bitcast <8 x i8> %1 to <4 x i16>
    490     %3 = add <4 x i16> %2, %2
    491     ret <4 x i16> %3
    492 ; SOFT: vrev64.16 [[REG:d[0-9]+]]
    493 ; SOFT: vmov r1, r0, [[REG]]
    494 ; HARD: vrev64.16 d0
    495 }
    496 
    497 ; CHECK-LABEL: test_v8i8_i64:
    498 define <8 x i8> @test_v8i8_i64(i64 %p) {
    499 ; CHECK: adds r1
    500 ; CHECK: adc r0
    501     %1 = add i64 %p, %p
    502     %2 = bitcast i64 %1 to <8 x i8>
    503     %3 = add <8 x i8> %2, %2
    504     ret <8 x i8> %3
    505 ; SOFT: vrev64.8 [[REG:d[0-9]+]]
    506 ; SOFT: vmov r1, r0, [[REG]]
    507 ; HARD: vrev64.8 d0
    508 }
    509 
    510 ; CHECK-LABEL: test_v8i8_f64:
    511 define <8 x i8> @test_v8i8_f64(double %p) {
    512 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    513 ; SOFT: vadd.f64 [[REG]]
    514 ; HARD: vadd.f64 d{{[0-9]+}}, d0
    515     %1 = fadd double %p, %p
    516     %2 = bitcast double %1 to <8 x i8>
    517     %3 = add <8 x i8> %2, %2
    518     ret <8 x i8> %3
    519 ; SOFT: vrev64.8 [[REG:d[0-9]+]]
    520 ; SOFT: vmov r1, r0, [[REG]]
    521 ; HARD: vrev64.8 d0
    522 }
    523 
    524 ; CHECK-LABEL: test_v8i8_v1i64:
    525 define <8 x i8> @test_v8i8_v1i64(<1 x i64> %p) {
    526 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    527 ; SOFT: vadd.i64 [[REG]]
    528 ; HARD: vadd.i64 d{{[0-9]+}}, d0
    529     %1 = add <1 x i64> %p, %p
    530     %2 = bitcast <1 x i64> %1 to <8 x i8>
    531     %3 = add <8 x i8> %2, %2
    532     ret <8 x i8> %3
    533 ; SOFT: vrev64.8 [[REG:d[0-9]+]]
    534 ; SOFT: vmov r1, r0, [[REG]]
    535 ; HARD: vrev64.8 d0
    536 }
    537 
    538 ; CHECK-LABEL: test_v8i8_v2f32:
    539 define <8 x i8> @test_v8i8_v2f32(<2 x float> %p) {
    540 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    541 ; SOFT: vrev64.32 [[REG]]
    542 ; HARD: vrev64.32 d{{[0-9]+}}, d0
    543     %1 = fadd <2 x float> %p, %p
    544     %2 = bitcast <2 x float> %1 to <8 x i8>
    545     %3 = add <8 x i8> %2, %2
    546     ret <8 x i8> %3
    547 ; SOFT: vrev64.8 [[REG:d[0-9]+]]
    548 ; SOFT: vmov r1, r0, [[REG]]
    549 ; HARD: vrev64.8 d0
    550 }
    551 
    552 ; CHECK-LABEL: test_v8i8_v2i32:
    553 define <8 x i8> @test_v8i8_v2i32(<2 x i32> %p) {
    554 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    555 ; SOFT: vrev64.32 [[REG]]
    556 ; HARD: vrev64.32 d{{[0-9]+}}, d0
    557     %1 = add <2 x i32> %p, %p
    558     %2 = bitcast <2 x i32> %1 to <8 x i8>
    559     %3 = add <8 x i8> %2, %2
    560     ret <8 x i8> %3
    561 ; SOFT: vrev64.8 [[REG:d[0-9]+]]
    562 ; SOFT: vmov r1, r0, [[REG]]
    563 ; HARD: vrev64.8 d0
    564 }
    565 
    566 ; CHECK-LABEL: test_v8i8_v4i16:
    567 define <8 x i8> @test_v8i8_v4i16(<4 x i16> %p) {
    568 ; SOFT: vmov [[REG:d[0-9]+]], r1, r0
    569 ; SOFT: vrev64.16 [[REG]]
    570 ; HARD: vrev64.16 d{{[0-9]+}}, d0
    571     %1 = add <4 x i16> %p, %p
    572     %2 = bitcast <4 x i16> %1 to <8 x i8>
    573     %3 = add <8 x i8> %2, %2
    574     ret <8 x i8> %3
    575 ; SOFT: vrev64.8 [[REG:d[0-9]+]]
    576 ; SOFT: vmov r1, r0, [[REG]]
    577 ; HARD: vrev64.8 d0
    578 }
    579 
    580 ; CHECK-LABEL: test_f128_v2f64:
    581 define fp128 @test_f128_v2f64(<2 x double> %p) {
    582 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    583 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    584 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG1]]
    585 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG2]]
    586 ; HARD: vadd.f64 d{{[0-9]+}}, d1
    587 ; HARD: vadd.f64 d{{[0-9]+}}, d0
    588     %1 = fadd <2 x double> %p, %p
    589     %2 = bitcast <2 x double> %1 to fp128
    590     %3 = fadd fp128 %2, %2
    591     ret fp128 %3
    592 ; CHECK: vst1.32 {d{{[0-9]+}}[1]}, [{{[a-z0-9]+}}:32]
    593 ; CHECK: vst1.32 {d{{[0-9]+}}[0]}, [{{[a-z0-9]+}}:32]
    594 }
    595 
    596 ; CHECK-LABEL: test_f128_v2i64:
    597 define fp128 @test_f128_v2i64(<2 x i64> %p) {
    598 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    599 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    600 ; HARD: vadd.i64 q{{[0-9]+}}, q0
    601     %1 = add <2 x i64> %p, %p
    602     %2 = bitcast <2 x i64> %1 to fp128
    603     %3 = fadd fp128 %2, %2
    604     ret fp128 %3
    605 ; CHECK: vst1.32 {d{{[0-9]+}}[1]}, [{{[a-z0-9]+}}:32]
    606 ; CHECK: vst1.32 {d{{[0-9]+}}[0]}, [{{[a-z0-9]+}}:32]
    607 }
    608 
    609 ; CHECK-LABEL: test_f128_v4f32:
    610 define fp128 @test_f128_v4f32(<4 x float> %p) {
    611 ; HARD: vrev64.32 q{{[0-9]+}}, q0
    612     %1 = fadd <4 x float> %p, %p
    613     %2 = bitcast <4 x float> %1 to fp128
    614     %3 = fadd fp128 %2, %2
    615     ret fp128 %3
    616 ; CHECK: vst1.32 {d{{[0-9]+}}[1]}, [{{[a-z0-9]+}}:32]
    617 ; CHECK: vst1.32 {d{{[0-9]+}}[0]}, [{{[a-z0-9]+}}:32]
    618 }
    619 
    620 ; CHECK-LABEL: test_f128_v4i32:
    621 define fp128 @test_f128_v4i32(<4 x i32> %p) {
    622 ; HARD: vrev64.32 q{{[0-9]+}}, q0
    623     %1 = add <4 x i32> %p, %p
    624     %2 = bitcast <4 x i32> %1 to fp128
    625     %3 = fadd fp128 %2, %2
    626     ret fp128 %3
    627 ; CHECK: vst1.32 {d{{[0-9]+}}[1]}, [{{[a-z0-9]+}}:32]
    628 ; CHECK: vst1.32 {d{{[0-9]+}}[0]}, [{{[a-z0-9]+}}:32]
    629 }
    630 
    631 ; CHECK-LABEL: test_f128_v8i16:
    632 define fp128 @test_f128_v8i16(<8 x i16> %p) {
    633 ; HARD: vrev64.16 q{{[0-9]+}}, q0
    634     %1 = add <8 x i16> %p, %p
    635     %2 = bitcast <8 x i16> %1 to fp128
    636     %3 = fadd fp128 %2, %2
    637     ret fp128 %3
    638 ; CHECK: vst1.32 {d{{[0-9]+}}[1]}, [{{[a-z0-9]+}}:32]
    639 ; CHECK: vst1.32 {d{{[0-9]+}}[0]}, [{{[a-z0-9]+}}:32]
    640 }
    641 
    642 ; CHECK-LABEL: test_f128_v16i8:
    643 define fp128 @test_f128_v16i8(<16 x i8> %p) {
    644 ; HARD: vrev64.8 q{{[0-9]+}}, q0
    645     %1 = add <16 x i8> %p, %p
    646     %2 = bitcast <16 x i8> %1 to fp128
    647     %3 = fadd fp128 %2, %2
    648     ret fp128 %3
    649 ; CHECK: vst1.32 {d{{[0-9]+}}[1]}, [{{[a-z0-9]+}}:32]
    650 ; CHECK: vst1.32 {d{{[0-9]+}}[0]}, [{{[a-z0-9]+}}:32]
    651 }
    652 
    653 ; CHECK-LABEL: test_v2f64_f128:
    654 define <2 x double> @test_v2f64_f128(fp128 %p) {
    655 ; CHECK: vmov.32 [[REG1:d[0-9]+]][0], r0
    656 ; CHECK: vmov.32 [[REG1]][1], r1
    657 ; CHECK: vmov.32 [[REG2:d[0-9]+]][0], r2
    658 ; CHECK: vmov.32 [[REG2]][1], r3
    659     %1 = fadd fp128 %p, %p
    660     %2 = bitcast fp128 %1 to <2 x double>
    661     %3 = fadd <2 x double> %2, %2
    662     ret <2 x double> %3
    663 ; SOFT: vadd.f64 [[REG1:d[0-9]+]]
    664 ; SOFT: vadd.f64 [[REG2:d[0-9]+]]
    665 ; SOFT: vmov r1, r0, [[REG2]]
    666 ; SOFT: vmov r3, r2, [[REG1]]
    667 ; HARD: vadd.f64 d1
    668 ; HARD: vadd.f64 d0
    669 }
    670 
    671 ; CHECK-LABEL: test_v2f64_v2i64:
    672 define <2 x double> @test_v2f64_v2i64(<2 x i64> %p) {
    673 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    674 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    675 ; HARD: vadd.i64 q{{[0-9]+}}, q0
    676     %1 = add <2 x i64> %p, %p
    677     %2 = bitcast <2 x i64> %1 to <2 x double>
    678     %3 = fadd <2 x double> %2, %2
    679     ret <2 x double> %3
    680 ; SOFT: vadd.f64 [[REG1:d[0-9]+]]
    681 ; SOFT: vadd.f64 [[REG2:d[0-9]+]]
    682 ; SOFT: vmov r1, r0, [[REG2]]
    683 ; SOFT: vmov r3, r2, [[REG1]]
    684 ; HARD: vadd.f64 d1
    685 ; HARD: vadd.f64 d0
    686 }
    687 
    688 ; CHECK-LABEL: test_v2f64_v4f32:
    689 define <2 x double> @test_v2f64_v4f32(<4 x float> %p) {
    690 ; HARD: vrev64.32  q{{[0-9]+}}, q0
    691     %1 = fadd <4 x float> %p, %p
    692     %2 = bitcast <4 x float> %1 to <2 x double>
    693     %3 = fadd <2 x double> %2, %2
    694     ret <2 x double> %3
    695 ; SOFT: vadd.f64 [[REG1:d[0-9]+]]
    696 ; SOFT: vadd.f64 [[REG2:d[0-9]+]]
    697 ; SOFT: vmov r1, r0, [[REG2]]
    698 ; SOFT: vmov r3, r2, [[REG1]]
    699 ; HARD: vadd.f64 d1
    700 ; HARD: vadd.f64 d0
    701 }
    702 
    703 ; CHECK-LABEL: test_v2f64_v4i32:
    704 define <2 x double> @test_v2f64_v4i32(<4 x i32> %p) {
    705 ; HARD: vrev64.32  q{{[0-9]+}}, q0
    706     %1 = add <4 x i32> %p, %p
    707     %2 = bitcast <4 x i32> %1 to <2 x double>
    708     %3 = fadd <2 x double> %2, %2
    709     ret <2 x double> %3
    710 ; SOFT: vadd.f64 [[REG1:d[0-9]+]]
    711 ; SOFT: vadd.f64 [[REG2:d[0-9]+]]
    712 ; SOFT: vmov r1, r0, [[REG2]]
    713 ; SOFT: vmov r3, r2, [[REG1]]
    714 ; HARD: vadd.f64 d1
    715 ; HARD: vadd.f64 d0
    716 }
    717 
    718 ; CHECK-LABEL: test_v2f64_v8i16:
    719 define <2 x double> @test_v2f64_v8i16(<8 x i16> %p) {
    720 ; HARD: vrev64.16  q{{[0-9]+}}, q0
    721     %1 = add <8 x i16> %p, %p
    722     %2 = bitcast <8 x i16> %1 to <2 x double>
    723     %3 = fadd <2 x double> %2, %2
    724     ret <2 x double> %3
    725 ; SOFT: vadd.f64 [[REG1:d[0-9]+]]
    726 ; SOFT: vadd.f64 [[REG2:d[0-9]+]]
    727 ; SOFT: vmov r1, r0, [[REG2]]
    728 ; SOFT: vmov r3, r2, [[REG1]]
    729 ; HARD: vadd.f64 d1
    730 ; HARD: vadd.f64 d0
    731 }
    732 
    733 ; CHECK-LABEL: test_v2f64_v16i8:
    734 define <2 x double> @test_v2f64_v16i8(<16 x i8> %p) {
    735 ; HARD: vrev64.8  q{{[0-9]+}}, q0
    736     %1 = add <16 x i8> %p, %p
    737     %2 = bitcast <16 x i8> %1 to <2 x double>
    738     %3 = fadd <2 x double> %2, %2
    739     ret <2 x double> %3
    740 ; SOFT: vadd.f64 [[REG1:d[0-9]+]]
    741 ; SOFT: vadd.f64 [[REG2:d[0-9]+]]
    742 ; SOFT: vmov r1, r0, [[REG2]]
    743 ; SOFT: vmov r3, r2, [[REG1]]
    744 ; HARD: vadd.f64 d1
    745 ; HARD: vadd.f64 d0
    746 }
    747 
    748 ; CHECK-LABEL: test_v2i64_f128:
    749 define <2 x i64> @test_v2i64_f128(fp128 %p) {
    750 ; CHECK: vmov.32 [[REG1:d[0-9]+]][0], r0
    751 ; CHECK: vmov.32 [[REG1]][1], r1
    752 ; CHECK: vmov.32 [[REG2:d[0-9]+]][0], r2
    753 ; CHECK: vmov.32 [[REG2]][1], r3
    754     %1 = fadd fp128 %p, %p
    755     %2 = bitcast fp128 %1 to <2 x i64>
    756     %3 = add <2 x i64> %2, %2
    757     ret <2 x i64> %3
    758 ; SOFT: vmov r1, r0
    759 ; SOFT: vmov r3, r2
    760 ; HARD: vadd.i64 q0
    761 }
    762 
    763 ; CHECK-LABEL: test_v2i64_v2f64:
    764 define <2 x i64> @test_v2i64_v2f64(<2 x double> %p) {
    765 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    766 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    767 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG1]]
    768 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG2]]
    769 ; HARD: vadd.f64  d{{[0-9]+}}, d1
    770 ; HARD: vadd.f64  d{{[0-9]+}}, d0
    771     %1 = fadd <2 x double> %p, %p
    772     %2 = bitcast <2 x double> %1 to <2 x i64>
    773     %3 = add <2 x i64> %2, %2
    774     ret <2 x i64> %3
    775 ; SOFT: vmov r1, r0
    776 ; SOFT: vmov r3, r2
    777 ; HARD: vadd.i64 q0
    778 }
    779 
    780 ; CHECK-LABEL: test_v2i64_v4f32:
    781 define <2 x i64> @test_v2i64_v4f32(<4 x float> %p) {
    782 ; HARD: vrev64.32  q{{[0-9]+}}, q0
    783     %1 = fadd <4 x float> %p, %p
    784     %2 = bitcast <4 x float> %1 to <2 x i64>
    785     %3 = add <2 x i64> %2, %2
    786     ret <2 x i64> %3
    787 ; SOFT: vmov r1, r0
    788 ; SOFT: vmov r3, r2
    789 ; HARD: vadd.i64 q0
    790 }
    791 
    792 ; CHECK-LABEL: test_v2i64_v4i32:
    793 define <2 x i64> @test_v2i64_v4i32(<4 x i32> %p) {
    794 ; HARD: vrev64.32  q{{[0-9]+}}, q0
    795     %1 = add <4 x i32> %p, %p
    796     %2 = bitcast <4 x i32> %1 to <2 x i64>
    797     %3 = add <2 x i64> %2, %2
    798     ret <2 x i64> %3
    799 ; SOFT: vmov r1, r0
    800 ; SOFT: vmov r3, r2
    801 ; HARD: vadd.i64 q0
    802 }
    803 
    804 ; CHECK-LABEL: test_v2i64_v8i16:
    805 define <2 x i64> @test_v2i64_v8i16(<8 x i16> %p) {
    806 ; HARD: vrev64.16  q{{[0-9]+}}, q0
    807     %1 = add <8 x i16> %p, %p
    808     %2 = bitcast <8 x i16> %1 to <2 x i64>
    809     %3 = add <2 x i64> %2, %2
    810     ret <2 x i64> %3
    811 ; SOFT: vmov r1, r0
    812 ; SOFT: vmov r3, r2
    813 ; HARD: vadd.i64 q0
    814 }
    815 
    816 ; CHECK-LABEL: test_v2i64_v16i8:
    817 define <2 x i64> @test_v2i64_v16i8(<16 x i8> %p) {
    818 ; HARD: vrev64.8  q{{[0-9]+}}, q0
    819     %1 = add <16 x i8> %p, %p
    820     %2 = bitcast <16 x i8> %1 to <2 x i64>
    821     %3 = add <2 x i64> %2, %2
    822     ret <2 x i64> %3
    823 ; SOFT: vmov r1, r0
    824 ; SOFT: vmov r3, r2
    825 ; HARD: vadd.i64 q0
    826 }
    827 
    828 ; CHECK-LABEL: test_v4f32_f128:
    829 define <4 x float> @test_v4f32_f128(fp128 %p) {
    830 ; CHECK: vmov.32 [[REG1:d[0-9]+]][0], r0
    831 ; CHECK: vmov.32 [[REG1]][1], r1
    832 ; CHECK: vmov.32 [[REG2:d[0-9]+]][0], r2
    833 ; CHECK: vmov.32 [[REG2]][1], r3
    834     %1 = fadd fp128 %p, %p
    835     %2 = bitcast fp128 %1 to <4 x float>
    836     %3 = fadd <4 x float> %2, %2
    837     ret <4 x float> %3
    838 ; SOFT: vmov r1, r0
    839 ; SOFT: vmov r3, r2
    840 ; HARD: vrev64.32 q0
    841 }
    842 
    843 ; CHECK-LABEL: test_v4f32_v2f64:
    844 define <4 x float> @test_v4f32_v2f64(<2 x double> %p) {
    845 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    846 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    847 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG1]]
    848 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG2]]
    849 ; HARD: vadd.f64  d{{[0-9]+}}, d1
    850 ; HARD: vadd.f64  d{{[0-9]+}}, d0
    851     %1 = fadd <2 x double> %p, %p
    852     %2 = bitcast <2 x double> %1 to <4 x float>
    853     %3 = fadd <4 x float> %2, %2
    854     ret <4 x float> %3
    855 ; SOFT: vmov r1, r0
    856 ; SOFT: vmov r3, r2
    857 ; HARD: vrev64.32 q0
    858 }
    859 
    860 ; CHECK-LABEL: test_v4f32_v2i64:
    861 define <4 x float> @test_v4f32_v2i64(<2 x i64> %p) {
    862 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    863 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    864 ; HARD: vadd.i64  q{{[0-9]+}}, q0
    865     %1 = add <2 x i64> %p, %p
    866     %2 = bitcast <2 x i64> %1 to <4 x float>
    867     %3 = fadd <4 x float> %2, %2
    868     ret <4 x float> %3
    869 ; SOFT: vmov r1, r0
    870 ; SOFT: vmov r3, r2
    871 ; HARD: vrev64.32 q0
    872 }
    873 
    874 ; CHECK-LABEL: test_v4f32_v4i32:
    875 define <4 x float> @test_v4f32_v4i32(<4 x i32> %p) {
    876 ; HARD: vrev64.32  q{{[0-9]+}}, q0
    877     %1 = add <4 x i32> %p, %p
    878     %2 = bitcast <4 x i32> %1 to <4 x float>
    879     %3 = fadd <4 x float> %2, %2
    880     ret <4 x float> %3
    881 ; SOFT: vmov r1, r0
    882 ; SOFT: vmov r3, r2
    883 ; HARD: vrev64.32 q0
    884 }
    885 
    886 ; CHECK-LABEL: test_v4f32_v8i16:
    887 define <4 x float> @test_v4f32_v8i16(<8 x i16> %p) {
    888 ; HARD: vrev64.16  q{{[0-9]+}}, q0
    889     %1 = add <8 x i16> %p, %p
    890     %2 = bitcast <8 x i16> %1 to <4 x float>
    891     %3 = fadd <4 x float> %2, %2
    892     ret <4 x float> %3
    893 ; SOFT: vmov r1, r0
    894 ; SOFT: vmov r3, r2
    895 ; HARD: vrev64.32 q0
    896 }
    897 
    898 ; CHECK-LABEL: test_v4f32_v16i8:
    899 define <4 x float> @test_v4f32_v16i8(<16 x i8> %p) {
    900 ; HARD: vrev64.8  q{{[0-9]+}}, q0
    901     %1 = add <16 x i8> %p, %p
    902     %2 = bitcast <16 x i8> %1 to <4 x float>
    903     %3 = fadd <4 x float> %2, %2
    904     ret <4 x float> %3
    905 ; SOFT: vmov r1, r0
    906 ; SOFT: vmov r3, r2
    907 ; HARD: vrev64.32 q0
    908 }
    909 
    910 ; CHECK-LABEL: test_v4i32_f128:
    911 define <4 x i32> @test_v4i32_f128(fp128 %p) {
    912 ; CHECK: vmov.32 [[REG1:d[0-9]+]][0], r0
    913 ; CHECK: vmov.32 [[REG1]][1], r1
    914 ; CHECK: vmov.32 [[REG2:d[0-9]+]][0], r2
    915 ; CHECK: vmov.32 [[REG2]][1], r3
    916     %1 = fadd fp128 %p, %p
    917     %2 = bitcast fp128 %1 to <4 x i32>
    918     %3 = add <4 x i32> %2, %2
    919     ret <4 x i32> %3
    920 ; SOFT: vmov r1, r0
    921 ; SOFT: vmov r3, r2
    922 ; HARD: vrev64.32 q0
    923 }
    924 
    925 ; CHECK-LABEL: test_v4i32_v2f64:
    926 define <4 x i32> @test_v4i32_v2f64(<2 x double> %p) {
    927 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    928 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    929 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG1]]
    930 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG2]]
    931 ; HARD: vadd.f64  d{{[0-9]+}}, d1
    932 ; HARD: vadd.f64  d{{[0-9]+}}, d0
    933     %1 = fadd <2 x double> %p, %p
    934     %2 = bitcast <2 x double> %1 to <4 x i32>
    935     %3 = add <4 x i32> %2, %2
    936     ret <4 x i32> %3
    937 ; SOFT: vmov r1, r0
    938 ; SOFT: vmov r3, r2
    939 ; HARD: vrev64.32 q0
    940 }
    941 
    942 ; CHECK-LABEL: test_v4i32_v2i64:
    943 define <4 x i32> @test_v4i32_v2i64(<2 x i64> %p) {
    944 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    945 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    946 ; HARD: vadd.i64  q{{[0-9]+}}, q0
    947     %1 = add <2 x i64> %p, %p
    948     %2 = bitcast <2 x i64> %1 to <4 x i32>
    949     %3 = add <4 x i32> %2, %2
    950     ret <4 x i32> %3
    951 ; SOFT: vmov r1, r0
    952 ; SOFT: vmov r3, r2
    953 ; HARD: vrev64.32 q0
    954 }
    955 
    956 ; CHECK-LABEL: test_v4i32_v4f32:
    957 define <4 x i32> @test_v4i32_v4f32(<4 x float> %p) {
    958 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    959 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    960 ; HARD: vrev64.32  q{{[0-9]+}}, q0
    961     %1 = fadd <4 x float> %p, %p
    962     %2 = bitcast <4 x float> %1 to <4 x i32>
    963     %3 = add <4 x i32> %2, %2
    964     ret <4 x i32> %3
    965 ; SOFT: vmov r1, r0
    966 ; SOFT: vmov r3, r2
    967 ; HARD: vrev64.32 q0
    968 }
    969 
    970 ; CHECK-LABEL: test_v4i32_v8i16:
    971 define <4 x i32> @test_v4i32_v8i16(<8 x i16> %p) {
    972 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    973 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    974 ; HARD: vrev64.16  q{{[0-9]+}}, q0
    975     %1 = add <8 x i16> %p, %p
    976     %2 = bitcast <8 x i16> %1 to <4 x i32>
    977     %3 = add <4 x i32> %2, %2
    978     ret <4 x i32> %3
    979 ; SOFT: vmov r1, r0
    980 ; SOFT: vmov r3, r2
    981 ; HARD: vrev64.32 q0
    982 }
    983 
    984 ; CHECK-LABEL: test_v4i32_v16i8:
    985 define <4 x i32> @test_v4i32_v16i8(<16 x i8> %p) {
    986 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
    987 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
    988 ; HARD: vrev64.8  q{{[0-9]+}}, q0
    989     %1 = add <16 x i8> %p, %p
    990     %2 = bitcast <16 x i8> %1 to <4 x i32>
    991     %3 = add <4 x i32> %2, %2
    992     ret <4 x i32> %3
    993 ; SOFT: vmov r1, r0
    994 ; SOFT: vmov r3, r2
    995 ; HARD: vrev64.32 q0
    996 }
    997 
    998 ; CHECK-LABEL: test_v8i16_f128:
    999 define <8 x i16> @test_v8i16_f128(fp128 %p) {
   1000 ; CHECK: vmov.32 [[REG1:d[0-9]+]][0], r0
   1001 ; CHECK: vmov.32 [[REG1]][1], r1
   1002 ; CHECK: vmov.32 [[REG2:d[0-9]+]][0], r2
   1003 ; CHECK: vmov.32 [[REG2]][1], r3
   1004     %1 = fadd fp128 %p, %p
   1005     %2 = bitcast fp128 %1 to <8 x i16>
   1006     %3 = add <8 x i16> %2, %2
   1007     ret <8 x i16> %3
   1008 ; SOFT: vmov r1, r0
   1009 ; SOFT: vmov r3, r2
   1010 ; HARD: vrev64.16 q0
   1011 }
   1012 
   1013 ; CHECK-LABEL: test_v8i16_v2f64:
   1014 define <8 x i16> @test_v8i16_v2f64(<2 x double> %p) {
   1015 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
   1016 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
   1017 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG1]]
   1018 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG2]]
   1019 ; HARD: vadd.f64  d{{[0-9]+}}, d1
   1020 ; HARD: vadd.f64  d{{[0-9]+}}, d0
   1021     %1 = fadd <2 x double> %p, %p
   1022     %2 = bitcast <2 x double> %1 to <8 x i16>
   1023     %3 = add <8 x i16> %2, %2
   1024     ret <8 x i16> %3
   1025 ; SOFT: vmov r1, r0
   1026 ; SOFT: vmov r3, r2
   1027 ; HARD: vrev64.16 q0
   1028 }
   1029 
   1030 ; CHECK-LABEL: test_v8i16_v2i64:
   1031 define <8 x i16> @test_v8i16_v2i64(<2 x i64> %p) {
   1032 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
   1033 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
   1034 ; HARD: vadd.i64  q{{[0-9]+}}, q0
   1035     %1 = add <2 x i64> %p, %p
   1036     %2 = bitcast <2 x i64> %1 to <8 x i16>
   1037     %3 = add <8 x i16> %2, %2
   1038     ret <8 x i16> %3
   1039 ; SOFT: vmov r1, r0
   1040 ; SOFT: vmov r3, r2
   1041 ; HARD: vrev64.16 q0
   1042 }
   1043 
   1044 ; CHECK-LABEL: test_v8i16_v4f32:
   1045 define <8 x i16> @test_v8i16_v4f32(<4 x float> %p) {
   1046 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
   1047 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
   1048 ; HARD: vrev64.32  q{{[0-9]+}}, q0
   1049     %1 = fadd <4 x float> %p, %p
   1050     %2 = bitcast <4 x float> %1 to <8 x i16>
   1051     %3 = add <8 x i16> %2, %2
   1052     ret <8 x i16> %3
   1053 ; SOFT: vmov r1, r0
   1054 ; SOFT: vmov r3, r2
   1055 ; HARD: vrev64.16 q0
   1056 }
   1057 
   1058 ; CHECK-LABEL: test_v8i16_v4i32:
   1059 define <8 x i16> @test_v8i16_v4i32(<4 x i32> %p) {
   1060 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
   1061 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
   1062 ; HARD: vrev64.32  q{{[0-9]+}}, q0
   1063     %1 = add <4 x i32> %p, %p
   1064     %2 = bitcast <4 x i32> %1 to <8 x i16>
   1065     %3 = add <8 x i16> %2, %2
   1066     ret <8 x i16> %3
   1067 ; SOFT: vmov r1, r0
   1068 ; SOFT: vmov r3, r2
   1069 ; HARD: vrev64.16 q0
   1070 }
   1071 
   1072 ; CHECK-LABEL: test_v8i16_v16i8:
   1073 define <8 x i16> @test_v8i16_v16i8(<16 x i8> %p) {
   1074 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
   1075 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
   1076 ; HARD: vrev64.8 q{{[0-9]+}}, q0
   1077     %1 = add <16 x i8> %p, %p
   1078     %2 = bitcast <16 x i8> %1 to <8 x i16>
   1079     %3 = add <8 x i16> %2, %2
   1080     ret <8 x i16> %3
   1081 ; SOFT: vmov r1, r0
   1082 ; SOFT: vmov r3, r2
   1083 ; HARD: vrev64.16 q0
   1084 }
   1085 
   1086 ; CHECK-LABEL: test_v16i8_f128:
   1087 define <16 x i8> @test_v16i8_f128(fp128 %p) {
   1088 ; CHECK: vmov.32 [[REG1:d[0-9]+]][0], r0
   1089 ; CHECK: vmov.32 [[REG1]][1], r1
   1090 ; CHECK: vmov.32 [[REG2:d[0-9]+]][0], r2
   1091 ; CHECK: vmov.32 [[REG2]][1], r3
   1092     %1 = fadd fp128 %p, %p
   1093     %2 = bitcast fp128 %1 to <16 x i8>
   1094     %3 = add <16 x i8> %2, %2
   1095     ret <16 x i8> %3
   1096 ; SOFT: vmov r1, r0
   1097 ; SOFT: vmov r3, r2
   1098 ; HARD: vrev64.8 q0
   1099 }
   1100 
   1101 ; CHECK-LABEL: test_v16i8_v2f64:
   1102 define <16 x i8> @test_v16i8_v2f64(<2 x double> %p) {
   1103 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
   1104 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
   1105 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG1]]
   1106 ; SOFT: vadd.f64 d{{[0-9]+}}, [[REG2]]
   1107 ; HARD: vadd.f64  d{{[0-9]+}}, d1
   1108 ; HARD: vadd.f64  d{{[0-9]+}}, d0
   1109     %1 = fadd <2 x double> %p, %p
   1110     %2 = bitcast <2 x double> %1 to <16 x i8>
   1111     %3 = add <16 x i8> %2, %2
   1112     ret <16 x i8> %3
   1113 ; SOFT: vmov r1, r0
   1114 ; SOFT: vmov r3, r2
   1115 ; HARD: vrev64.8 q0
   1116 }
   1117 
   1118 ; CHECK-LABEL: test_v16i8_v2i64:
   1119 define <16 x i8> @test_v16i8_v2i64(<2 x i64> %p) {
   1120 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
   1121 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
   1122 ; HARD: vadd.i64  q{{[0-9]+}}, q0
   1123     %1 = add <2 x i64> %p, %p
   1124     %2 = bitcast <2 x i64> %1 to <16 x i8>
   1125     %3 = add <16 x i8> %2, %2
   1126     ret <16 x i8> %3
   1127 ; SOFT: vmov r1, r0
   1128 ; SOFT: vmov r3, r2
   1129 ; HARD: vrev64.8 q0
   1130 }
   1131 
   1132 ; CHECK-LABEL: test_v16i8_v4f32:
   1133 define <16 x i8> @test_v16i8_v4f32(<4 x float> %p) {
   1134 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
   1135 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
   1136 ; HARD: vrev64.32 q{{[0-9]+}}, q0
   1137     %1 = fadd <4 x float> %p, %p
   1138     %2 = bitcast <4 x float> %1 to <16 x i8>
   1139     %3 = add <16 x i8> %2, %2
   1140     ret <16 x i8> %3
   1141 ; SOFT: vmov r1, r0
   1142 ; SOFT: vmov r3, r2
   1143 ; HARD: vrev64.8 q0
   1144 }
   1145 
   1146 ; CHECK-LABEL: test_v16i8_v4i32:
   1147 define <16 x i8> @test_v16i8_v4i32(<4 x i32> %p) {
   1148 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
   1149 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
   1150 ; HARD: vrev64.32 q{{[0-9]+}}, q0
   1151     %1 = add <4 x i32> %p, %p
   1152     %2 = bitcast <4 x i32> %1 to <16 x i8>
   1153     %3 = add <16 x i8> %2, %2
   1154     ret <16 x i8> %3
   1155 ; SOFT: vmov r1, r0
   1156 ; SOFT: vmov r3, r2
   1157 ; HARD: vrev64.8 q0
   1158 }
   1159 
   1160 ; CHECK-LABEL: test_v16i8_v8i16:
   1161 define <16 x i8> @test_v16i8_v8i16(<8 x i16> %p) {
   1162 ; SOFT: vmov [[REG1:d[0-9]+]], r3, r2
   1163 ; SOFT: vmov [[REG2:d[0-9]+]], r1, r0
   1164 ; HARD: vrev64.16 q{{[0-9]+}}, q0
   1165     %1 = add <8 x i16> %p, %p
   1166     %2 = bitcast <8 x i16> %1 to <16 x i8>
   1167     %3 = add <16 x i8> %2, %2
   1168     ret <16 x i8> %3
   1169 ; SOFT: vmov r1, r0
   1170 ; SOFT: vmov r3, r2
   1171 ; HARD: vrev64.8 q0
   1172 }
   1173