Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=SSE --check-prefix=SSE2
      3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4a | FileCheck %s --check-prefix=SSE --check-prefix=SSE4A
      4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE --check-prefix=SSE41
      5 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
      6 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
      7 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512vl | FileCheck %s --check-prefix=VLX
      8 
      9 ; Make sure that we generate non-temporal stores for the test cases below.
     10 ; We use xorps for zeroing, so domain information isn't available anymore.
     11 
     12 ; Scalar versions (zeroing means we can this even for fp types).
     13 
     14 define void @test_zero_f32(float* %dst) {
     15 ; SSE-LABEL: test_zero_f32:
     16 ; SSE:       # %bb.0:
     17 ; SSE-NEXT:    xorl %eax, %eax
     18 ; SSE-NEXT:    movntil %eax, (%rdi)
     19 ; SSE-NEXT:    retq
     20 ;
     21 ; AVX-LABEL: test_zero_f32:
     22 ; AVX:       # %bb.0:
     23 ; AVX-NEXT:    xorl %eax, %eax
     24 ; AVX-NEXT:    movntil %eax, (%rdi)
     25 ; AVX-NEXT:    retq
     26 ;
     27 ; VLX-LABEL: test_zero_f32:
     28 ; VLX:       # %bb.0:
     29 ; VLX-NEXT:    xorl %eax, %eax
     30 ; VLX-NEXT:    movntil %eax, (%rdi)
     31 ; VLX-NEXT:    retq
     32   store float zeroinitializer, float* %dst, align 1, !nontemporal !1
     33   ret void
     34 }
     35 
     36 define void @test_zero_i32(i32* %dst) {
     37 ; SSE-LABEL: test_zero_i32:
     38 ; SSE:       # %bb.0:
     39 ; SSE-NEXT:    xorl %eax, %eax
     40 ; SSE-NEXT:    movntil %eax, (%rdi)
     41 ; SSE-NEXT:    retq
     42 ;
     43 ; AVX-LABEL: test_zero_i32:
     44 ; AVX:       # %bb.0:
     45 ; AVX-NEXT:    xorl %eax, %eax
     46 ; AVX-NEXT:    movntil %eax, (%rdi)
     47 ; AVX-NEXT:    retq
     48 ;
     49 ; VLX-LABEL: test_zero_i32:
     50 ; VLX:       # %bb.0:
     51 ; VLX-NEXT:    xorl %eax, %eax
     52 ; VLX-NEXT:    movntil %eax, (%rdi)
     53 ; VLX-NEXT:    retq
     54   store i32 zeroinitializer, i32* %dst, align 1, !nontemporal !1
     55   ret void
     56 }
     57 
     58 define void @test_zero_f64(double* %dst) {
     59 ; SSE-LABEL: test_zero_f64:
     60 ; SSE:       # %bb.0:
     61 ; SSE-NEXT:    xorl %eax, %eax
     62 ; SSE-NEXT:    movntiq %rax, (%rdi)
     63 ; SSE-NEXT:    retq
     64 ;
     65 ; AVX-LABEL: test_zero_f64:
     66 ; AVX:       # %bb.0:
     67 ; AVX-NEXT:    xorl %eax, %eax
     68 ; AVX-NEXT:    movntiq %rax, (%rdi)
     69 ; AVX-NEXT:    retq
     70 ;
     71 ; VLX-LABEL: test_zero_f64:
     72 ; VLX:       # %bb.0:
     73 ; VLX-NEXT:    xorl %eax, %eax
     74 ; VLX-NEXT:    movntiq %rax, (%rdi)
     75 ; VLX-NEXT:    retq
     76   store double zeroinitializer, double* %dst, align 1, !nontemporal !1
     77   ret void
     78 }
     79 
     80 define void @test_zero_i64(i64* %dst) {
     81 ; SSE-LABEL: test_zero_i64:
     82 ; SSE:       # %bb.0:
     83 ; SSE-NEXT:    xorl %eax, %eax
     84 ; SSE-NEXT:    movntiq %rax, (%rdi)
     85 ; SSE-NEXT:    retq
     86 ;
     87 ; AVX-LABEL: test_zero_i64:
     88 ; AVX:       # %bb.0:
     89 ; AVX-NEXT:    xorl %eax, %eax
     90 ; AVX-NEXT:    movntiq %rax, (%rdi)
     91 ; AVX-NEXT:    retq
     92 ;
     93 ; VLX-LABEL: test_zero_i64:
     94 ; VLX:       # %bb.0:
     95 ; VLX-NEXT:    xorl %eax, %eax
     96 ; VLX-NEXT:    movntiq %rax, (%rdi)
     97 ; VLX-NEXT:    retq
     98   store i64 zeroinitializer, i64* %dst, align 1, !nontemporal !1
     99   ret void
    100 }
    101 
    102 ; And now XMM versions.
    103 
    104 define void @test_zero_v4f32(<4 x float>* %dst) {
    105 ; SSE-LABEL: test_zero_v4f32:
    106 ; SSE:       # %bb.0:
    107 ; SSE-NEXT:    xorps %xmm0, %xmm0
    108 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    109 ; SSE-NEXT:    retq
    110 ;
    111 ; AVX-LABEL: test_zero_v4f32:
    112 ; AVX:       # %bb.0:
    113 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    114 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    115 ; AVX-NEXT:    retq
    116 ;
    117 ; VLX-LABEL: test_zero_v4f32:
    118 ; VLX:       # %bb.0:
    119 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    120 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    121 ; VLX-NEXT:    retq
    122   store <4 x float> zeroinitializer, <4 x float>* %dst, align 16, !nontemporal !1
    123   ret void
    124 }
    125 
    126 define void @test_zero_v4i32(<4 x i32>* %dst) {
    127 ; SSE-LABEL: test_zero_v4i32:
    128 ; SSE:       # %bb.0:
    129 ; SSE-NEXT:    xorps %xmm0, %xmm0
    130 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    131 ; SSE-NEXT:    retq
    132 ;
    133 ; AVX-LABEL: test_zero_v4i32:
    134 ; AVX:       # %bb.0:
    135 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    136 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    137 ; AVX-NEXT:    retq
    138 ;
    139 ; VLX-LABEL: test_zero_v4i32:
    140 ; VLX:       # %bb.0:
    141 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    142 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    143 ; VLX-NEXT:    retq
    144   store <4 x i32> zeroinitializer, <4 x i32>* %dst, align 16, !nontemporal !1
    145   store <4 x i32> zeroinitializer, <4 x i32>* %dst, align 16, !nontemporal !1
    146   ret void
    147 }
    148 
    149 define void @test_zero_v2f64(<2 x double>* %dst) {
    150 ; SSE-LABEL: test_zero_v2f64:
    151 ; SSE:       # %bb.0:
    152 ; SSE-NEXT:    xorps %xmm0, %xmm0
    153 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    154 ; SSE-NEXT:    retq
    155 ;
    156 ; AVX-LABEL: test_zero_v2f64:
    157 ; AVX:       # %bb.0:
    158 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    159 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    160 ; AVX-NEXT:    retq
    161 ;
    162 ; VLX-LABEL: test_zero_v2f64:
    163 ; VLX:       # %bb.0:
    164 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    165 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    166 ; VLX-NEXT:    retq
    167   store <2 x double> zeroinitializer, <2 x double>* %dst, align 16, !nontemporal !1
    168   ret void
    169 }
    170 
    171 define void @test_zero_v2i64(<2 x i64>* %dst) {
    172 ; SSE-LABEL: test_zero_v2i64:
    173 ; SSE:       # %bb.0:
    174 ; SSE-NEXT:    xorps %xmm0, %xmm0
    175 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    176 ; SSE-NEXT:    retq
    177 ;
    178 ; AVX-LABEL: test_zero_v2i64:
    179 ; AVX:       # %bb.0:
    180 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    181 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    182 ; AVX-NEXT:    retq
    183 ;
    184 ; VLX-LABEL: test_zero_v2i64:
    185 ; VLX:       # %bb.0:
    186 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    187 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    188 ; VLX-NEXT:    retq
    189   store <2 x i64> zeroinitializer, <2 x i64>* %dst, align 16, !nontemporal !1
    190   ret void
    191 }
    192 
    193 define void @test_zero_v8i16(<8 x i16>* %dst) {
    194 ; SSE-LABEL: test_zero_v8i16:
    195 ; SSE:       # %bb.0:
    196 ; SSE-NEXT:    xorps %xmm0, %xmm0
    197 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    198 ; SSE-NEXT:    retq
    199 ;
    200 ; AVX-LABEL: test_zero_v8i16:
    201 ; AVX:       # %bb.0:
    202 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    203 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    204 ; AVX-NEXT:    retq
    205 ;
    206 ; VLX-LABEL: test_zero_v8i16:
    207 ; VLX:       # %bb.0:
    208 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    209 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    210 ; VLX-NEXT:    retq
    211   store <8 x i16> zeroinitializer, <8 x i16>* %dst, align 16, !nontemporal !1
    212   ret void
    213 }
    214 
    215 define void @test_zero_v16i8(<16 x i8>* %dst) {
    216 ; SSE-LABEL: test_zero_v16i8:
    217 ; SSE:       # %bb.0:
    218 ; SSE-NEXT:    xorps %xmm0, %xmm0
    219 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    220 ; SSE-NEXT:    retq
    221 ;
    222 ; AVX-LABEL: test_zero_v16i8:
    223 ; AVX:       # %bb.0:
    224 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    225 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    226 ; AVX-NEXT:    retq
    227 ;
    228 ; VLX-LABEL: test_zero_v16i8:
    229 ; VLX:       # %bb.0:
    230 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    231 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    232 ; VLX-NEXT:    retq
    233   store <16 x i8> zeroinitializer, <16 x i8>* %dst, align 16, !nontemporal !1
    234   ret void
    235 }
    236 
    237 ; And now YMM versions.
    238 
    239 define void @test_zero_v8f32(<8 x float>* %dst) {
    240 ; SSE-LABEL: test_zero_v8f32:
    241 ; SSE:       # %bb.0:
    242 ; SSE-NEXT:    xorps %xmm0, %xmm0
    243 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    244 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    245 ; SSE-NEXT:    retq
    246 ;
    247 ; AVX-LABEL: test_zero_v8f32:
    248 ; AVX:       # %bb.0:
    249 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    250 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    251 ; AVX-NEXT:    vzeroupper
    252 ; AVX-NEXT:    retq
    253 ;
    254 ; VLX-LABEL: test_zero_v8f32:
    255 ; VLX:       # %bb.0:
    256 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    257 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    258 ; VLX-NEXT:    vzeroupper
    259 ; VLX-NEXT:    retq
    260   store <8 x float> zeroinitializer, <8 x float>* %dst, align 32, !nontemporal !1
    261   ret void
    262 }
    263 
    264 define void @test_zero_v8i32(<8 x i32>* %dst) {
    265 ; SSE-LABEL: test_zero_v8i32:
    266 ; SSE:       # %bb.0:
    267 ; SSE-NEXT:    xorps %xmm0, %xmm0
    268 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    269 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    270 ; SSE-NEXT:    retq
    271 ;
    272 ; AVX-LABEL: test_zero_v8i32:
    273 ; AVX:       # %bb.0:
    274 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    275 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    276 ; AVX-NEXT:    vzeroupper
    277 ; AVX-NEXT:    retq
    278 ;
    279 ; VLX-LABEL: test_zero_v8i32:
    280 ; VLX:       # %bb.0:
    281 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    282 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    283 ; VLX-NEXT:    vzeroupper
    284 ; VLX-NEXT:    retq
    285   store <8 x i32> zeroinitializer, <8 x i32>* %dst, align 32, !nontemporal !1
    286   ret void
    287 }
    288 
    289 define void @test_zero_v4f64(<4 x double>* %dst) {
    290 ; SSE-LABEL: test_zero_v4f64:
    291 ; SSE:       # %bb.0:
    292 ; SSE-NEXT:    xorps %xmm0, %xmm0
    293 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    294 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    295 ; SSE-NEXT:    retq
    296 ;
    297 ; AVX-LABEL: test_zero_v4f64:
    298 ; AVX:       # %bb.0:
    299 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    300 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    301 ; AVX-NEXT:    vzeroupper
    302 ; AVX-NEXT:    retq
    303 ;
    304 ; VLX-LABEL: test_zero_v4f64:
    305 ; VLX:       # %bb.0:
    306 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    307 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    308 ; VLX-NEXT:    vzeroupper
    309 ; VLX-NEXT:    retq
    310   store <4 x double> zeroinitializer, <4 x double>* %dst, align 32, !nontemporal !1
    311   ret void
    312 }
    313 
    314 define void @test_zero_v4i64(<4 x i64>* %dst) {
    315 ; SSE-LABEL: test_zero_v4i64:
    316 ; SSE:       # %bb.0:
    317 ; SSE-NEXT:    xorps %xmm0, %xmm0
    318 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    319 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    320 ; SSE-NEXT:    retq
    321 ;
    322 ; AVX-LABEL: test_zero_v4i64:
    323 ; AVX:       # %bb.0:
    324 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    325 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    326 ; AVX-NEXT:    vzeroupper
    327 ; AVX-NEXT:    retq
    328 ;
    329 ; VLX-LABEL: test_zero_v4i64:
    330 ; VLX:       # %bb.0:
    331 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    332 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    333 ; VLX-NEXT:    vzeroupper
    334 ; VLX-NEXT:    retq
    335   store <4 x i64> zeroinitializer, <4 x i64>* %dst, align 32, !nontemporal !1
    336   ret void
    337 }
    338 
    339 define void @test_zero_v16i16(<16 x i16>* %dst) {
    340 ; SSE-LABEL: test_zero_v16i16:
    341 ; SSE:       # %bb.0:
    342 ; SSE-NEXT:    xorps %xmm0, %xmm0
    343 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    344 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    345 ; SSE-NEXT:    retq
    346 ;
    347 ; AVX-LABEL: test_zero_v16i16:
    348 ; AVX:       # %bb.0:
    349 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    350 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    351 ; AVX-NEXT:    vzeroupper
    352 ; AVX-NEXT:    retq
    353 ;
    354 ; VLX-LABEL: test_zero_v16i16:
    355 ; VLX:       # %bb.0:
    356 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    357 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    358 ; VLX-NEXT:    vzeroupper
    359 ; VLX-NEXT:    retq
    360   store <16 x i16> zeroinitializer, <16 x i16>* %dst, align 32, !nontemporal !1
    361   ret void
    362 }
    363 
    364 define void @test_zero_v32i8(<32 x i8>* %dst) {
    365 ; SSE-LABEL: test_zero_v32i8:
    366 ; SSE:       # %bb.0:
    367 ; SSE-NEXT:    xorps %xmm0, %xmm0
    368 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    369 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    370 ; SSE-NEXT:    retq
    371 ;
    372 ; AVX-LABEL: test_zero_v32i8:
    373 ; AVX:       # %bb.0:
    374 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    375 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    376 ; AVX-NEXT:    vzeroupper
    377 ; AVX-NEXT:    retq
    378 ;
    379 ; VLX-LABEL: test_zero_v32i8:
    380 ; VLX:       # %bb.0:
    381 ; VLX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
    382 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    383 ; VLX-NEXT:    vzeroupper
    384 ; VLX-NEXT:    retq
    385   store <32 x i8> zeroinitializer, <32 x i8>* %dst, align 32, !nontemporal !1
    386   ret void
    387 }
    388 
    389 
    390 ; Check that we also handle arguments.  Here the type survives longer.
    391 
    392 ; Scalar versions.
    393 
    394 define void @test_arg_f32(float %arg, float* %dst) {
    395 ; SSE2-LABEL: test_arg_f32:
    396 ; SSE2:       # %bb.0:
    397 ; SSE2-NEXT:    movss %xmm0, (%rdi)
    398 ; SSE2-NEXT:    retq
    399 ;
    400 ; SSE4A-LABEL: test_arg_f32:
    401 ; SSE4A:       # %bb.0:
    402 ; SSE4A-NEXT:    movntss %xmm0, (%rdi)
    403 ; SSE4A-NEXT:    retq
    404 ;
    405 ; SSE41-LABEL: test_arg_f32:
    406 ; SSE41:       # %bb.0:
    407 ; SSE41-NEXT:    movss %xmm0, (%rdi)
    408 ; SSE41-NEXT:    retq
    409 ;
    410 ; AVX-LABEL: test_arg_f32:
    411 ; AVX:       # %bb.0:
    412 ; AVX-NEXT:    vmovss %xmm0, (%rdi)
    413 ; AVX-NEXT:    retq
    414 ;
    415 ; VLX-LABEL: test_arg_f32:
    416 ; VLX:       # %bb.0:
    417 ; VLX-NEXT:    vmovss %xmm0, (%rdi)
    418 ; VLX-NEXT:    retq
    419   store float %arg, float* %dst, align 1, !nontemporal !1
    420   ret void
    421 }
    422 
    423 define void @test_arg_i32(i32 %arg, i32* %dst) {
    424 ; SSE-LABEL: test_arg_i32:
    425 ; SSE:       # %bb.0:
    426 ; SSE-NEXT:    movntil %edi, (%rsi)
    427 ; SSE-NEXT:    retq
    428 ;
    429 ; AVX-LABEL: test_arg_i32:
    430 ; AVX:       # %bb.0:
    431 ; AVX-NEXT:    movntil %edi, (%rsi)
    432 ; AVX-NEXT:    retq
    433 ;
    434 ; VLX-LABEL: test_arg_i32:
    435 ; VLX:       # %bb.0:
    436 ; VLX-NEXT:    movntil %edi, (%rsi)
    437 ; VLX-NEXT:    retq
    438   store i32 %arg, i32* %dst, align 1, !nontemporal !1
    439   ret void
    440 }
    441 
    442 define void @test_arg_f64(double %arg, double* %dst) {
    443 ; SSE2-LABEL: test_arg_f64:
    444 ; SSE2:       # %bb.0:
    445 ; SSE2-NEXT:    movsd %xmm0, (%rdi)
    446 ; SSE2-NEXT:    retq
    447 ;
    448 ; SSE4A-LABEL: test_arg_f64:
    449 ; SSE4A:       # %bb.0:
    450 ; SSE4A-NEXT:    movntsd %xmm0, (%rdi)
    451 ; SSE4A-NEXT:    retq
    452 ;
    453 ; SSE41-LABEL: test_arg_f64:
    454 ; SSE41:       # %bb.0:
    455 ; SSE41-NEXT:    movsd %xmm0, (%rdi)
    456 ; SSE41-NEXT:    retq
    457 ;
    458 ; AVX-LABEL: test_arg_f64:
    459 ; AVX:       # %bb.0:
    460 ; AVX-NEXT:    vmovsd %xmm0, (%rdi)
    461 ; AVX-NEXT:    retq
    462 ;
    463 ; VLX-LABEL: test_arg_f64:
    464 ; VLX:       # %bb.0:
    465 ; VLX-NEXT:    vmovsd %xmm0, (%rdi)
    466 ; VLX-NEXT:    retq
    467   store double %arg, double* %dst, align 1, !nontemporal !1
    468   ret void
    469 }
    470 
    471 define void @test_arg_i64(i64 %arg, i64* %dst) {
    472 ; SSE-LABEL: test_arg_i64:
    473 ; SSE:       # %bb.0:
    474 ; SSE-NEXT:    movntiq %rdi, (%rsi)
    475 ; SSE-NEXT:    retq
    476 ;
    477 ; AVX-LABEL: test_arg_i64:
    478 ; AVX:       # %bb.0:
    479 ; AVX-NEXT:    movntiq %rdi, (%rsi)
    480 ; AVX-NEXT:    retq
    481 ;
    482 ; VLX-LABEL: test_arg_i64:
    483 ; VLX:       # %bb.0:
    484 ; VLX-NEXT:    movntiq %rdi, (%rsi)
    485 ; VLX-NEXT:    retq
    486   store i64 %arg, i64* %dst, align 1, !nontemporal !1
    487   ret void
    488 }
    489 
    490 ; Extract versions
    491 
    492 define void @test_extract_f32(<4 x float> %arg, float* %dst) {
    493 ; SSE2-LABEL: test_extract_f32:
    494 ; SSE2:       # %bb.0:
    495 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,2,3]
    496 ; SSE2-NEXT:    movss %xmm0, (%rdi)
    497 ; SSE2-NEXT:    retq
    498 ;
    499 ; SSE4A-LABEL: test_extract_f32:
    500 ; SSE4A:       # %bb.0:
    501 ; SSE4A-NEXT:    movshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
    502 ; SSE4A-NEXT:    movntss %xmm0, (%rdi)
    503 ; SSE4A-NEXT:    retq
    504 ;
    505 ; SSE41-LABEL: test_extract_f32:
    506 ; SSE41:       # %bb.0:
    507 ; SSE41-NEXT:    extractps $1, %xmm0, %eax
    508 ; SSE41-NEXT:    movntil %eax, (%rdi)
    509 ; SSE41-NEXT:    retq
    510 ;
    511 ; AVX-LABEL: test_extract_f32:
    512 ; AVX:       # %bb.0:
    513 ; AVX-NEXT:    vextractps $1, %xmm0, %eax
    514 ; AVX-NEXT:    movntil %eax, (%rdi)
    515 ; AVX-NEXT:    retq
    516 ;
    517 ; VLX-LABEL: test_extract_f32:
    518 ; VLX:       # %bb.0:
    519 ; VLX-NEXT:    vextractps $1, %xmm0, %eax
    520 ; VLX-NEXT:    movntil %eax, (%rdi)
    521 ; VLX-NEXT:    retq
    522   %1 = extractelement <4 x float> %arg, i32 1
    523   store float %1, float* %dst, align 1, !nontemporal !1
    524   ret void
    525 }
    526 
    527 define void @test_extract_i32(<4 x i32> %arg, i32* %dst) {
    528 ; SSE2-LABEL: test_extract_i32:
    529 ; SSE2:       # %bb.0:
    530 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
    531 ; SSE2-NEXT:    movd %xmm0, %eax
    532 ; SSE2-NEXT:    movntil %eax, (%rdi)
    533 ; SSE2-NEXT:    retq
    534 ;
    535 ; SSE4A-LABEL: test_extract_i32:
    536 ; SSE4A:       # %bb.0:
    537 ; SSE4A-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
    538 ; SSE4A-NEXT:    movd %xmm0, %eax
    539 ; SSE4A-NEXT:    movntil %eax, (%rdi)
    540 ; SSE4A-NEXT:    retq
    541 ;
    542 ; SSE41-LABEL: test_extract_i32:
    543 ; SSE41:       # %bb.0:
    544 ; SSE41-NEXT:    extractps $1, %xmm0, %eax
    545 ; SSE41-NEXT:    movntil %eax, (%rdi)
    546 ; SSE41-NEXT:    retq
    547 ;
    548 ; AVX-LABEL: test_extract_i32:
    549 ; AVX:       # %bb.0:
    550 ; AVX-NEXT:    vextractps $1, %xmm0, %eax
    551 ; AVX-NEXT:    movntil %eax, (%rdi)
    552 ; AVX-NEXT:    retq
    553 ;
    554 ; VLX-LABEL: test_extract_i32:
    555 ; VLX:       # %bb.0:
    556 ; VLX-NEXT:    vextractps $1, %xmm0, %eax
    557 ; VLX-NEXT:    movntil %eax, (%rdi)
    558 ; VLX-NEXT:    retq
    559   %1 = extractelement <4 x i32> %arg, i32 1
    560   store i32 %1, i32* %dst, align 1, !nontemporal !1
    561   ret void
    562 }
    563 
    564 define void @test_extract_f64(<2 x double> %arg, double* %dst) {
    565 ; SSE2-LABEL: test_extract_f64:
    566 ; SSE2:       # %bb.0:
    567 ; SSE2-NEXT:    movhpd %xmm0, (%rdi)
    568 ; SSE2-NEXT:    retq
    569 ;
    570 ; SSE4A-LABEL: test_extract_f64:
    571 ; SSE4A:       # %bb.0:
    572 ; SSE4A-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
    573 ; SSE4A-NEXT:    movntsd %xmm0, (%rdi)
    574 ; SSE4A-NEXT:    retq
    575 ;
    576 ; SSE41-LABEL: test_extract_f64:
    577 ; SSE41:       # %bb.0:
    578 ; SSE41-NEXT:    movhpd %xmm0, (%rdi)
    579 ; SSE41-NEXT:    retq
    580 ;
    581 ; AVX-LABEL: test_extract_f64:
    582 ; AVX:       # %bb.0:
    583 ; AVX-NEXT:    vmovhpd %xmm0, (%rdi)
    584 ; AVX-NEXT:    retq
    585 ;
    586 ; VLX-LABEL: test_extract_f64:
    587 ; VLX:       # %bb.0:
    588 ; VLX-NEXT:    vmovhpd %xmm0, (%rdi)
    589 ; VLX-NEXT:    retq
    590   %1 = extractelement <2 x double> %arg, i32 1
    591   store double %1, double* %dst, align 1, !nontemporal !1
    592   ret void
    593 }
    594 
    595 define void @test_extract_i64(<2 x i64> %arg, i64* %dst) {
    596 ; SSE2-LABEL: test_extract_i64:
    597 ; SSE2:       # %bb.0:
    598 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
    599 ; SSE2-NEXT:    movq %xmm0, %rax
    600 ; SSE2-NEXT:    movntiq %rax, (%rdi)
    601 ; SSE2-NEXT:    retq
    602 ;
    603 ; SSE4A-LABEL: test_extract_i64:
    604 ; SSE4A:       # %bb.0:
    605 ; SSE4A-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
    606 ; SSE4A-NEXT:    movq %xmm0, %rax
    607 ; SSE4A-NEXT:    movntiq %rax, (%rdi)
    608 ; SSE4A-NEXT:    retq
    609 ;
    610 ; SSE41-LABEL: test_extract_i64:
    611 ; SSE41:       # %bb.0:
    612 ; SSE41-NEXT:    pextrq $1, %xmm0, %rax
    613 ; SSE41-NEXT:    movntiq %rax, (%rdi)
    614 ; SSE41-NEXT:    retq
    615 ;
    616 ; AVX-LABEL: test_extract_i64:
    617 ; AVX:       # %bb.0:
    618 ; AVX-NEXT:    vpextrq $1, %xmm0, %rax
    619 ; AVX-NEXT:    movntiq %rax, (%rdi)
    620 ; AVX-NEXT:    retq
    621 ;
    622 ; VLX-LABEL: test_extract_i64:
    623 ; VLX:       # %bb.0:
    624 ; VLX-NEXT:    vpextrq $1, %xmm0, %rax
    625 ; VLX-NEXT:    movntiq %rax, (%rdi)
    626 ; VLX-NEXT:    retq
    627   %1 = extractelement <2 x i64> %arg, i32 1
    628   store i64 %1, i64* %dst, align 1, !nontemporal !1
    629   ret void
    630 }
    631 
    632 ; And now XMM versions.
    633 
    634 define void @test_arg_v4f32(<4 x float> %arg, <4 x float>* %dst) {
    635 ; SSE-LABEL: test_arg_v4f32:
    636 ; SSE:       # %bb.0:
    637 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    638 ; SSE-NEXT:    retq
    639 ;
    640 ; AVX-LABEL: test_arg_v4f32:
    641 ; AVX:       # %bb.0:
    642 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    643 ; AVX-NEXT:    retq
    644 ;
    645 ; VLX-LABEL: test_arg_v4f32:
    646 ; VLX:       # %bb.0:
    647 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    648 ; VLX-NEXT:    retq
    649   store <4 x float> %arg, <4 x float>* %dst, align 16, !nontemporal !1
    650   ret void
    651 }
    652 
    653 define void @test_arg_v4i32(<4 x i32> %arg, <4 x i32>* %dst) {
    654 ; SSE-LABEL: test_arg_v4i32:
    655 ; SSE:       # %bb.0:
    656 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    657 ; SSE-NEXT:    retq
    658 ;
    659 ; AVX-LABEL: test_arg_v4i32:
    660 ; AVX:       # %bb.0:
    661 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    662 ; AVX-NEXT:    retq
    663 ;
    664 ; VLX-LABEL: test_arg_v4i32:
    665 ; VLX:       # %bb.0:
    666 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    667 ; VLX-NEXT:    retq
    668   store <4 x i32> %arg, <4 x i32>* %dst, align 16, !nontemporal !1
    669   ret void
    670 }
    671 
    672 define void @test_arg_v2f64(<2 x double> %arg, <2 x double>* %dst) {
    673 ; SSE-LABEL: test_arg_v2f64:
    674 ; SSE:       # %bb.0:
    675 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    676 ; SSE-NEXT:    retq
    677 ;
    678 ; AVX-LABEL: test_arg_v2f64:
    679 ; AVX:       # %bb.0:
    680 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    681 ; AVX-NEXT:    retq
    682 ;
    683 ; VLX-LABEL: test_arg_v2f64:
    684 ; VLX:       # %bb.0:
    685 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    686 ; VLX-NEXT:    retq
    687   store <2 x double> %arg, <2 x double>* %dst, align 16, !nontemporal !1
    688   ret void
    689 }
    690 
    691 define void @test_arg_v2i64(<2 x i64> %arg, <2 x i64>* %dst) {
    692 ; SSE-LABEL: test_arg_v2i64:
    693 ; SSE:       # %bb.0:
    694 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    695 ; SSE-NEXT:    retq
    696 ;
    697 ; AVX-LABEL: test_arg_v2i64:
    698 ; AVX:       # %bb.0:
    699 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    700 ; AVX-NEXT:    retq
    701 ;
    702 ; VLX-LABEL: test_arg_v2i64:
    703 ; VLX:       # %bb.0:
    704 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    705 ; VLX-NEXT:    retq
    706   store <2 x i64> %arg, <2 x i64>* %dst, align 16, !nontemporal !1
    707   ret void
    708 }
    709 
    710 define void @test_arg_v8i16(<8 x i16> %arg, <8 x i16>* %dst) {
    711 ; SSE-LABEL: test_arg_v8i16:
    712 ; SSE:       # %bb.0:
    713 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    714 ; SSE-NEXT:    retq
    715 ;
    716 ; AVX-LABEL: test_arg_v8i16:
    717 ; AVX:       # %bb.0:
    718 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    719 ; AVX-NEXT:    retq
    720 ;
    721 ; VLX-LABEL: test_arg_v8i16:
    722 ; VLX:       # %bb.0:
    723 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    724 ; VLX-NEXT:    retq
    725   store <8 x i16> %arg, <8 x i16>* %dst, align 16, !nontemporal !1
    726   ret void
    727 }
    728 
    729 define void @test_arg_v16i8(<16 x i8> %arg, <16 x i8>* %dst) {
    730 ; SSE-LABEL: test_arg_v16i8:
    731 ; SSE:       # %bb.0:
    732 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    733 ; SSE-NEXT:    retq
    734 ;
    735 ; AVX-LABEL: test_arg_v16i8:
    736 ; AVX:       # %bb.0:
    737 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    738 ; AVX-NEXT:    retq
    739 ;
    740 ; VLX-LABEL: test_arg_v16i8:
    741 ; VLX:       # %bb.0:
    742 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    743 ; VLX-NEXT:    retq
    744   store <16 x i8> %arg, <16 x i8>* %dst, align 16, !nontemporal !1
    745   ret void
    746 }
    747 
    748 ; And now YMM versions.
    749 
    750 define void @test_arg_v8f32(<8 x float> %arg, <8 x float>* %dst) {
    751 ; SSE-LABEL: test_arg_v8f32:
    752 ; SSE:       # %bb.0:
    753 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    754 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    755 ; SSE-NEXT:    retq
    756 ;
    757 ; AVX-LABEL: test_arg_v8f32:
    758 ; AVX:       # %bb.0:
    759 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    760 ; AVX-NEXT:    vzeroupper
    761 ; AVX-NEXT:    retq
    762 ;
    763 ; VLX-LABEL: test_arg_v8f32:
    764 ; VLX:       # %bb.0:
    765 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    766 ; VLX-NEXT:    vzeroupper
    767 ; VLX-NEXT:    retq
    768   store <8 x float> %arg, <8 x float>* %dst, align 32, !nontemporal !1
    769   ret void
    770 }
    771 
    772 define void @test_arg_v8i32(<8 x i32> %arg, <8 x i32>* %dst) {
    773 ; SSE-LABEL: test_arg_v8i32:
    774 ; SSE:       # %bb.0:
    775 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    776 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    777 ; SSE-NEXT:    retq
    778 ;
    779 ; AVX-LABEL: test_arg_v8i32:
    780 ; AVX:       # %bb.0:
    781 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    782 ; AVX-NEXT:    vzeroupper
    783 ; AVX-NEXT:    retq
    784 ;
    785 ; VLX-LABEL: test_arg_v8i32:
    786 ; VLX:       # %bb.0:
    787 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    788 ; VLX-NEXT:    vzeroupper
    789 ; VLX-NEXT:    retq
    790   store <8 x i32> %arg, <8 x i32>* %dst, align 32, !nontemporal !1
    791   ret void
    792 }
    793 
    794 define void @test_arg_v4f64(<4 x double> %arg, <4 x double>* %dst) {
    795 ; SSE-LABEL: test_arg_v4f64:
    796 ; SSE:       # %bb.0:
    797 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    798 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    799 ; SSE-NEXT:    retq
    800 ;
    801 ; AVX-LABEL: test_arg_v4f64:
    802 ; AVX:       # %bb.0:
    803 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    804 ; AVX-NEXT:    vzeroupper
    805 ; AVX-NEXT:    retq
    806 ;
    807 ; VLX-LABEL: test_arg_v4f64:
    808 ; VLX:       # %bb.0:
    809 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    810 ; VLX-NEXT:    vzeroupper
    811 ; VLX-NEXT:    retq
    812   store <4 x double> %arg, <4 x double>* %dst, align 32, !nontemporal !1
    813   ret void
    814 }
    815 
    816 define void @test_arg_v4i64(<4 x i64> %arg, <4 x i64>* %dst) {
    817 ; SSE-LABEL: test_arg_v4i64:
    818 ; SSE:       # %bb.0:
    819 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    820 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    821 ; SSE-NEXT:    retq
    822 ;
    823 ; AVX-LABEL: test_arg_v4i64:
    824 ; AVX:       # %bb.0:
    825 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    826 ; AVX-NEXT:    vzeroupper
    827 ; AVX-NEXT:    retq
    828 ;
    829 ; VLX-LABEL: test_arg_v4i64:
    830 ; VLX:       # %bb.0:
    831 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    832 ; VLX-NEXT:    vzeroupper
    833 ; VLX-NEXT:    retq
    834   store <4 x i64> %arg, <4 x i64>* %dst, align 32, !nontemporal !1
    835   ret void
    836 }
    837 
    838 define void @test_arg_v16i16(<16 x i16> %arg, <16 x i16>* %dst) {
    839 ; SSE-LABEL: test_arg_v16i16:
    840 ; SSE:       # %bb.0:
    841 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    842 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    843 ; SSE-NEXT:    retq
    844 ;
    845 ; AVX-LABEL: test_arg_v16i16:
    846 ; AVX:       # %bb.0:
    847 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    848 ; AVX-NEXT:    vzeroupper
    849 ; AVX-NEXT:    retq
    850 ;
    851 ; VLX-LABEL: test_arg_v16i16:
    852 ; VLX:       # %bb.0:
    853 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    854 ; VLX-NEXT:    vzeroupper
    855 ; VLX-NEXT:    retq
    856   store <16 x i16> %arg, <16 x i16>* %dst, align 32, !nontemporal !1
    857   ret void
    858 }
    859 
    860 define void @test_arg_v32i8(<32 x i8> %arg, <32 x i8>* %dst) {
    861 ; SSE-LABEL: test_arg_v32i8:
    862 ; SSE:       # %bb.0:
    863 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    864 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    865 ; SSE-NEXT:    retq
    866 ;
    867 ; AVX-LABEL: test_arg_v32i8:
    868 ; AVX:       # %bb.0:
    869 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    870 ; AVX-NEXT:    vzeroupper
    871 ; AVX-NEXT:    retq
    872 ;
    873 ; VLX-LABEL: test_arg_v32i8:
    874 ; VLX:       # %bb.0:
    875 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    876 ; VLX-NEXT:    vzeroupper
    877 ; VLX-NEXT:    retq
    878   store <32 x i8> %arg, <32 x i8>* %dst, align 32, !nontemporal !1
    879   ret void
    880 }
    881 
    882 
    883 ; Now check that if the execution domain is trivially visible, we use it.
    884 ; We use an add to make the type survive all the way to the MOVNT.
    885 
    886 define void @test_op_v4f32(<4 x float> %a, <4 x float> %b, <4 x float>* %dst) {
    887 ; SSE-LABEL: test_op_v4f32:
    888 ; SSE:       # %bb.0:
    889 ; SSE-NEXT:    addps %xmm1, %xmm0
    890 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    891 ; SSE-NEXT:    retq
    892 ;
    893 ; AVX-LABEL: test_op_v4f32:
    894 ; AVX:       # %bb.0:
    895 ; AVX-NEXT:    vaddps %xmm1, %xmm0, %xmm0
    896 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    897 ; AVX-NEXT:    retq
    898 ;
    899 ; VLX-LABEL: test_op_v4f32:
    900 ; VLX:       # %bb.0:
    901 ; VLX-NEXT:    vaddps %xmm1, %xmm0, %xmm0
    902 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    903 ; VLX-NEXT:    retq
    904   %r = fadd <4 x float> %a, %b
    905   store <4 x float> %r, <4 x float>* %dst, align 16, !nontemporal !1
    906   ret void
    907 }
    908 
    909 define void @test_op_v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32>* %dst) {
    910 ; SSE-LABEL: test_op_v4i32:
    911 ; SSE:       # %bb.0:
    912 ; SSE-NEXT:    paddd %xmm1, %xmm0
    913 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
    914 ; SSE-NEXT:    retq
    915 ;
    916 ; AVX-LABEL: test_op_v4i32:
    917 ; AVX:       # %bb.0:
    918 ; AVX-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
    919 ; AVX-NEXT:    vmovntdq %xmm0, (%rdi)
    920 ; AVX-NEXT:    retq
    921 ;
    922 ; VLX-LABEL: test_op_v4i32:
    923 ; VLX:       # %bb.0:
    924 ; VLX-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
    925 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
    926 ; VLX-NEXT:    retq
    927   %r = add <4 x i32> %a, %b
    928   store <4 x i32> %r, <4 x i32>* %dst, align 16, !nontemporal !1
    929   ret void
    930 }
    931 
    932 define void @test_op_v2f64(<2 x double> %a, <2 x double> %b, <2 x double>* %dst) {
    933 ; SSE-LABEL: test_op_v2f64:
    934 ; SSE:       # %bb.0:
    935 ; SSE-NEXT:    addpd %xmm1, %xmm0
    936 ; SSE-NEXT:    movntpd %xmm0, (%rdi)
    937 ; SSE-NEXT:    retq
    938 ;
    939 ; AVX-LABEL: test_op_v2f64:
    940 ; AVX:       # %bb.0:
    941 ; AVX-NEXT:    vaddpd %xmm1, %xmm0, %xmm0
    942 ; AVX-NEXT:    vmovntpd %xmm0, (%rdi)
    943 ; AVX-NEXT:    retq
    944 ;
    945 ; VLX-LABEL: test_op_v2f64:
    946 ; VLX:       # %bb.0:
    947 ; VLX-NEXT:    vaddpd %xmm1, %xmm0, %xmm0
    948 ; VLX-NEXT:    vmovntpd %xmm0, (%rdi)
    949 ; VLX-NEXT:    retq
    950   %r = fadd <2 x double> %a, %b
    951   store <2 x double> %r, <2 x double>* %dst, align 16, !nontemporal !1
    952   ret void
    953 }
    954 
    955 define void @test_op_v2i64(<2 x i64> %a, <2 x i64> %b, <2 x i64>* %dst) {
    956 ; SSE-LABEL: test_op_v2i64:
    957 ; SSE:       # %bb.0:
    958 ; SSE-NEXT:    paddq %xmm1, %xmm0
    959 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
    960 ; SSE-NEXT:    retq
    961 ;
    962 ; AVX-LABEL: test_op_v2i64:
    963 ; AVX:       # %bb.0:
    964 ; AVX-NEXT:    vpaddq %xmm1, %xmm0, %xmm0
    965 ; AVX-NEXT:    vmovntdq %xmm0, (%rdi)
    966 ; AVX-NEXT:    retq
    967 ;
    968 ; VLX-LABEL: test_op_v2i64:
    969 ; VLX:       # %bb.0:
    970 ; VLX-NEXT:    vpaddq %xmm1, %xmm0, %xmm0
    971 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
    972 ; VLX-NEXT:    retq
    973   %r = add <2 x i64> %a, %b
    974   store <2 x i64> %r, <2 x i64>* %dst, align 16, !nontemporal !1
    975   ret void
    976 }
    977 
    978 define void @test_op_v8i16(<8 x i16> %a, <8 x i16> %b, <8 x i16>* %dst) {
    979 ; SSE-LABEL: test_op_v8i16:
    980 ; SSE:       # %bb.0:
    981 ; SSE-NEXT:    paddw %xmm1, %xmm0
    982 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
    983 ; SSE-NEXT:    retq
    984 ;
    985 ; AVX-LABEL: test_op_v8i16:
    986 ; AVX:       # %bb.0:
    987 ; AVX-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
    988 ; AVX-NEXT:    vmovntdq %xmm0, (%rdi)
    989 ; AVX-NEXT:    retq
    990 ;
    991 ; VLX-LABEL: test_op_v8i16:
    992 ; VLX:       # %bb.0:
    993 ; VLX-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
    994 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
    995 ; VLX-NEXT:    retq
    996   %r = add <8 x i16> %a, %b
    997   store <8 x i16> %r, <8 x i16>* %dst, align 16, !nontemporal !1
    998   ret void
    999 }
   1000 
   1001 define void @test_op_v16i8(<16 x i8> %a, <16 x i8> %b, <16 x i8>* %dst) {
   1002 ; SSE-LABEL: test_op_v16i8:
   1003 ; SSE:       # %bb.0:
   1004 ; SSE-NEXT:    paddb %xmm1, %xmm0
   1005 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
   1006 ; SSE-NEXT:    retq
   1007 ;
   1008 ; AVX-LABEL: test_op_v16i8:
   1009 ; AVX:       # %bb.0:
   1010 ; AVX-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
   1011 ; AVX-NEXT:    vmovntdq %xmm0, (%rdi)
   1012 ; AVX-NEXT:    retq
   1013 ;
   1014 ; VLX-LABEL: test_op_v16i8:
   1015 ; VLX:       # %bb.0:
   1016 ; VLX-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
   1017 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
   1018 ; VLX-NEXT:    retq
   1019   %r = add <16 x i8> %a, %b
   1020   store <16 x i8> %r, <16 x i8>* %dst, align 16, !nontemporal !1
   1021   ret void
   1022 }
   1023 
   1024 ; And now YMM versions.
   1025 
   1026 define void @test_op_v8f32(<8 x float> %a, <8 x float> %b, <8 x float>* %dst) {
   1027 ; SSE-LABEL: test_op_v8f32:
   1028 ; SSE:       # %bb.0:
   1029 ; SSE-NEXT:    addps %xmm2, %xmm0
   1030 ; SSE-NEXT:    addps %xmm3, %xmm1
   1031 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
   1032 ; SSE-NEXT:    movntps %xmm0, (%rdi)
   1033 ; SSE-NEXT:    retq
   1034 ;
   1035 ; AVX-LABEL: test_op_v8f32:
   1036 ; AVX:       # %bb.0:
   1037 ; AVX-NEXT:    vaddps %ymm1, %ymm0, %ymm0
   1038 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
   1039 ; AVX-NEXT:    vzeroupper
   1040 ; AVX-NEXT:    retq
   1041 ;
   1042 ; VLX-LABEL: test_op_v8f32:
   1043 ; VLX:       # %bb.0:
   1044 ; VLX-NEXT:    vaddps %ymm1, %ymm0, %ymm0
   1045 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
   1046 ; VLX-NEXT:    vzeroupper
   1047 ; VLX-NEXT:    retq
   1048   %r = fadd <8 x float> %a, %b
   1049   store <8 x float> %r, <8 x float>* %dst, align 32, !nontemporal !1
   1050   ret void
   1051 }
   1052 
   1053 define void @test_op_v8i32(<8 x i32> %a, <8 x i32> %b, <8 x i32>* %dst) {
   1054 ; SSE-LABEL: test_op_v8i32:
   1055 ; SSE:       # %bb.0:
   1056 ; SSE-NEXT:    paddd %xmm2, %xmm0
   1057 ; SSE-NEXT:    paddd %xmm3, %xmm1
   1058 ; SSE-NEXT:    movntdq %xmm1, 16(%rdi)
   1059 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
   1060 ; SSE-NEXT:    retq
   1061 ;
   1062 ; AVX1-LABEL: test_op_v8i32:
   1063 ; AVX1:       # %bb.0:
   1064 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
   1065 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
   1066 ; AVX1-NEXT:    vpaddd %xmm2, %xmm3, %xmm2
   1067 ; AVX1-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
   1068 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
   1069 ; AVX1-NEXT:    vmovntps %ymm0, (%rdi)
   1070 ; AVX1-NEXT:    vzeroupper
   1071 ; AVX1-NEXT:    retq
   1072 ;
   1073 ; AVX2-LABEL: test_op_v8i32:
   1074 ; AVX2:       # %bb.0:
   1075 ; AVX2-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
   1076 ; AVX2-NEXT:    vmovntdq %ymm0, (%rdi)
   1077 ; AVX2-NEXT:    vzeroupper
   1078 ; AVX2-NEXT:    retq
   1079 ;
   1080 ; VLX-LABEL: test_op_v8i32:
   1081 ; VLX:       # %bb.0:
   1082 ; VLX-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
   1083 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
   1084 ; VLX-NEXT:    vzeroupper
   1085 ; VLX-NEXT:    retq
   1086   %r = add <8 x i32> %a, %b
   1087   store <8 x i32> %r, <8 x i32>* %dst, align 32, !nontemporal !1
   1088   ret void
   1089 }
   1090 
   1091 define void @test_op_v4f64(<4 x double> %a, <4 x double> %b, <4 x double>* %dst) {
   1092 ; SSE-LABEL: test_op_v4f64:
   1093 ; SSE:       # %bb.0:
   1094 ; SSE-NEXT:    addpd %xmm2, %xmm0
   1095 ; SSE-NEXT:    addpd %xmm3, %xmm1
   1096 ; SSE-NEXT:    movntpd %xmm1, 16(%rdi)
   1097 ; SSE-NEXT:    movntpd %xmm0, (%rdi)
   1098 ; SSE-NEXT:    retq
   1099 ;
   1100 ; AVX-LABEL: test_op_v4f64:
   1101 ; AVX:       # %bb.0:
   1102 ; AVX-NEXT:    vaddpd %ymm1, %ymm0, %ymm0
   1103 ; AVX-NEXT:    vmovntpd %ymm0, (%rdi)
   1104 ; AVX-NEXT:    vzeroupper
   1105 ; AVX-NEXT:    retq
   1106 ;
   1107 ; VLX-LABEL: test_op_v4f64:
   1108 ; VLX:       # %bb.0:
   1109 ; VLX-NEXT:    vaddpd %ymm1, %ymm0, %ymm0
   1110 ; VLX-NEXT:    vmovntpd %ymm0, (%rdi)
   1111 ; VLX-NEXT:    vzeroupper
   1112 ; VLX-NEXT:    retq
   1113   %r = fadd <4 x double> %a, %b
   1114   store <4 x double> %r, <4 x double>* %dst, align 32, !nontemporal !1
   1115   ret void
   1116 }
   1117 
   1118 define void @test_op_v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64>* %dst) {
   1119 ; SSE-LABEL: test_op_v4i64:
   1120 ; SSE:       # %bb.0:
   1121 ; SSE-NEXT:    paddq %xmm2, %xmm0
   1122 ; SSE-NEXT:    paddq %xmm3, %xmm1
   1123 ; SSE-NEXT:    movntdq %xmm1, 16(%rdi)
   1124 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
   1125 ; SSE-NEXT:    retq
   1126 ;
   1127 ; AVX1-LABEL: test_op_v4i64:
   1128 ; AVX1:       # %bb.0:
   1129 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
   1130 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
   1131 ; AVX1-NEXT:    vpaddq %xmm2, %xmm3, %xmm2
   1132 ; AVX1-NEXT:    vpaddq %xmm1, %xmm0, %xmm0
   1133 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
   1134 ; AVX1-NEXT:    vmovntps %ymm0, (%rdi)
   1135 ; AVX1-NEXT:    vzeroupper
   1136 ; AVX1-NEXT:    retq
   1137 ;
   1138 ; AVX2-LABEL: test_op_v4i64:
   1139 ; AVX2:       # %bb.0:
   1140 ; AVX2-NEXT:    vpaddq %ymm1, %ymm0, %ymm0
   1141 ; AVX2-NEXT:    vmovntdq %ymm0, (%rdi)
   1142 ; AVX2-NEXT:    vzeroupper
   1143 ; AVX2-NEXT:    retq
   1144 ;
   1145 ; VLX-LABEL: test_op_v4i64:
   1146 ; VLX:       # %bb.0:
   1147 ; VLX-NEXT:    vpaddq %ymm1, %ymm0, %ymm0
   1148 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
   1149 ; VLX-NEXT:    vzeroupper
   1150 ; VLX-NEXT:    retq
   1151   %r = add <4 x i64> %a, %b
   1152   store <4 x i64> %r, <4 x i64>* %dst, align 32, !nontemporal !1
   1153   ret void
   1154 }
   1155 
   1156 define void @test_op_v16i16(<16 x i16> %a, <16 x i16> %b, <16 x i16>* %dst) {
   1157 ; SSE-LABEL: test_op_v16i16:
   1158 ; SSE:       # %bb.0:
   1159 ; SSE-NEXT:    paddw %xmm2, %xmm0
   1160 ; SSE-NEXT:    paddw %xmm3, %xmm1
   1161 ; SSE-NEXT:    movntdq %xmm1, 16(%rdi)
   1162 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
   1163 ; SSE-NEXT:    retq
   1164 ;
   1165 ; AVX1-LABEL: test_op_v16i16:
   1166 ; AVX1:       # %bb.0:
   1167 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
   1168 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
   1169 ; AVX1-NEXT:    vpaddw %xmm2, %xmm3, %xmm2
   1170 ; AVX1-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
   1171 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
   1172 ; AVX1-NEXT:    vmovntps %ymm0, (%rdi)
   1173 ; AVX1-NEXT:    vzeroupper
   1174 ; AVX1-NEXT:    retq
   1175 ;
   1176 ; AVX2-LABEL: test_op_v16i16:
   1177 ; AVX2:       # %bb.0:
   1178 ; AVX2-NEXT:    vpaddw %ymm1, %ymm0, %ymm0
   1179 ; AVX2-NEXT:    vmovntdq %ymm0, (%rdi)
   1180 ; AVX2-NEXT:    vzeroupper
   1181 ; AVX2-NEXT:    retq
   1182 ;
   1183 ; VLX-LABEL: test_op_v16i16:
   1184 ; VLX:       # %bb.0:
   1185 ; VLX-NEXT:    vpaddw %ymm1, %ymm0, %ymm0
   1186 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
   1187 ; VLX-NEXT:    vzeroupper
   1188 ; VLX-NEXT:    retq
   1189   %r = add <16 x i16> %a, %b
   1190   store <16 x i16> %r, <16 x i16>* %dst, align 32, !nontemporal !1
   1191   ret void
   1192 }
   1193 
   1194 define void @test_op_v32i8(<32 x i8> %a, <32 x i8> %b, <32 x i8>* %dst) {
   1195 ; SSE-LABEL: test_op_v32i8:
   1196 ; SSE:       # %bb.0:
   1197 ; SSE-NEXT:    paddb %xmm2, %xmm0
   1198 ; SSE-NEXT:    paddb %xmm3, %xmm1
   1199 ; SSE-NEXT:    movntdq %xmm1, 16(%rdi)
   1200 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
   1201 ; SSE-NEXT:    retq
   1202 ;
   1203 ; AVX1-LABEL: test_op_v32i8:
   1204 ; AVX1:       # %bb.0:
   1205 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
   1206 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
   1207 ; AVX1-NEXT:    vpaddb %xmm2, %xmm3, %xmm2
   1208 ; AVX1-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
   1209 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
   1210 ; AVX1-NEXT:    vmovntps %ymm0, (%rdi)
   1211 ; AVX1-NEXT:    vzeroupper
   1212 ; AVX1-NEXT:    retq
   1213 ;
   1214 ; AVX2-LABEL: test_op_v32i8:
   1215 ; AVX2:       # %bb.0:
   1216 ; AVX2-NEXT:    vpaddb %ymm1, %ymm0, %ymm0
   1217 ; AVX2-NEXT:    vmovntdq %ymm0, (%rdi)
   1218 ; AVX2-NEXT:    vzeroupper
   1219 ; AVX2-NEXT:    retq
   1220 ;
   1221 ; VLX-LABEL: test_op_v32i8:
   1222 ; VLX:       # %bb.0:
   1223 ; VLX-NEXT:    vpaddb %ymm1, %ymm0, %ymm0
   1224 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
   1225 ; VLX-NEXT:    vzeroupper
   1226 ; VLX-NEXT:    retq
   1227   %r = add <32 x i8> %a, %b
   1228   store <32 x i8> %r, <32 x i8>* %dst, align 32, !nontemporal !1
   1229   ret void
   1230 }
   1231 
   1232 ; 256-bit NT stores require 256-bit alignment.
   1233 ; FIXME: For AVX, we could lower this to 2x movntps %xmm. Taken further, we
   1234 ; could even scalarize to movnti when we have 1-alignment: nontemporal is
   1235 ; probably always worth even some 20 instruction scalarization.
   1236 define void @test_unaligned_v8f32(<8 x float> %a, <8 x float> %b, <8 x float>* %dst) {
   1237 ; SSE-LABEL: test_unaligned_v8f32:
   1238 ; SSE:       # %bb.0:
   1239 ; SSE-NEXT:    addps %xmm2, %xmm0
   1240 ; SSE-NEXT:    addps %xmm3, %xmm1
   1241 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
   1242 ; SSE-NEXT:    movntps %xmm0, (%rdi)
   1243 ; SSE-NEXT:    retq
   1244 ;
   1245 ; AVX-LABEL: test_unaligned_v8f32:
   1246 ; AVX:       # %bb.0:
   1247 ; AVX-NEXT:    vaddps %ymm1, %ymm0, %ymm0
   1248 ; AVX-NEXT:    vmovups %ymm0, (%rdi)
   1249 ; AVX-NEXT:    vzeroupper
   1250 ; AVX-NEXT:    retq
   1251 ;
   1252 ; VLX-LABEL: test_unaligned_v8f32:
   1253 ; VLX:       # %bb.0:
   1254 ; VLX-NEXT:    vaddps %ymm1, %ymm0, %ymm0
   1255 ; VLX-NEXT:    vmovups %ymm0, (%rdi)
   1256 ; VLX-NEXT:    vzeroupper
   1257 ; VLX-NEXT:    retq
   1258   %r = fadd <8 x float> %a, %b
   1259   store <8 x float> %r, <8 x float>* %dst, align 16, !nontemporal !1
   1260   ret void
   1261 }
   1262 
   1263 !1 = !{i32 1}
   1264