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:    vpxord %xmm0, %xmm0, %xmm0
    120 ; VLX-NEXT:    vmovntdq %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:    vpxord %xmm0, %xmm0, %xmm0
    142 ; VLX-NEXT:    vmovntdq %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:    vpxord %xmm0, %xmm0, %xmm0
    165 ; VLX-NEXT:    vmovntdq %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:    vpxord %xmm0, %xmm0, %xmm0
    187 ; VLX-NEXT:    vmovntdq %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:    vpxord %xmm0, %xmm0, %xmm0
    209 ; VLX-NEXT:    vmovntdq %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:    vpxord %xmm0, %xmm0, %xmm0
    231 ; VLX-NEXT:    vmovntdq %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 %ymm0, %ymm0, %ymm0
    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:    vpxord %ymm0, %ymm0, %ymm0
    257 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
    258 ; VLX-NEXT:    retq
    259   store <8 x float> zeroinitializer, <8 x float>* %dst, align 32, !nontemporal !1
    260   ret void
    261 }
    262 
    263 define void @test_zero_v8i32(<8 x i32>* %dst) {
    264 ; SSE-LABEL: test_zero_v8i32:
    265 ; SSE:       # BB#0:
    266 ; SSE-NEXT:    xorps %xmm0, %xmm0
    267 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    268 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    269 ; SSE-NEXT:    retq
    270 ;
    271 ; AVX-LABEL: test_zero_v8i32:
    272 ; AVX:       # BB#0:
    273 ; AVX-NEXT:    vxorps %ymm0, %ymm0, %ymm0
    274 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    275 ; AVX-NEXT:    vzeroupper
    276 ; AVX-NEXT:    retq
    277 ;
    278 ; VLX-LABEL: test_zero_v8i32:
    279 ; VLX:       # BB#0:
    280 ; VLX-NEXT:    vpxord %ymm0, %ymm0, %ymm0
    281 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
    282 ; VLX-NEXT:    retq
    283   store <8 x i32> zeroinitializer, <8 x i32>* %dst, align 32, !nontemporal !1
    284   ret void
    285 }
    286 
    287 define void @test_zero_v4f64(<4 x double>* %dst) {
    288 ; SSE-LABEL: test_zero_v4f64:
    289 ; SSE:       # BB#0:
    290 ; SSE-NEXT:    xorps %xmm0, %xmm0
    291 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    292 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    293 ; SSE-NEXT:    retq
    294 ;
    295 ; AVX-LABEL: test_zero_v4f64:
    296 ; AVX:       # BB#0:
    297 ; AVX-NEXT:    vxorps %ymm0, %ymm0, %ymm0
    298 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    299 ; AVX-NEXT:    vzeroupper
    300 ; AVX-NEXT:    retq
    301 ;
    302 ; VLX-LABEL: test_zero_v4f64:
    303 ; VLX:       # BB#0:
    304 ; VLX-NEXT:    vpxord %ymm0, %ymm0, %ymm0
    305 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
    306 ; VLX-NEXT:    retq
    307   store <4 x double> zeroinitializer, <4 x double>* %dst, align 32, !nontemporal !1
    308   ret void
    309 }
    310 
    311 define void @test_zero_v4i64(<4 x i64>* %dst) {
    312 ; SSE-LABEL: test_zero_v4i64:
    313 ; SSE:       # BB#0:
    314 ; SSE-NEXT:    xorps %xmm0, %xmm0
    315 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    316 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    317 ; SSE-NEXT:    retq
    318 ;
    319 ; AVX-LABEL: test_zero_v4i64:
    320 ; AVX:       # BB#0:
    321 ; AVX-NEXT:    vxorps %ymm0, %ymm0, %ymm0
    322 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    323 ; AVX-NEXT:    vzeroupper
    324 ; AVX-NEXT:    retq
    325 ;
    326 ; VLX-LABEL: test_zero_v4i64:
    327 ; VLX:       # BB#0:
    328 ; VLX-NEXT:    vpxord %ymm0, %ymm0, %ymm0
    329 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
    330 ; VLX-NEXT:    retq
    331   store <4 x i64> zeroinitializer, <4 x i64>* %dst, align 32, !nontemporal !1
    332   ret void
    333 }
    334 
    335 define void @test_zero_v16i16(<16 x i16>* %dst) {
    336 ; SSE-LABEL: test_zero_v16i16:
    337 ; SSE:       # BB#0:
    338 ; SSE-NEXT:    xorps %xmm0, %xmm0
    339 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    340 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    341 ; SSE-NEXT:    retq
    342 ;
    343 ; AVX-LABEL: test_zero_v16i16:
    344 ; AVX:       # BB#0:
    345 ; AVX-NEXT:    vxorps %ymm0, %ymm0, %ymm0
    346 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    347 ; AVX-NEXT:    vzeroupper
    348 ; AVX-NEXT:    retq
    349 ;
    350 ; VLX-LABEL: test_zero_v16i16:
    351 ; VLX:       # BB#0:
    352 ; VLX-NEXT:    vpxord %ymm0, %ymm0, %ymm0
    353 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
    354 ; VLX-NEXT:    retq
    355   store <16 x i16> zeroinitializer, <16 x i16>* %dst, align 32, !nontemporal !1
    356   ret void
    357 }
    358 
    359 define void @test_zero_v32i8(<32 x i8>* %dst) {
    360 ; SSE-LABEL: test_zero_v32i8:
    361 ; SSE:       # BB#0:
    362 ; SSE-NEXT:    xorps %xmm0, %xmm0
    363 ; SSE-NEXT:    movntps %xmm0, 16(%rdi)
    364 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    365 ; SSE-NEXT:    retq
    366 ;
    367 ; AVX-LABEL: test_zero_v32i8:
    368 ; AVX:       # BB#0:
    369 ; AVX-NEXT:    vxorps %ymm0, %ymm0, %ymm0
    370 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    371 ; AVX-NEXT:    vzeroupper
    372 ; AVX-NEXT:    retq
    373 ;
    374 ; VLX-LABEL: test_zero_v32i8:
    375 ; VLX:       # BB#0:
    376 ; VLX-NEXT:    vpxord %ymm0, %ymm0, %ymm0
    377 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
    378 ; VLX-NEXT:    retq
    379   store <32 x i8> zeroinitializer, <32 x i8>* %dst, align 32, !nontemporal !1
    380   ret void
    381 }
    382 
    383 
    384 ; Check that we also handle arguments.  Here the type survives longer.
    385 
    386 ; Scalar versions.
    387 
    388 define void @test_arg_f32(float %arg, float* %dst) {
    389 ; SSE2-LABEL: test_arg_f32:
    390 ; SSE2:       # BB#0:
    391 ; SSE2-NEXT:    movss %xmm0, (%rdi)
    392 ; SSE2-NEXT:    retq
    393 ;
    394 ; SSE4A-LABEL: test_arg_f32:
    395 ; SSE4A:       # BB#0:
    396 ; SSE4A-NEXT:    movntss %xmm0, (%rdi)
    397 ; SSE4A-NEXT:    retq
    398 ;
    399 ; SSE41-LABEL: test_arg_f32:
    400 ; SSE41:       # BB#0:
    401 ; SSE41-NEXT:    movss %xmm0, (%rdi)
    402 ; SSE41-NEXT:    retq
    403 ;
    404 ; AVX-LABEL: test_arg_f32:
    405 ; AVX:       # BB#0:
    406 ; AVX-NEXT:    vmovss %xmm0, (%rdi)
    407 ; AVX-NEXT:    retq
    408 ;
    409 ; VLX-LABEL: test_arg_f32:
    410 ; VLX:       # BB#0:
    411 ; VLX-NEXT:    vmovss %xmm0, (%rdi)
    412 ; VLX-NEXT:    retq
    413   store float %arg, float* %dst, align 1, !nontemporal !1
    414   ret void
    415 }
    416 
    417 define void @test_arg_i32(i32 %arg, i32* %dst) {
    418 ; SSE-LABEL: test_arg_i32:
    419 ; SSE:       # BB#0:
    420 ; SSE-NEXT:    movntil %edi, (%rsi)
    421 ; SSE-NEXT:    retq
    422 ;
    423 ; AVX-LABEL: test_arg_i32:
    424 ; AVX:       # BB#0:
    425 ; AVX-NEXT:    movntil %edi, (%rsi)
    426 ; AVX-NEXT:    retq
    427 ;
    428 ; VLX-LABEL: test_arg_i32:
    429 ; VLX:       # BB#0:
    430 ; VLX-NEXT:    movntil %edi, (%rsi)
    431 ; VLX-NEXT:    retq
    432   store i32 %arg, i32* %dst, align 1, !nontemporal !1
    433   ret void
    434 }
    435 
    436 define void @test_arg_f64(double %arg, double* %dst) {
    437 ; SSE2-LABEL: test_arg_f64:
    438 ; SSE2:       # BB#0:
    439 ; SSE2-NEXT:    movsd %xmm0, (%rdi)
    440 ; SSE2-NEXT:    retq
    441 ;
    442 ; SSE4A-LABEL: test_arg_f64:
    443 ; SSE4A:       # BB#0:
    444 ; SSE4A-NEXT:    movntsd %xmm0, (%rdi)
    445 ; SSE4A-NEXT:    retq
    446 ;
    447 ; SSE41-LABEL: test_arg_f64:
    448 ; SSE41:       # BB#0:
    449 ; SSE41-NEXT:    movsd %xmm0, (%rdi)
    450 ; SSE41-NEXT:    retq
    451 ;
    452 ; AVX-LABEL: test_arg_f64:
    453 ; AVX:       # BB#0:
    454 ; AVX-NEXT:    vmovsd %xmm0, (%rdi)
    455 ; AVX-NEXT:    retq
    456 ;
    457 ; VLX-LABEL: test_arg_f64:
    458 ; VLX:       # BB#0:
    459 ; VLX-NEXT:    vmovsd %xmm0, (%rdi)
    460 ; VLX-NEXT:    retq
    461   store double %arg, double* %dst, align 1, !nontemporal !1
    462   ret void
    463 }
    464 
    465 define void @test_arg_i64(i64 %arg, i64* %dst) {
    466 ; SSE-LABEL: test_arg_i64:
    467 ; SSE:       # BB#0:
    468 ; SSE-NEXT:    movntiq %rdi, (%rsi)
    469 ; SSE-NEXT:    retq
    470 ;
    471 ; AVX-LABEL: test_arg_i64:
    472 ; AVX:       # BB#0:
    473 ; AVX-NEXT:    movntiq %rdi, (%rsi)
    474 ; AVX-NEXT:    retq
    475 ;
    476 ; VLX-LABEL: test_arg_i64:
    477 ; VLX:       # BB#0:
    478 ; VLX-NEXT:    movntiq %rdi, (%rsi)
    479 ; VLX-NEXT:    retq
    480   store i64 %arg, i64* %dst, align 1, !nontemporal !1
    481   ret void
    482 }
    483 
    484 ; Extract versions
    485 
    486 define void @test_extract_f32(<4 x float> %arg, float* %dst) {
    487 ; SSE2-LABEL: test_extract_f32:
    488 ; SSE2:       # BB#0:
    489 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,2,3]
    490 ; SSE2-NEXT:    movss %xmm0, (%rdi)
    491 ; SSE2-NEXT:    retq
    492 ;
    493 ; SSE4A-LABEL: test_extract_f32:
    494 ; SSE4A:       # BB#0:
    495 ; SSE4A-NEXT:    movshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
    496 ; SSE4A-NEXT:    movntss %xmm0, (%rdi)
    497 ; SSE4A-NEXT:    retq
    498 ;
    499 ; SSE41-LABEL: test_extract_f32:
    500 ; SSE41:       # BB#0:
    501 ; SSE41-NEXT:    extractps $1, %xmm0, %eax
    502 ; SSE41-NEXT:    movntil %eax, (%rdi)
    503 ; SSE41-NEXT:    retq
    504 ;
    505 ; AVX-LABEL: test_extract_f32:
    506 ; AVX:       # BB#0:
    507 ; AVX-NEXT:    vextractps $1, %xmm0, %eax
    508 ; AVX-NEXT:    movntil %eax, (%rdi)
    509 ; AVX-NEXT:    retq
    510 ;
    511 ; VLX-LABEL: test_extract_f32:
    512 ; VLX:       # BB#0:
    513 ; VLX-NEXT:    vextractps $1, %xmm0, %eax
    514 ; VLX-NEXT:    movntil %eax, (%rdi)
    515 ; VLX-NEXT:    retq
    516   %1 = extractelement <4 x float> %arg, i32 1
    517   store float %1, float* %dst, align 1, !nontemporal !1
    518   ret void
    519 }
    520 
    521 define void @test_extract_i32(<4 x i32> %arg, i32* %dst) {
    522 ; SSE2-LABEL: test_extract_i32:
    523 ; SSE2:       # BB#0:
    524 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
    525 ; SSE2-NEXT:    movd %xmm0, %eax
    526 ; SSE2-NEXT:    movntil %eax, (%rdi)
    527 ; SSE2-NEXT:    retq
    528 ;
    529 ; SSE4A-LABEL: test_extract_i32:
    530 ; SSE4A:       # BB#0:
    531 ; SSE4A-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
    532 ; SSE4A-NEXT:    movd %xmm0, %eax
    533 ; SSE4A-NEXT:    movntil %eax, (%rdi)
    534 ; SSE4A-NEXT:    retq
    535 ;
    536 ; SSE41-LABEL: test_extract_i32:
    537 ; SSE41:       # BB#0:
    538 ; SSE41-NEXT:    pextrd $1, %xmm0, %eax
    539 ; SSE41-NEXT:    movntil %eax, (%rdi)
    540 ; SSE41-NEXT:    retq
    541 ;
    542 ; AVX-LABEL: test_extract_i32:
    543 ; AVX:       # BB#0:
    544 ; AVX-NEXT:    vpextrd $1, %xmm0, %eax
    545 ; AVX-NEXT:    movntil %eax, (%rdi)
    546 ; AVX-NEXT:    retq
    547 ;
    548 ; VLX-LABEL: test_extract_i32:
    549 ; VLX:       # BB#0:
    550 ; VLX-NEXT:    vpextrd $1, %xmm0, %eax
    551 ; VLX-NEXT:    movntil %eax, (%rdi)
    552 ; VLX-NEXT:    retq
    553   %1 = extractelement <4 x i32> %arg, i32 1
    554   store i32 %1, i32* %dst, align 1, !nontemporal !1
    555   ret void
    556 }
    557 
    558 define void @test_extract_f64(<2 x double> %arg, double* %dst) {
    559 ; SSE2-LABEL: test_extract_f64:
    560 ; SSE2:       # BB#0:
    561 ; SSE2-NEXT:    movhpd %xmm0, (%rdi)
    562 ; SSE2-NEXT:    retq
    563 ;
    564 ; SSE4A-LABEL: test_extract_f64:
    565 ; SSE4A:       # BB#0:
    566 ; SSE4A-NEXT:    shufpd {{.*#+}} xmm0 = xmm0[1,0]
    567 ; SSE4A-NEXT:    movntsd %xmm0, (%rdi)
    568 ; SSE4A-NEXT:    retq
    569 ;
    570 ; SSE41-LABEL: test_extract_f64:
    571 ; SSE41:       # BB#0:
    572 ; SSE41-NEXT:    movhpd %xmm0, (%rdi)
    573 ; SSE41-NEXT:    retq
    574 ;
    575 ; AVX-LABEL: test_extract_f64:
    576 ; AVX:       # BB#0:
    577 ; AVX-NEXT:    vmovhpd %xmm0, (%rdi)
    578 ; AVX-NEXT:    retq
    579 ;
    580 ; VLX-LABEL: test_extract_f64:
    581 ; VLX:       # BB#0:
    582 ; VLX-NEXT:    vmovhpd %xmm0, (%rdi)
    583 ; VLX-NEXT:    retq
    584   %1 = extractelement <2 x double> %arg, i32 1
    585   store double %1, double* %dst, align 1, !nontemporal !1
    586   ret void
    587 }
    588 
    589 define void @test_extract_i64(<2 x i64> %arg, i64* %dst) {
    590 ; SSE2-LABEL: test_extract_i64:
    591 ; SSE2:       # BB#0:
    592 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
    593 ; SSE2-NEXT:    movd %xmm0, %rax
    594 ; SSE2-NEXT:    movntiq %rax, (%rdi)
    595 ; SSE2-NEXT:    retq
    596 ;
    597 ; SSE4A-LABEL: test_extract_i64:
    598 ; SSE4A:       # BB#0:
    599 ; SSE4A-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
    600 ; SSE4A-NEXT:    movd %xmm0, %rax
    601 ; SSE4A-NEXT:    movntiq %rax, (%rdi)
    602 ; SSE4A-NEXT:    retq
    603 ;
    604 ; SSE41-LABEL: test_extract_i64:
    605 ; SSE41:       # BB#0:
    606 ; SSE41-NEXT:    pextrq $1, %xmm0, %rax
    607 ; SSE41-NEXT:    movntiq %rax, (%rdi)
    608 ; SSE41-NEXT:    retq
    609 ;
    610 ; AVX-LABEL: test_extract_i64:
    611 ; AVX:       # BB#0:
    612 ; AVX-NEXT:    vpextrq $1, %xmm0, %rax
    613 ; AVX-NEXT:    movntiq %rax, (%rdi)
    614 ; AVX-NEXT:    retq
    615 ;
    616 ; VLX-LABEL: test_extract_i64:
    617 ; VLX:       # BB#0:
    618 ; VLX-NEXT:    vpextrq $1, %xmm0, %rax
    619 ; VLX-NEXT:    movntiq %rax, (%rdi)
    620 ; VLX-NEXT:    retq
    621   %1 = extractelement <2 x i64> %arg, i32 1
    622   store i64 %1, i64* %dst, align 1, !nontemporal !1
    623   ret void
    624 }
    625 
    626 ; And now XMM versions.
    627 
    628 define void @test_arg_v4f32(<4 x float> %arg, <4 x float>* %dst) {
    629 ; SSE-LABEL: test_arg_v4f32:
    630 ; SSE:       # BB#0:
    631 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    632 ; SSE-NEXT:    retq
    633 ;
    634 ; AVX-LABEL: test_arg_v4f32:
    635 ; AVX:       # BB#0:
    636 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    637 ; AVX-NEXT:    retq
    638 ;
    639 ; VLX-LABEL: test_arg_v4f32:
    640 ; VLX:       # BB#0:
    641 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    642 ; VLX-NEXT:    retq
    643   store <4 x float> %arg, <4 x float>* %dst, align 16, !nontemporal !1
    644   ret void
    645 }
    646 
    647 define void @test_arg_v4i32(<4 x i32> %arg, <4 x i32>* %dst) {
    648 ; SSE-LABEL: test_arg_v4i32:
    649 ; SSE:       # BB#0:
    650 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    651 ; SSE-NEXT:    retq
    652 ;
    653 ; AVX-LABEL: test_arg_v4i32:
    654 ; AVX:       # BB#0:
    655 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    656 ; AVX-NEXT:    retq
    657 ;
    658 ; VLX-LABEL: test_arg_v4i32:
    659 ; VLX:       # BB#0:
    660 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
    661 ; VLX-NEXT:    retq
    662   store <4 x i32> %arg, <4 x i32>* %dst, align 16, !nontemporal !1
    663   ret void
    664 }
    665 
    666 define void @test_arg_v2f64(<2 x double> %arg, <2 x double>* %dst) {
    667 ; SSE-LABEL: test_arg_v2f64:
    668 ; SSE:       # BB#0:
    669 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    670 ; SSE-NEXT:    retq
    671 ;
    672 ; AVX-LABEL: test_arg_v2f64:
    673 ; AVX:       # BB#0:
    674 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    675 ; AVX-NEXT:    retq
    676 ;
    677 ; VLX-LABEL: test_arg_v2f64:
    678 ; VLX:       # BB#0:
    679 ; VLX-NEXT:    vmovntpd %xmm0, (%rdi)
    680 ; VLX-NEXT:    retq
    681   store <2 x double> %arg, <2 x double>* %dst, align 16, !nontemporal !1
    682   ret void
    683 }
    684 
    685 define void @test_arg_v2i64(<2 x i64> %arg, <2 x i64>* %dst) {
    686 ; SSE-LABEL: test_arg_v2i64:
    687 ; SSE:       # BB#0:
    688 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    689 ; SSE-NEXT:    retq
    690 ;
    691 ; AVX-LABEL: test_arg_v2i64:
    692 ; AVX:       # BB#0:
    693 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    694 ; AVX-NEXT:    retq
    695 ;
    696 ; VLX-LABEL: test_arg_v2i64:
    697 ; VLX:       # BB#0:
    698 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
    699 ; VLX-NEXT:    retq
    700   store <2 x i64> %arg, <2 x i64>* %dst, align 16, !nontemporal !1
    701   ret void
    702 }
    703 
    704 define void @test_arg_v8i16(<8 x i16> %arg, <8 x i16>* %dst) {
    705 ; SSE-LABEL: test_arg_v8i16:
    706 ; SSE:       # BB#0:
    707 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    708 ; SSE-NEXT:    retq
    709 ;
    710 ; AVX-LABEL: test_arg_v8i16:
    711 ; AVX:       # BB#0:
    712 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    713 ; AVX-NEXT:    retq
    714 ;
    715 ; VLX-LABEL: test_arg_v8i16:
    716 ; VLX:       # BB#0:
    717 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
    718 ; VLX-NEXT:    retq
    719   store <8 x i16> %arg, <8 x i16>* %dst, align 16, !nontemporal !1
    720   ret void
    721 }
    722 
    723 define void @test_arg_v16i8(<16 x i8> %arg, <16 x i8>* %dst) {
    724 ; SSE-LABEL: test_arg_v16i8:
    725 ; SSE:       # BB#0:
    726 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    727 ; SSE-NEXT:    retq
    728 ;
    729 ; AVX-LABEL: test_arg_v16i8:
    730 ; AVX:       # BB#0:
    731 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    732 ; AVX-NEXT:    retq
    733 ;
    734 ; VLX-LABEL: test_arg_v16i8:
    735 ; VLX:       # BB#0:
    736 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
    737 ; VLX-NEXT:    retq
    738   store <16 x i8> %arg, <16 x i8>* %dst, align 16, !nontemporal !1
    739   ret void
    740 }
    741 
    742 ; And now YMM versions.
    743 
    744 define void @test_arg_v8f32(<8 x float> %arg, <8 x float>* %dst) {
    745 ; SSE-LABEL: test_arg_v8f32:
    746 ; SSE:       # BB#0:
    747 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    748 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    749 ; SSE-NEXT:    retq
    750 ;
    751 ; AVX-LABEL: test_arg_v8f32:
    752 ; AVX:       # BB#0:
    753 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    754 ; AVX-NEXT:    vzeroupper
    755 ; AVX-NEXT:    retq
    756 ;
    757 ; VLX-LABEL: test_arg_v8f32:
    758 ; VLX:       # BB#0:
    759 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
    760 ; VLX-NEXT:    retq
    761   store <8 x float> %arg, <8 x float>* %dst, align 32, !nontemporal !1
    762   ret void
    763 }
    764 
    765 define void @test_arg_v8i32(<8 x i32> %arg, <8 x i32>* %dst) {
    766 ; SSE-LABEL: test_arg_v8i32:
    767 ; SSE:       # BB#0:
    768 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    769 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    770 ; SSE-NEXT:    retq
    771 ;
    772 ; AVX-LABEL: test_arg_v8i32:
    773 ; AVX:       # BB#0:
    774 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    775 ; AVX-NEXT:    vzeroupper
    776 ; AVX-NEXT:    retq
    777 ;
    778 ; VLX-LABEL: test_arg_v8i32:
    779 ; VLX:       # BB#0:
    780 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
    781 ; VLX-NEXT:    retq
    782   store <8 x i32> %arg, <8 x i32>* %dst, align 32, !nontemporal !1
    783   ret void
    784 }
    785 
    786 define void @test_arg_v4f64(<4 x double> %arg, <4 x double>* %dst) {
    787 ; SSE-LABEL: test_arg_v4f64:
    788 ; SSE:       # BB#0:
    789 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    790 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    791 ; SSE-NEXT:    retq
    792 ;
    793 ; AVX-LABEL: test_arg_v4f64:
    794 ; AVX:       # BB#0:
    795 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    796 ; AVX-NEXT:    vzeroupper
    797 ; AVX-NEXT:    retq
    798 ;
    799 ; VLX-LABEL: test_arg_v4f64:
    800 ; VLX:       # BB#0:
    801 ; VLX-NEXT:    vmovntpd %ymm0, (%rdi)
    802 ; VLX-NEXT:    retq
    803   store <4 x double> %arg, <4 x double>* %dst, align 32, !nontemporal !1
    804   ret void
    805 }
    806 
    807 define void @test_arg_v4i64(<4 x i64> %arg, <4 x i64>* %dst) {
    808 ; SSE-LABEL: test_arg_v4i64:
    809 ; SSE:       # BB#0:
    810 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    811 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    812 ; SSE-NEXT:    retq
    813 ;
    814 ; AVX-LABEL: test_arg_v4i64:
    815 ; AVX:       # BB#0:
    816 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    817 ; AVX-NEXT:    vzeroupper
    818 ; AVX-NEXT:    retq
    819 ;
    820 ; VLX-LABEL: test_arg_v4i64:
    821 ; VLX:       # BB#0:
    822 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
    823 ; VLX-NEXT:    retq
    824   store <4 x i64> %arg, <4 x i64>* %dst, align 32, !nontemporal !1
    825   ret void
    826 }
    827 
    828 define void @test_arg_v16i16(<16 x i16> %arg, <16 x i16>* %dst) {
    829 ; SSE-LABEL: test_arg_v16i16:
    830 ; SSE:       # BB#0:
    831 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    832 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    833 ; SSE-NEXT:    retq
    834 ;
    835 ; AVX-LABEL: test_arg_v16i16:
    836 ; AVX:       # BB#0:
    837 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    838 ; AVX-NEXT:    vzeroupper
    839 ; AVX-NEXT:    retq
    840 ;
    841 ; VLX-LABEL: test_arg_v16i16:
    842 ; VLX:       # BB#0:
    843 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
    844 ; VLX-NEXT:    retq
    845   store <16 x i16> %arg, <16 x i16>* %dst, align 32, !nontemporal !1
    846   ret void
    847 }
    848 
    849 define void @test_arg_v32i8(<32 x i8> %arg, <32 x i8>* %dst) {
    850 ; SSE-LABEL: test_arg_v32i8:
    851 ; SSE:       # BB#0:
    852 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
    853 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    854 ; SSE-NEXT:    retq
    855 ;
    856 ; AVX-LABEL: test_arg_v32i8:
    857 ; AVX:       # BB#0:
    858 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
    859 ; AVX-NEXT:    vzeroupper
    860 ; AVX-NEXT:    retq
    861 ;
    862 ; VLX-LABEL: test_arg_v32i8:
    863 ; VLX:       # BB#0:
    864 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
    865 ; VLX-NEXT:    retq
    866   store <32 x i8> %arg, <32 x i8>* %dst, align 32, !nontemporal !1
    867   ret void
    868 }
    869 
    870 
    871 ; Now check that if the execution domain is trivially visible, we use it.
    872 ; We use an add to make the type survive all the way to the MOVNT.
    873 
    874 define void @test_op_v4f32(<4 x float> %a, <4 x float> %b, <4 x float>* %dst) {
    875 ; SSE-LABEL: test_op_v4f32:
    876 ; SSE:       # BB#0:
    877 ; SSE-NEXT:    addps %xmm1, %xmm0
    878 ; SSE-NEXT:    movntps %xmm0, (%rdi)
    879 ; SSE-NEXT:    retq
    880 ;
    881 ; AVX-LABEL: test_op_v4f32:
    882 ; AVX:       # BB#0:
    883 ; AVX-NEXT:    vaddps %xmm1, %xmm0, %xmm0
    884 ; AVX-NEXT:    vmovntps %xmm0, (%rdi)
    885 ; AVX-NEXT:    retq
    886 ;
    887 ; VLX-LABEL: test_op_v4f32:
    888 ; VLX:       # BB#0:
    889 ; VLX-NEXT:    vaddps %xmm1, %xmm0, %xmm0
    890 ; VLX-NEXT:    vmovntps %xmm0, (%rdi)
    891 ; VLX-NEXT:    retq
    892   %r = fadd <4 x float> %a, %b
    893   store <4 x float> %r, <4 x float>* %dst, align 16, !nontemporal !1
    894   ret void
    895 }
    896 
    897 define void @test_op_v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32>* %dst) {
    898 ; SSE-LABEL: test_op_v4i32:
    899 ; SSE:       # BB#0:
    900 ; SSE-NEXT:    paddd %xmm1, %xmm0
    901 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
    902 ; SSE-NEXT:    retq
    903 ;
    904 ; AVX-LABEL: test_op_v4i32:
    905 ; AVX:       # BB#0:
    906 ; AVX-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
    907 ; AVX-NEXT:    vmovntdq %xmm0, (%rdi)
    908 ; AVX-NEXT:    retq
    909 ;
    910 ; VLX-LABEL: test_op_v4i32:
    911 ; VLX:       # BB#0:
    912 ; VLX-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
    913 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
    914 ; VLX-NEXT:    retq
    915   %r = add <4 x i32> %a, %b
    916   store <4 x i32> %r, <4 x i32>* %dst, align 16, !nontemporal !1
    917   ret void
    918 }
    919 
    920 define void @test_op_v2f64(<2 x double> %a, <2 x double> %b, <2 x double>* %dst) {
    921 ; SSE-LABEL: test_op_v2f64:
    922 ; SSE:       # BB#0:
    923 ; SSE-NEXT:    addpd %xmm1, %xmm0
    924 ; SSE-NEXT:    movntpd %xmm0, (%rdi)
    925 ; SSE-NEXT:    retq
    926 ;
    927 ; AVX-LABEL: test_op_v2f64:
    928 ; AVX:       # BB#0:
    929 ; AVX-NEXT:    vaddpd %xmm1, %xmm0, %xmm0
    930 ; AVX-NEXT:    vmovntpd %xmm0, (%rdi)
    931 ; AVX-NEXT:    retq
    932 ;
    933 ; VLX-LABEL: test_op_v2f64:
    934 ; VLX:       # BB#0:
    935 ; VLX-NEXT:    vaddpd %xmm1, %xmm0, %xmm0
    936 ; VLX-NEXT:    vmovntpd %xmm0, (%rdi)
    937 ; VLX-NEXT:    retq
    938   %r = fadd <2 x double> %a, %b
    939   store <2 x double> %r, <2 x double>* %dst, align 16, !nontemporal !1
    940   ret void
    941 }
    942 
    943 define void @test_op_v2i64(<2 x i64> %a, <2 x i64> %b, <2 x i64>* %dst) {
    944 ; SSE-LABEL: test_op_v2i64:
    945 ; SSE:       # BB#0:
    946 ; SSE-NEXT:    paddq %xmm1, %xmm0
    947 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
    948 ; SSE-NEXT:    retq
    949 ;
    950 ; AVX-LABEL: test_op_v2i64:
    951 ; AVX:       # BB#0:
    952 ; AVX-NEXT:    vpaddq %xmm1, %xmm0, %xmm0
    953 ; AVX-NEXT:    vmovntdq %xmm0, (%rdi)
    954 ; AVX-NEXT:    retq
    955 ;
    956 ; VLX-LABEL: test_op_v2i64:
    957 ; VLX:       # BB#0:
    958 ; VLX-NEXT:    vpaddq %xmm1, %xmm0, %xmm0
    959 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
    960 ; VLX-NEXT:    retq
    961   %r = add <2 x i64> %a, %b
    962   store <2 x i64> %r, <2 x i64>* %dst, align 16, !nontemporal !1
    963   ret void
    964 }
    965 
    966 define void @test_op_v8i16(<8 x i16> %a, <8 x i16> %b, <8 x i16>* %dst) {
    967 ; SSE-LABEL: test_op_v8i16:
    968 ; SSE:       # BB#0:
    969 ; SSE-NEXT:    paddw %xmm1, %xmm0
    970 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
    971 ; SSE-NEXT:    retq
    972 ;
    973 ; AVX-LABEL: test_op_v8i16:
    974 ; AVX:       # BB#0:
    975 ; AVX-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
    976 ; AVX-NEXT:    vmovntdq %xmm0, (%rdi)
    977 ; AVX-NEXT:    retq
    978 ;
    979 ; VLX-LABEL: test_op_v8i16:
    980 ; VLX:       # BB#0:
    981 ; VLX-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
    982 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
    983 ; VLX-NEXT:    retq
    984   %r = add <8 x i16> %a, %b
    985   store <8 x i16> %r, <8 x i16>* %dst, align 16, !nontemporal !1
    986   ret void
    987 }
    988 
    989 define void @test_op_v16i8(<16 x i8> %a, <16 x i8> %b, <16 x i8>* %dst) {
    990 ; SSE-LABEL: test_op_v16i8:
    991 ; SSE:       # BB#0:
    992 ; SSE-NEXT:    paddb %xmm1, %xmm0
    993 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
    994 ; SSE-NEXT:    retq
    995 ;
    996 ; AVX-LABEL: test_op_v16i8:
    997 ; AVX:       # BB#0:
    998 ; AVX-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
    999 ; AVX-NEXT:    vmovntdq %xmm0, (%rdi)
   1000 ; AVX-NEXT:    retq
   1001 ;
   1002 ; VLX-LABEL: test_op_v16i8:
   1003 ; VLX:       # BB#0:
   1004 ; VLX-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
   1005 ; VLX-NEXT:    vmovntdq %xmm0, (%rdi)
   1006 ; VLX-NEXT:    retq
   1007   %r = add <16 x i8> %a, %b
   1008   store <16 x i8> %r, <16 x i8>* %dst, align 16, !nontemporal !1
   1009   ret void
   1010 }
   1011 
   1012 ; And now YMM versions.
   1013 
   1014 define void @test_op_v8f32(<8 x float> %a, <8 x float> %b, <8 x float>* %dst) {
   1015 ; SSE-LABEL: test_op_v8f32:
   1016 ; SSE:       # BB#0:
   1017 ; SSE-NEXT:    addps %xmm2, %xmm0
   1018 ; SSE-NEXT:    addps %xmm3, %xmm1
   1019 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
   1020 ; SSE-NEXT:    movntps %xmm0, (%rdi)
   1021 ; SSE-NEXT:    retq
   1022 ;
   1023 ; AVX-LABEL: test_op_v8f32:
   1024 ; AVX:       # BB#0:
   1025 ; AVX-NEXT:    vaddps %ymm1, %ymm0, %ymm0
   1026 ; AVX-NEXT:    vmovntps %ymm0, (%rdi)
   1027 ; AVX-NEXT:    vzeroupper
   1028 ; AVX-NEXT:    retq
   1029 ;
   1030 ; VLX-LABEL: test_op_v8f32:
   1031 ; VLX:       # BB#0:
   1032 ; VLX-NEXT:    vaddps %ymm1, %ymm0, %ymm0
   1033 ; VLX-NEXT:    vmovntps %ymm0, (%rdi)
   1034 ; VLX-NEXT:    retq
   1035   %r = fadd <8 x float> %a, %b
   1036   store <8 x float> %r, <8 x float>* %dst, align 32, !nontemporal !1
   1037   ret void
   1038 }
   1039 
   1040 define void @test_op_v8i32(<8 x i32> %a, <8 x i32> %b, <8 x i32>* %dst) {
   1041 ; SSE-LABEL: test_op_v8i32:
   1042 ; SSE:       # BB#0:
   1043 ; SSE-NEXT:    paddd %xmm2, %xmm0
   1044 ; SSE-NEXT:    paddd %xmm3, %xmm1
   1045 ; SSE-NEXT:    movntdq %xmm1, 16(%rdi)
   1046 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
   1047 ; SSE-NEXT:    retq
   1048 ;
   1049 ; AVX1-LABEL: test_op_v8i32:
   1050 ; AVX1:       # BB#0:
   1051 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
   1052 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
   1053 ; AVX1-NEXT:    vpaddd %xmm2, %xmm3, %xmm2
   1054 ; AVX1-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
   1055 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
   1056 ; AVX1-NEXT:    vmovntps %ymm0, (%rdi)
   1057 ; AVX1-NEXT:    vzeroupper
   1058 ; AVX1-NEXT:    retq
   1059 ;
   1060 ; AVX2-LABEL: test_op_v8i32:
   1061 ; AVX2:       # BB#0:
   1062 ; AVX2-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
   1063 ; AVX2-NEXT:    vmovntdq %ymm0, (%rdi)
   1064 ; AVX2-NEXT:    vzeroupper
   1065 ; AVX2-NEXT:    retq
   1066 ;
   1067 ; VLX-LABEL: test_op_v8i32:
   1068 ; VLX:       # BB#0:
   1069 ; VLX-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
   1070 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
   1071 ; VLX-NEXT:    retq
   1072   %r = add <8 x i32> %a, %b
   1073   store <8 x i32> %r, <8 x i32>* %dst, align 32, !nontemporal !1
   1074   ret void
   1075 }
   1076 
   1077 define void @test_op_v4f64(<4 x double> %a, <4 x double> %b, <4 x double>* %dst) {
   1078 ; SSE-LABEL: test_op_v4f64:
   1079 ; SSE:       # BB#0:
   1080 ; SSE-NEXT:    addpd %xmm2, %xmm0
   1081 ; SSE-NEXT:    addpd %xmm3, %xmm1
   1082 ; SSE-NEXT:    movntpd %xmm1, 16(%rdi)
   1083 ; SSE-NEXT:    movntpd %xmm0, (%rdi)
   1084 ; SSE-NEXT:    retq
   1085 ;
   1086 ; AVX-LABEL: test_op_v4f64:
   1087 ; AVX:       # BB#0:
   1088 ; AVX-NEXT:    vaddpd %ymm1, %ymm0, %ymm0
   1089 ; AVX-NEXT:    vmovntpd %ymm0, (%rdi)
   1090 ; AVX-NEXT:    vzeroupper
   1091 ; AVX-NEXT:    retq
   1092 ;
   1093 ; VLX-LABEL: test_op_v4f64:
   1094 ; VLX:       # BB#0:
   1095 ; VLX-NEXT:    vaddpd %ymm1, %ymm0, %ymm0
   1096 ; VLX-NEXT:    vmovntpd %ymm0, (%rdi)
   1097 ; VLX-NEXT:    retq
   1098   %r = fadd <4 x double> %a, %b
   1099   store <4 x double> %r, <4 x double>* %dst, align 32, !nontemporal !1
   1100   ret void
   1101 }
   1102 
   1103 define void @test_op_v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64>* %dst) {
   1104 ; SSE-LABEL: test_op_v4i64:
   1105 ; SSE:       # BB#0:
   1106 ; SSE-NEXT:    paddq %xmm2, %xmm0
   1107 ; SSE-NEXT:    paddq %xmm3, %xmm1
   1108 ; SSE-NEXT:    movntdq %xmm1, 16(%rdi)
   1109 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
   1110 ; SSE-NEXT:    retq
   1111 ;
   1112 ; AVX1-LABEL: test_op_v4i64:
   1113 ; AVX1:       # BB#0:
   1114 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
   1115 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
   1116 ; AVX1-NEXT:    vpaddq %xmm2, %xmm3, %xmm2
   1117 ; AVX1-NEXT:    vpaddq %xmm1, %xmm0, %xmm0
   1118 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
   1119 ; AVX1-NEXT:    vmovntps %ymm0, (%rdi)
   1120 ; AVX1-NEXT:    vzeroupper
   1121 ; AVX1-NEXT:    retq
   1122 ;
   1123 ; AVX2-LABEL: test_op_v4i64:
   1124 ; AVX2:       # BB#0:
   1125 ; AVX2-NEXT:    vpaddq %ymm1, %ymm0, %ymm0
   1126 ; AVX2-NEXT:    vmovntdq %ymm0, (%rdi)
   1127 ; AVX2-NEXT:    vzeroupper
   1128 ; AVX2-NEXT:    retq
   1129 ;
   1130 ; VLX-LABEL: test_op_v4i64:
   1131 ; VLX:       # BB#0:
   1132 ; VLX-NEXT:    vpaddq %ymm1, %ymm0, %ymm0
   1133 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
   1134 ; VLX-NEXT:    retq
   1135   %r = add <4 x i64> %a, %b
   1136   store <4 x i64> %r, <4 x i64>* %dst, align 32, !nontemporal !1
   1137   ret void
   1138 }
   1139 
   1140 define void @test_op_v16i16(<16 x i16> %a, <16 x i16> %b, <16 x i16>* %dst) {
   1141 ; SSE-LABEL: test_op_v16i16:
   1142 ; SSE:       # BB#0:
   1143 ; SSE-NEXT:    paddw %xmm2, %xmm0
   1144 ; SSE-NEXT:    paddw %xmm3, %xmm1
   1145 ; SSE-NEXT:    movntdq %xmm1, 16(%rdi)
   1146 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
   1147 ; SSE-NEXT:    retq
   1148 ;
   1149 ; AVX1-LABEL: test_op_v16i16:
   1150 ; AVX1:       # BB#0:
   1151 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
   1152 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
   1153 ; AVX1-NEXT:    vpaddw %xmm2, %xmm3, %xmm2
   1154 ; AVX1-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
   1155 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
   1156 ; AVX1-NEXT:    vmovntps %ymm0, (%rdi)
   1157 ; AVX1-NEXT:    vzeroupper
   1158 ; AVX1-NEXT:    retq
   1159 ;
   1160 ; AVX2-LABEL: test_op_v16i16:
   1161 ; AVX2:       # BB#0:
   1162 ; AVX2-NEXT:    vpaddw %ymm1, %ymm0, %ymm0
   1163 ; AVX2-NEXT:    vmovntdq %ymm0, (%rdi)
   1164 ; AVX2-NEXT:    vzeroupper
   1165 ; AVX2-NEXT:    retq
   1166 ;
   1167 ; VLX-LABEL: test_op_v16i16:
   1168 ; VLX:       # BB#0:
   1169 ; VLX-NEXT:    vpaddw %ymm1, %ymm0, %ymm0
   1170 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
   1171 ; VLX-NEXT:    retq
   1172   %r = add <16 x i16> %a, %b
   1173   store <16 x i16> %r, <16 x i16>* %dst, align 32, !nontemporal !1
   1174   ret void
   1175 }
   1176 
   1177 define void @test_op_v32i8(<32 x i8> %a, <32 x i8> %b, <32 x i8>* %dst) {
   1178 ; SSE-LABEL: test_op_v32i8:
   1179 ; SSE:       # BB#0:
   1180 ; SSE-NEXT:    paddb %xmm2, %xmm0
   1181 ; SSE-NEXT:    paddb %xmm3, %xmm1
   1182 ; SSE-NEXT:    movntdq %xmm1, 16(%rdi)
   1183 ; SSE-NEXT:    movntdq %xmm0, (%rdi)
   1184 ; SSE-NEXT:    retq
   1185 ;
   1186 ; AVX1-LABEL: test_op_v32i8:
   1187 ; AVX1:       # BB#0:
   1188 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
   1189 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
   1190 ; AVX1-NEXT:    vpaddb %xmm2, %xmm3, %xmm2
   1191 ; AVX1-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
   1192 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
   1193 ; AVX1-NEXT:    vmovntps %ymm0, (%rdi)
   1194 ; AVX1-NEXT:    vzeroupper
   1195 ; AVX1-NEXT:    retq
   1196 ;
   1197 ; AVX2-LABEL: test_op_v32i8:
   1198 ; AVX2:       # BB#0:
   1199 ; AVX2-NEXT:    vpaddb %ymm1, %ymm0, %ymm0
   1200 ; AVX2-NEXT:    vmovntdq %ymm0, (%rdi)
   1201 ; AVX2-NEXT:    vzeroupper
   1202 ; AVX2-NEXT:    retq
   1203 ;
   1204 ; VLX-LABEL: test_op_v32i8:
   1205 ; VLX:       # BB#0:
   1206 ; VLX-NEXT:    vpaddb %ymm1, %ymm0, %ymm0
   1207 ; VLX-NEXT:    vmovntdq %ymm0, (%rdi)
   1208 ; VLX-NEXT:    retq
   1209   %r = add <32 x i8> %a, %b
   1210   store <32 x i8> %r, <32 x i8>* %dst, align 32, !nontemporal !1
   1211   ret void
   1212 }
   1213 
   1214 ; 256-bit NT stores require 256-bit alignment.
   1215 ; FIXME: For AVX, we could lower this to 2x movntps %xmm. Taken further, we
   1216 ; could even scalarize to movnti when we have 1-alignment: nontemporal is
   1217 ; probably always worth even some 20 instruction scalarization.
   1218 define void @test_unaligned_v8f32(<8 x float> %a, <8 x float> %b, <8 x float>* %dst) {
   1219 ; SSE-LABEL: test_unaligned_v8f32:
   1220 ; SSE:       # BB#0:
   1221 ; SSE-NEXT:    addps %xmm2, %xmm0
   1222 ; SSE-NEXT:    addps %xmm3, %xmm1
   1223 ; SSE-NEXT:    movntps %xmm1, 16(%rdi)
   1224 ; SSE-NEXT:    movntps %xmm0, (%rdi)
   1225 ; SSE-NEXT:    retq
   1226 ;
   1227 ; AVX-LABEL: test_unaligned_v8f32:
   1228 ; AVX:       # BB#0:
   1229 ; AVX-NEXT:    vaddps %ymm1, %ymm0, %ymm0
   1230 ; AVX-NEXT:    vmovups %ymm0, (%rdi)
   1231 ; AVX-NEXT:    vzeroupper
   1232 ; AVX-NEXT:    retq
   1233 ;
   1234 ; VLX-LABEL: test_unaligned_v8f32:
   1235 ; VLX:       # BB#0:
   1236 ; VLX-NEXT:    vaddps %ymm1, %ymm0, %ymm0
   1237 ; VLX-NEXT:    vmovups %ymm0, (%rdi)
   1238 ; VLX-NEXT:    retq
   1239   %r = fadd <8 x float> %a, %b
   1240   store <8 x float> %r, <8 x float>* %dst, align 16, !nontemporal !1
   1241   ret void
   1242 }
   1243 
   1244 !1 = !{i32 1}
   1245