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 -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE2
      3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE --check-prefix=SSE41
      4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
      5 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
      6 
      7 ; If we have a cmp and a sel with different-sized operands followed by a size-changing cast,
      8 ; we may want to pull the cast ahead of the select operands to create a select with matching op sizes:
      9 ; ext (sel (cmp a, b), c, d) --> sel (cmp a, b), (ext c), (ext d)
     10 
     11 define <8 x i32> @sext(<8 x float> %a, <8 x float> %b, <8 x i16> %c, <8 x i16> %d) {
     12 ; SSE2-LABEL: sext:
     13 ; SSE2:       # %bb.0:
     14 ; SSE2-NEXT:    cmpltps %xmm3, %xmm1
     15 ; SSE2-NEXT:    cmpltps %xmm2, %xmm0
     16 ; SSE2-NEXT:    packssdw %xmm1, %xmm0
     17 ; SSE2-NEXT:    pand %xmm0, %xmm4
     18 ; SSE2-NEXT:    pandn %xmm5, %xmm0
     19 ; SSE2-NEXT:    por %xmm4, %xmm0
     20 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
     21 ; SSE2-NEXT:    psrad $16, %xmm2
     22 ; SSE2-NEXT:    punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
     23 ; SSE2-NEXT:    psrad $16, %xmm1
     24 ; SSE2-NEXT:    movdqa %xmm2, %xmm0
     25 ; SSE2-NEXT:    retq
     26 ;
     27 ; SSE41-LABEL: sext:
     28 ; SSE41:       # %bb.0:
     29 ; SSE41-NEXT:    cmpltps %xmm3, %xmm1
     30 ; SSE41-NEXT:    cmpltps %xmm2, %xmm0
     31 ; SSE41-NEXT:    packssdw %xmm1, %xmm0
     32 ; SSE41-NEXT:    pblendvb %xmm0, %xmm4, %xmm5
     33 ; SSE41-NEXT:    pmovsxwd %xmm5, %xmm0
     34 ; SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm5[2,3,0,1]
     35 ; SSE41-NEXT:    pmovsxwd %xmm1, %xmm1
     36 ; SSE41-NEXT:    retq
     37 ;
     38 ; AVX1-LABEL: sext:
     39 ; AVX1:       # %bb.0:
     40 ; AVX1-NEXT:    vcmpltps %ymm1, %ymm0, %ymm0
     41 ; AVX1-NEXT:    vpmovsxwd %xmm2, %xmm1
     42 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm2 = xmm2[2,3,0,1]
     43 ; AVX1-NEXT:    vpmovsxwd %xmm2, %xmm2
     44 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
     45 ; AVX1-NEXT:    vpmovsxwd %xmm3, %xmm2
     46 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm3 = xmm3[2,3,0,1]
     47 ; AVX1-NEXT:    vpmovsxwd %xmm3, %xmm3
     48 ; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm2, %ymm2
     49 ; AVX1-NEXT:    vblendvps %ymm0, %ymm1, %ymm2, %ymm0
     50 ; AVX1-NEXT:    retq
     51 ;
     52 ; AVX2-LABEL: sext:
     53 ; AVX2:       # %bb.0:
     54 ; AVX2-NEXT:    vcmpltps %ymm1, %ymm0, %ymm0
     55 ; AVX2-NEXT:    vpmovsxwd %xmm2, %ymm1
     56 ; AVX2-NEXT:    vpmovsxwd %xmm3, %ymm2
     57 ; AVX2-NEXT:    vblendvps %ymm0, %ymm1, %ymm2, %ymm0
     58 ; AVX2-NEXT:    retq
     59   %cmp = fcmp olt <8 x float> %a, %b
     60   %sel = select <8 x i1> %cmp, <8 x i16> %c, <8 x i16> %d
     61   %ext = sext <8 x i16> %sel to <8 x i32>
     62   ret <8 x i32> %ext
     63 }
     64 
     65 define <8 x i32> @zext(<8 x float> %a, <8 x float> %b, <8 x i16> %c, <8 x i16> %d) {
     66 ; SSE2-LABEL: zext:
     67 ; SSE2:       # %bb.0:
     68 ; SSE2-NEXT:    movaps %xmm0, %xmm6
     69 ; SSE2-NEXT:    cmpltps %xmm3, %xmm1
     70 ; SSE2-NEXT:    cmpltps %xmm2, %xmm6
     71 ; SSE2-NEXT:    packssdw %xmm1, %xmm6
     72 ; SSE2-NEXT:    pand %xmm6, %xmm4
     73 ; SSE2-NEXT:    pandn %xmm5, %xmm6
     74 ; SSE2-NEXT:    por %xmm4, %xmm6
     75 ; SSE2-NEXT:    pxor %xmm1, %xmm1
     76 ; SSE2-NEXT:    movdqa %xmm6, %xmm0
     77 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
     78 ; SSE2-NEXT:    punpckhwd {{.*#+}} xmm6 = xmm6[4],xmm1[4],xmm6[5],xmm1[5],xmm6[6],xmm1[6],xmm6[7],xmm1[7]
     79 ; SSE2-NEXT:    movdqa %xmm6, %xmm1
     80 ; SSE2-NEXT:    retq
     81 ;
     82 ; SSE41-LABEL: zext:
     83 ; SSE41:       # %bb.0:
     84 ; SSE41-NEXT:    cmpltps %xmm3, %xmm1
     85 ; SSE41-NEXT:    cmpltps %xmm2, %xmm0
     86 ; SSE41-NEXT:    packssdw %xmm1, %xmm0
     87 ; SSE41-NEXT:    pblendvb %xmm0, %xmm4, %xmm5
     88 ; SSE41-NEXT:    pmovzxwd {{.*#+}} xmm0 = xmm5[0],zero,xmm5[1],zero,xmm5[2],zero,xmm5[3],zero
     89 ; SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm5[2,3,0,1]
     90 ; SSE41-NEXT:    pmovzxwd {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero
     91 ; SSE41-NEXT:    retq
     92 ;
     93 ; AVX1-LABEL: zext:
     94 ; AVX1:       # %bb.0:
     95 ; AVX1-NEXT:    vcmpltps %ymm1, %ymm0, %ymm0
     96 ; AVX1-NEXT:    vpmovzxwd {{.*#+}} xmm1 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero
     97 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm2 = xmm2[2,3,0,1]
     98 ; AVX1-NEXT:    vpmovzxwd {{.*#+}} xmm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero
     99 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
    100 ; AVX1-NEXT:    vpmovzxwd {{.*#+}} xmm2 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero
    101 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm3 = xmm3[2,3,0,1]
    102 ; AVX1-NEXT:    vpmovzxwd {{.*#+}} xmm3 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero
    103 ; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm2, %ymm2
    104 ; AVX1-NEXT:    vblendvps %ymm0, %ymm1, %ymm2, %ymm0
    105 ; AVX1-NEXT:    retq
    106 ;
    107 ; AVX2-LABEL: zext:
    108 ; AVX2:       # %bb.0:
    109 ; AVX2-NEXT:    vcmpltps %ymm1, %ymm0, %ymm0
    110 ; AVX2-NEXT:    vpmovzxwd {{.*#+}} ymm1 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero
    111 ; AVX2-NEXT:    vpmovzxwd {{.*#+}} ymm2 = xmm3[0],zero,xmm3[1],zero,xmm3[2],zero,xmm3[3],zero,xmm3[4],zero,xmm3[5],zero,xmm3[6],zero,xmm3[7],zero
    112 ; AVX2-NEXT:    vblendvps %ymm0, %ymm1, %ymm2, %ymm0
    113 ; AVX2-NEXT:    retq
    114   %cmp = fcmp olt <8 x float> %a, %b
    115   %sel = select <8 x i1> %cmp, <8 x i16> %c, <8 x i16> %d
    116   %ext = zext <8 x i16> %sel to <8 x i32>
    117   ret <8 x i32> %ext
    118 }
    119 
    120 define <4 x double> @fpext(<4 x double> %a, <4 x double> %b, <4 x float> %c, <4 x float> %d) {
    121 ; SSE2-LABEL: fpext:
    122 ; SSE2:       # %bb.0:
    123 ; SSE2-NEXT:    cmpltpd %xmm3, %xmm1
    124 ; SSE2-NEXT:    cmpltpd %xmm2, %xmm0
    125 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
    126 ; SSE2-NEXT:    andps %xmm0, %xmm4
    127 ; SSE2-NEXT:    andnps %xmm5, %xmm0
    128 ; SSE2-NEXT:    orps %xmm4, %xmm0
    129 ; SSE2-NEXT:    cvtps2pd %xmm0, %xmm2
    130 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
    131 ; SSE2-NEXT:    cvtps2pd %xmm0, %xmm1
    132 ; SSE2-NEXT:    movaps %xmm2, %xmm0
    133 ; SSE2-NEXT:    retq
    134 ;
    135 ; SSE41-LABEL: fpext:
    136 ; SSE41:       # %bb.0:
    137 ; SSE41-NEXT:    cmpltpd %xmm3, %xmm1
    138 ; SSE41-NEXT:    cmpltpd %xmm2, %xmm0
    139 ; SSE41-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
    140 ; SSE41-NEXT:    blendvps %xmm0, %xmm4, %xmm5
    141 ; SSE41-NEXT:    cvtps2pd %xmm5, %xmm0
    142 ; SSE41-NEXT:    movhlps {{.*#+}} xmm5 = xmm5[1,1]
    143 ; SSE41-NEXT:    cvtps2pd %xmm5, %xmm1
    144 ; SSE41-NEXT:    retq
    145 ;
    146 ; AVX-LABEL: fpext:
    147 ; AVX:       # %bb.0:
    148 ; AVX-NEXT:    vcmpltpd %ymm1, %ymm0, %ymm0
    149 ; AVX-NEXT:    vcvtps2pd %xmm2, %ymm1
    150 ; AVX-NEXT:    vcvtps2pd %xmm3, %ymm2
    151 ; AVX-NEXT:    vblendvpd %ymm0, %ymm1, %ymm2, %ymm0
    152 ; AVX-NEXT:    retq
    153   %cmp = fcmp olt <4 x double> %a, %b
    154   %sel = select <4 x i1> %cmp, <4 x float> %c, <4 x float> %d
    155   %ext = fpext <4 x float> %sel to <4 x double>
    156   ret <4 x double> %ext
    157 }
    158 
    159 define <8 x i16> @trunc(<8 x i16> %a, <8 x i16> %b, <8 x i32> %c, <8 x i32> %d) {
    160 ; SSE2-LABEL: trunc:
    161 ; SSE2:       # %bb.0:
    162 ; SSE2-NEXT:    pcmpeqw %xmm1, %xmm0
    163 ; SSE2-NEXT:    pslld $16, %xmm5
    164 ; SSE2-NEXT:    psrad $16, %xmm5
    165 ; SSE2-NEXT:    pslld $16, %xmm4
    166 ; SSE2-NEXT:    psrad $16, %xmm4
    167 ; SSE2-NEXT:    packssdw %xmm5, %xmm4
    168 ; SSE2-NEXT:    pslld $16, %xmm3
    169 ; SSE2-NEXT:    psrad $16, %xmm3
    170 ; SSE2-NEXT:    pslld $16, %xmm2
    171 ; SSE2-NEXT:    psrad $16, %xmm2
    172 ; SSE2-NEXT:    packssdw %xmm3, %xmm2
    173 ; SSE2-NEXT:    pand %xmm0, %xmm2
    174 ; SSE2-NEXT:    pandn %xmm4, %xmm0
    175 ; SSE2-NEXT:    por %xmm2, %xmm0
    176 ; SSE2-NEXT:    retq
    177 ;
    178 ; SSE41-LABEL: trunc:
    179 ; SSE41:       # %bb.0:
    180 ; SSE41-NEXT:    pcmpeqw %xmm1, %xmm0
    181 ; SSE41-NEXT:    movdqa {{.*#+}} xmm1 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
    182 ; SSE41-NEXT:    pshufb %xmm1, %xmm3
    183 ; SSE41-NEXT:    pshufb %xmm1, %xmm2
    184 ; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
    185 ; SSE41-NEXT:    pshufb %xmm1, %xmm5
    186 ; SSE41-NEXT:    pshufb %xmm1, %xmm4
    187 ; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm4 = xmm4[0],xmm5[0]
    188 ; SSE41-NEXT:    pblendvb %xmm0, %xmm2, %xmm4
    189 ; SSE41-NEXT:    movdqa %xmm4, %xmm0
    190 ; SSE41-NEXT:    retq
    191 ;
    192 ; AVX1-LABEL: trunc:
    193 ; AVX1:       # %bb.0:
    194 ; AVX1-NEXT:    vpcmpeqw %xmm1, %xmm0, %xmm0
    195 ; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm1
    196 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm4 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
    197 ; AVX1-NEXT:    vpshufb %xmm4, %xmm1, %xmm1
    198 ; AVX1-NEXT:    vpshufb %xmm4, %xmm2, %xmm2
    199 ; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
    200 ; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm2
    201 ; AVX1-NEXT:    vpshufb %xmm4, %xmm2, %xmm2
    202 ; AVX1-NEXT:    vpshufb %xmm4, %xmm3, %xmm3
    203 ; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm2 = xmm3[0],xmm2[0]
    204 ; AVX1-NEXT:    vpblendvb %xmm0, %xmm1, %xmm2, %xmm0
    205 ; AVX1-NEXT:    vzeroupper
    206 ; AVX1-NEXT:    retq
    207 ;
    208 ; AVX2-LABEL: trunc:
    209 ; AVX2:       # %bb.0:
    210 ; AVX2-NEXT:    vpcmpeqw %xmm1, %xmm0, %xmm0
    211 ; AVX2-NEXT:    vmovdqa {{.*#+}} ymm1 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
    212 ; AVX2-NEXT:    vpshufb %ymm1, %ymm2, %ymm2
    213 ; AVX2-NEXT:    vpermq {{.*#+}} ymm2 = ymm2[0,2,2,3]
    214 ; AVX2-NEXT:    vpshufb %ymm1, %ymm3, %ymm1
    215 ; AVX2-NEXT:    vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3]
    216 ; AVX2-NEXT:    vpblendvb %xmm0, %xmm2, %xmm1, %xmm0
    217 ; AVX2-NEXT:    vzeroupper
    218 ; AVX2-NEXT:    retq
    219   %cmp = icmp eq <8 x i16> %a, %b
    220   %sel = select <8 x i1> %cmp, <8 x i32> %c, <8 x i32> %d
    221   %tr = trunc <8 x i32> %sel to <8 x i16>
    222   ret <8 x i16> %tr
    223 }
    224 
    225 define <4 x float> @fptrunc(<4 x float> %a, <4 x float> %b, <4 x double> %c, <4 x double> %d) {
    226 ; SSE2-LABEL: fptrunc:
    227 ; SSE2:       # %bb.0:
    228 ; SSE2-NEXT:    cmpltps %xmm1, %xmm0
    229 ; SSE2-NEXT:    cvtpd2ps %xmm5, %xmm1
    230 ; SSE2-NEXT:    cvtpd2ps %xmm4, %xmm4
    231 ; SSE2-NEXT:    unpcklpd {{.*#+}} xmm4 = xmm4[0],xmm1[0]
    232 ; SSE2-NEXT:    cvtpd2ps %xmm3, %xmm1
    233 ; SSE2-NEXT:    cvtpd2ps %xmm2, %xmm2
    234 ; SSE2-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
    235 ; SSE2-NEXT:    andpd %xmm0, %xmm2
    236 ; SSE2-NEXT:    andnpd %xmm4, %xmm0
    237 ; SSE2-NEXT:    orpd %xmm2, %xmm0
    238 ; SSE2-NEXT:    retq
    239 ;
    240 ; SSE41-LABEL: fptrunc:
    241 ; SSE41:       # %bb.0:
    242 ; SSE41-NEXT:    cmpltps %xmm1, %xmm0
    243 ; SSE41-NEXT:    cvtpd2ps %xmm3, %xmm1
    244 ; SSE41-NEXT:    cvtpd2ps %xmm2, %xmm2
    245 ; SSE41-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
    246 ; SSE41-NEXT:    cvtpd2ps %xmm5, %xmm3
    247 ; SSE41-NEXT:    cvtpd2ps %xmm4, %xmm1
    248 ; SSE41-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
    249 ; SSE41-NEXT:    blendvps %xmm0, %xmm2, %xmm1
    250 ; SSE41-NEXT:    movaps %xmm1, %xmm0
    251 ; SSE41-NEXT:    retq
    252 ;
    253 ; AVX-LABEL: fptrunc:
    254 ; AVX:       # %bb.0:
    255 ; AVX-NEXT:    vcmpltps %xmm1, %xmm0, %xmm0
    256 ; AVX-NEXT:    vcvtpd2ps %ymm2, %xmm1
    257 ; AVX-NEXT:    vcvtpd2ps %ymm3, %xmm2
    258 ; AVX-NEXT:    vblendvps %xmm0, %xmm1, %xmm2, %xmm0
    259 ; AVX-NEXT:    vzeroupper
    260 ; AVX-NEXT:    retq
    261   %cmp = fcmp olt <4 x float> %a, %b
    262   %sel = select <4 x i1> %cmp, <4 x double> %c, <4 x double> %d
    263   %tr = fptrunc <4 x double> %sel to <4 x float>
    264   ret <4 x float> %tr
    265 }
    266 
    267 ; PR14657 - avoid truncation/extension of comparison results
    268 ; These tests demonstrate the same issue as the simpler cases above,
    269 ; but also include multi-BB to show potentially larger transforms/codegen issues.
    270 
    271 @da = common global [1024 x float] zeroinitializer, align 32
    272 @db = common global [1024 x float] zeroinitializer, align 32
    273 @dc = common global [1024 x float] zeroinitializer, align 32
    274 @dd = common global [1024 x float] zeroinitializer, align 32
    275 @dj = common global [1024 x i32] zeroinitializer, align 32
    276 
    277 define void @example25() nounwind {
    278 ; SSE2-LABEL: example25:
    279 ; SSE2:       # %bb.0: # %vector.ph
    280 ; SSE2-NEXT:    movq $-4096, %rax # imm = 0xF000
    281 ; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [1,1,1,1]
    282 ; SSE2-NEXT:    .p2align 4, 0x90
    283 ; SSE2-NEXT:  .LBB5_1: # %vector.body
    284 ; SSE2-NEXT:    # =>This Inner Loop Header: Depth=1
    285 ; SSE2-NEXT:    movaps da+4096(%rax), %xmm1
    286 ; SSE2-NEXT:    movaps da+4112(%rax), %xmm2
    287 ; SSE2-NEXT:    cmpltps db+4112(%rax), %xmm2
    288 ; SSE2-NEXT:    cmpltps db+4096(%rax), %xmm1
    289 ; SSE2-NEXT:    packssdw %xmm2, %xmm1
    290 ; SSE2-NEXT:    movaps dc+4096(%rax), %xmm2
    291 ; SSE2-NEXT:    movaps dc+4112(%rax), %xmm3
    292 ; SSE2-NEXT:    cmpltps dd+4112(%rax), %xmm3
    293 ; SSE2-NEXT:    cmpltps dd+4096(%rax), %xmm2
    294 ; SSE2-NEXT:    packssdw %xmm3, %xmm2
    295 ; SSE2-NEXT:    pand %xmm1, %xmm2
    296 ; SSE2-NEXT:    movdqa %xmm2, %xmm1
    297 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
    298 ; SSE2-NEXT:    pand %xmm0, %xmm1
    299 ; SSE2-NEXT:    punpckhwd {{.*#+}} xmm2 = xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7]
    300 ; SSE2-NEXT:    pand %xmm0, %xmm2
    301 ; SSE2-NEXT:    movdqa %xmm2, dj+4112(%rax)
    302 ; SSE2-NEXT:    movdqa %xmm1, dj+4096(%rax)
    303 ; SSE2-NEXT:    addq $32, %rax
    304 ; SSE2-NEXT:    jne .LBB5_1
    305 ; SSE2-NEXT:  # %bb.2: # %for.end
    306 ; SSE2-NEXT:    retq
    307 ;
    308 ; SSE41-LABEL: example25:
    309 ; SSE41:       # %bb.0: # %vector.ph
    310 ; SSE41-NEXT:    movq $-4096, %rax # imm = 0xF000
    311 ; SSE41-NEXT:    movdqa {{.*#+}} xmm0 = [1,1,1,1]
    312 ; SSE41-NEXT:    .p2align 4, 0x90
    313 ; SSE41-NEXT:  .LBB5_1: # %vector.body
    314 ; SSE41-NEXT:    # =>This Inner Loop Header: Depth=1
    315 ; SSE41-NEXT:    movaps da+4096(%rax), %xmm1
    316 ; SSE41-NEXT:    movaps da+4112(%rax), %xmm2
    317 ; SSE41-NEXT:    cmpltps db+4112(%rax), %xmm2
    318 ; SSE41-NEXT:    cmpltps db+4096(%rax), %xmm1
    319 ; SSE41-NEXT:    packssdw %xmm2, %xmm1
    320 ; SSE41-NEXT:    movaps dc+4096(%rax), %xmm2
    321 ; SSE41-NEXT:    movaps dc+4112(%rax), %xmm3
    322 ; SSE41-NEXT:    cmpltps dd+4112(%rax), %xmm3
    323 ; SSE41-NEXT:    cmpltps dd+4096(%rax), %xmm2
    324 ; SSE41-NEXT:    packssdw %xmm3, %xmm2
    325 ; SSE41-NEXT:    pand %xmm1, %xmm2
    326 ; SSE41-NEXT:    pmovzxwd {{.*#+}} xmm1 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero
    327 ; SSE41-NEXT:    pand %xmm0, %xmm1
    328 ; SSE41-NEXT:    punpckhwd {{.*#+}} xmm2 = xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7]
    329 ; SSE41-NEXT:    pand %xmm0, %xmm2
    330 ; SSE41-NEXT:    movdqa %xmm2, dj+4112(%rax)
    331 ; SSE41-NEXT:    movdqa %xmm1, dj+4096(%rax)
    332 ; SSE41-NEXT:    addq $32, %rax
    333 ; SSE41-NEXT:    jne .LBB5_1
    334 ; SSE41-NEXT:  # %bb.2: # %for.end
    335 ; SSE41-NEXT:    retq
    336 ;
    337 ; AVX1-LABEL: example25:
    338 ; AVX1:       # %bb.0: # %vector.ph
    339 ; AVX1-NEXT:    movq $-4096, %rax # imm = 0xF000
    340 ; AVX1-NEXT:    vmovaps {{.*#+}} ymm0 = [1,1,1,1,1,1,1,1]
    341 ; AVX1-NEXT:    .p2align 4, 0x90
    342 ; AVX1-NEXT:  .LBB5_1: # %vector.body
    343 ; AVX1-NEXT:    # =>This Inner Loop Header: Depth=1
    344 ; AVX1-NEXT:    vmovups da+4096(%rax), %ymm1
    345 ; AVX1-NEXT:    vcmpltps db+4096(%rax), %ymm1, %ymm1
    346 ; AVX1-NEXT:    vmovups dc+4096(%rax), %ymm2
    347 ; AVX1-NEXT:    vcmpltps dd+4096(%rax), %ymm2, %ymm2
    348 ; AVX1-NEXT:    vandps %ymm2, %ymm1, %ymm1
    349 ; AVX1-NEXT:    vandps %ymm0, %ymm1, %ymm1
    350 ; AVX1-NEXT:    vmovups %ymm1, dj+4096(%rax)
    351 ; AVX1-NEXT:    addq $32, %rax
    352 ; AVX1-NEXT:    jne .LBB5_1
    353 ; AVX1-NEXT:  # %bb.2: # %for.end
    354 ; AVX1-NEXT:    vzeroupper
    355 ; AVX1-NEXT:    retq
    356 ;
    357 ; AVX2-LABEL: example25:
    358 ; AVX2:       # %bb.0: # %vector.ph
    359 ; AVX2-NEXT:    movq $-4096, %rax # imm = 0xF000
    360 ; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm0 = [1,1,1,1,1,1,1,1]
    361 ; AVX2-NEXT:    .p2align 4, 0x90
    362 ; AVX2-NEXT:  .LBB5_1: # %vector.body
    363 ; AVX2-NEXT:    # =>This Inner Loop Header: Depth=1
    364 ; AVX2-NEXT:    vmovups da+4096(%rax), %ymm1
    365 ; AVX2-NEXT:    vcmpltps db+4096(%rax), %ymm1, %ymm1
    366 ; AVX2-NEXT:    vmovups dc+4096(%rax), %ymm2
    367 ; AVX2-NEXT:    vcmpltps dd+4096(%rax), %ymm2, %ymm2
    368 ; AVX2-NEXT:    vandps %ymm0, %ymm2, %ymm2
    369 ; AVX2-NEXT:    vandps %ymm2, %ymm1, %ymm1
    370 ; AVX2-NEXT:    vmovups %ymm1, dj+4096(%rax)
    371 ; AVX2-NEXT:    addq $32, %rax
    372 ; AVX2-NEXT:    jne .LBB5_1
    373 ; AVX2-NEXT:  # %bb.2: # %for.end
    374 ; AVX2-NEXT:    vzeroupper
    375 ; AVX2-NEXT:    retq
    376 vector.ph:
    377   br label %vector.body
    378 
    379 vector.body:
    380   %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
    381   %0 = getelementptr inbounds [1024 x float], [1024 x float]* @da, i64 0, i64 %index
    382   %1 = bitcast float* %0 to <8 x float>*
    383   %2 = load <8 x float>, <8 x float>* %1, align 16
    384   %3 = getelementptr inbounds [1024 x float], [1024 x float]* @db, i64 0, i64 %index
    385   %4 = bitcast float* %3 to <8 x float>*
    386   %5 = load <8 x float>, <8 x float>* %4, align 16
    387   %6 = fcmp olt <8 x float> %2, %5
    388   %7 = getelementptr inbounds [1024 x float], [1024 x float]* @dc, i64 0, i64 %index
    389   %8 = bitcast float* %7 to <8 x float>*
    390   %9 = load <8 x float>, <8 x float>* %8, align 16
    391   %10 = getelementptr inbounds [1024 x float], [1024 x float]* @dd, i64 0, i64 %index
    392   %11 = bitcast float* %10 to <8 x float>*
    393   %12 = load <8 x float>, <8 x float>* %11, align 16
    394   %13 = fcmp olt <8 x float> %9, %12
    395   %14 = and <8 x i1> %6, %13
    396   %15 = zext <8 x i1> %14 to <8 x i32>
    397   %16 = getelementptr inbounds [1024 x i32], [1024 x i32]* @dj, i64 0, i64 %index
    398   %17 = bitcast i32* %16 to <8 x i32>*
    399   store <8 x i32> %15, <8 x i32>* %17, align 16
    400   %index.next = add i64 %index, 8
    401   %18 = icmp eq i64 %index.next, 1024
    402   br i1 %18, label %for.end, label %vector.body
    403 
    404 for.end:
    405   ret void
    406 }
    407 
    408 define void @example24(i16 signext %x, i16 signext %y) nounwind {
    409 ; SSE2-LABEL: example24:
    410 ; SSE2:       # %bb.0: # %vector.ph
    411 ; SSE2-NEXT:    movd %edi, %xmm0
    412 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,0,2,3,4,5,6,7]
    413 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,0,0,0]
    414 ; SSE2-NEXT:    movd %esi, %xmm1
    415 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,0,2,3,4,5,6,7]
    416 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,0,0,0]
    417 ; SSE2-NEXT:    movq $-4096, %rax # imm = 0xF000
    418 ; SSE2-NEXT:    .p2align 4, 0x90
    419 ; SSE2-NEXT:  .LBB6_1: # %vector.body
    420 ; SSE2-NEXT:    # =>This Inner Loop Header: Depth=1
    421 ; SSE2-NEXT:    movaps da+4096(%rax), %xmm2
    422 ; SSE2-NEXT:    movaps da+4112(%rax), %xmm3
    423 ; SSE2-NEXT:    cmpltps db+4112(%rax), %xmm3
    424 ; SSE2-NEXT:    cmpltps db+4096(%rax), %xmm2
    425 ; SSE2-NEXT:    packssdw %xmm3, %xmm2
    426 ; SSE2-NEXT:    movdqa %xmm0, %xmm3
    427 ; SSE2-NEXT:    pand %xmm2, %xmm3
    428 ; SSE2-NEXT:    pandn %xmm1, %xmm2
    429 ; SSE2-NEXT:    por %xmm3, %xmm2
    430 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3]
    431 ; SSE2-NEXT:    psrad $16, %xmm3
    432 ; SSE2-NEXT:    punpckhwd {{.*#+}} xmm2 = xmm2[4,4,5,5,6,6,7,7]
    433 ; SSE2-NEXT:    psrad $16, %xmm2
    434 ; SSE2-NEXT:    movdqa %xmm2, dj+4112(%rax)
    435 ; SSE2-NEXT:    movdqa %xmm3, dj+4096(%rax)
    436 ; SSE2-NEXT:    addq $32, %rax
    437 ; SSE2-NEXT:    jne .LBB6_1
    438 ; SSE2-NEXT:  # %bb.2: # %for.end
    439 ; SSE2-NEXT:    retq
    440 ;
    441 ; SSE41-LABEL: example24:
    442 ; SSE41:       # %bb.0: # %vector.ph
    443 ; SSE41-NEXT:    movd %edi, %xmm0
    444 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,0,2,3,4,5,6,7]
    445 ; SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[0,0,0,0]
    446 ; SSE41-NEXT:    movd %esi, %xmm0
    447 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,0,2,3,4,5,6,7]
    448 ; SSE41-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[0,0,0,0]
    449 ; SSE41-NEXT:    movq $-4096, %rax # imm = 0xF000
    450 ; SSE41-NEXT:    .p2align 4, 0x90
    451 ; SSE41-NEXT:  .LBB6_1: # %vector.body
    452 ; SSE41-NEXT:    # =>This Inner Loop Header: Depth=1
    453 ; SSE41-NEXT:    movaps da+4096(%rax), %xmm0
    454 ; SSE41-NEXT:    movaps da+4112(%rax), %xmm3
    455 ; SSE41-NEXT:    cmpltps db+4112(%rax), %xmm3
    456 ; SSE41-NEXT:    cmpltps db+4096(%rax), %xmm0
    457 ; SSE41-NEXT:    packssdw %xmm3, %xmm0
    458 ; SSE41-NEXT:    movdqa %xmm2, %xmm3
    459 ; SSE41-NEXT:    pblendvb %xmm0, %xmm1, %xmm3
    460 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[2,3,0,1]
    461 ; SSE41-NEXT:    pmovsxwd %xmm0, %xmm0
    462 ; SSE41-NEXT:    pmovsxwd %xmm3, %xmm3
    463 ; SSE41-NEXT:    movdqa %xmm3, dj+4096(%rax)
    464 ; SSE41-NEXT:    movdqa %xmm0, dj+4112(%rax)
    465 ; SSE41-NEXT:    addq $32, %rax
    466 ; SSE41-NEXT:    jne .LBB6_1
    467 ; SSE41-NEXT:  # %bb.2: # %for.end
    468 ; SSE41-NEXT:    retq
    469 ;
    470 ; AVX1-LABEL: example24:
    471 ; AVX1:       # %bb.0: # %vector.ph
    472 ; AVX1-NEXT:    vmovd %edi, %xmm0
    473 ; AVX1-NEXT:    vpshuflw {{.*#+}} xmm0 = xmm0[0,0,2,3,4,5,6,7]
    474 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,0,0,0]
    475 ; AVX1-NEXT:    vmovd %esi, %xmm1
    476 ; AVX1-NEXT:    vpshuflw {{.*#+}} xmm1 = xmm1[0,0,2,3,4,5,6,7]
    477 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[0,0,0,0]
    478 ; AVX1-NEXT:    movq $-4096, %rax # imm = 0xF000
    479 ; AVX1-NEXT:    vpmovsxwd %xmm0, %xmm2
    480 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
    481 ; AVX1-NEXT:    vpmovsxwd %xmm0, %xmm0
    482 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm2, %ymm0
    483 ; AVX1-NEXT:    vpmovsxwd %xmm1, %xmm2
    484 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
    485 ; AVX1-NEXT:    vpmovsxwd %xmm1, %xmm1
    486 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm2, %ymm1
    487 ; AVX1-NEXT:    .p2align 4, 0x90
    488 ; AVX1-NEXT:  .LBB6_1: # %vector.body
    489 ; AVX1-NEXT:    # =>This Inner Loop Header: Depth=1
    490 ; AVX1-NEXT:    vmovups da+4096(%rax), %ymm2
    491 ; AVX1-NEXT:    vcmpltps db+4096(%rax), %ymm2, %ymm2
    492 ; AVX1-NEXT:    vblendvps %ymm2, %ymm0, %ymm1, %ymm2
    493 ; AVX1-NEXT:    vmovups %ymm2, dj+4096(%rax)
    494 ; AVX1-NEXT:    addq $32, %rax
    495 ; AVX1-NEXT:    jne .LBB6_1
    496 ; AVX1-NEXT:  # %bb.2: # %for.end
    497 ; AVX1-NEXT:    vzeroupper
    498 ; AVX1-NEXT:    retq
    499 ;
    500 ; AVX2-LABEL: example24:
    501 ; AVX2:       # %bb.0: # %vector.ph
    502 ; AVX2-NEXT:    vmovd %edi, %xmm0
    503 ; AVX2-NEXT:    vpbroadcastw %xmm0, %xmm0
    504 ; AVX2-NEXT:    vmovd %esi, %xmm1
    505 ; AVX2-NEXT:    vpbroadcastw %xmm1, %xmm1
    506 ; AVX2-NEXT:    movq $-4096, %rax # imm = 0xF000
    507 ; AVX2-NEXT:    vpmovsxwd %xmm0, %ymm0
    508 ; AVX2-NEXT:    vpmovsxwd %xmm1, %ymm1
    509 ; AVX2-NEXT:    .p2align 4, 0x90
    510 ; AVX2-NEXT:  .LBB6_1: # %vector.body
    511 ; AVX2-NEXT:    # =>This Inner Loop Header: Depth=1
    512 ; AVX2-NEXT:    vmovups da+4096(%rax), %ymm2
    513 ; AVX2-NEXT:    vcmpltps db+4096(%rax), %ymm2, %ymm2
    514 ; AVX2-NEXT:    vblendvps %ymm2, %ymm0, %ymm1, %ymm2
    515 ; AVX2-NEXT:    vmovups %ymm2, dj+4096(%rax)
    516 ; AVX2-NEXT:    addq $32, %rax
    517 ; AVX2-NEXT:    jne .LBB6_1
    518 ; AVX2-NEXT:  # %bb.2: # %for.end
    519 ; AVX2-NEXT:    vzeroupper
    520 ; AVX2-NEXT:    retq
    521 vector.ph:
    522   %0 = insertelement <8 x i16> undef, i16 %x, i32 0
    523   %broadcast11 = shufflevector <8 x i16> %0, <8 x i16> undef, <8 x i32> zeroinitializer
    524   %1 = insertelement <8 x i16> undef, i16 %y, i32 0
    525   %broadcast12 = shufflevector <8 x i16> %1, <8 x i16> undef, <8 x i32> zeroinitializer
    526   br label %vector.body
    527 
    528 vector.body:
    529   %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
    530   %2 = getelementptr inbounds [1024 x float], [1024 x float]* @da, i64 0, i64 %index
    531   %3 = bitcast float* %2 to <8 x float>*
    532   %4 = load <8 x float>, <8 x float>* %3, align 16
    533   %5 = getelementptr inbounds [1024 x float], [1024 x float]* @db, i64 0, i64 %index
    534   %6 = bitcast float* %5 to <8 x float>*
    535   %7 = load <8 x float>, <8 x float>* %6, align 16
    536   %8 = fcmp olt <8 x float> %4, %7
    537   %9 = select <8 x i1> %8, <8 x i16> %broadcast11, <8 x i16> %broadcast12
    538   %10 = sext <8 x i16> %9 to <8 x i32>
    539   %11 = getelementptr inbounds [1024 x i32], [1024 x i32]* @dj, i64 0, i64 %index
    540   %12 = bitcast i32* %11 to <8 x i32>*
    541   store <8 x i32> %10, <8 x i32>* %12, align 16
    542   %index.next = add i64 %index, 8
    543   %13 = icmp eq i64 %index.next, 1024
    544   br i1 %13, label %for.end, label %vector.body
    545 
    546 for.end:
    547   ret void
    548 }
    549 
    550