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=+sse4.1 | FileCheck %s --check-prefix=SSE
      3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX
      4 
      5 ; fold (sub x, 0) -> x
      6 define <4 x i32> @combine_vec_sub_zero(<4 x i32> %a) {
      7 ; SSE-LABEL: combine_vec_sub_zero:
      8 ; SSE:       # %bb.0:
      9 ; SSE-NEXT:    retq
     10 ;
     11 ; AVX-LABEL: combine_vec_sub_zero:
     12 ; AVX:       # %bb.0:
     13 ; AVX-NEXT:    retq
     14   %1 = sub <4 x i32> %a, zeroinitializer
     15   ret <4 x i32> %1
     16 }
     17 
     18 ; fold (sub x, x) -> 0
     19 define <4 x i32> @combine_vec_sub_self(<4 x i32> %a) {
     20 ; SSE-LABEL: combine_vec_sub_self:
     21 ; SSE:       # %bb.0:
     22 ; SSE-NEXT:    xorps %xmm0, %xmm0
     23 ; SSE-NEXT:    retq
     24 ;
     25 ; AVX-LABEL: combine_vec_sub_self:
     26 ; AVX:       # %bb.0:
     27 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
     28 ; AVX-NEXT:    retq
     29   %1 = sub <4 x i32> %a, %a
     30   ret <4 x i32> %1
     31 }
     32 
     33 ; fold (sub x, c) -> (add x, -c)
     34 define <4 x i32> @combine_vec_sub_constant(<4 x i32> %x) {
     35 ; SSE-LABEL: combine_vec_sub_constant:
     36 ; SSE:       # %bb.0:
     37 ; SSE-NEXT:    psubd {{.*}}(%rip), %xmm0
     38 ; SSE-NEXT:    retq
     39 ;
     40 ; AVX-LABEL: combine_vec_sub_constant:
     41 ; AVX:       # %bb.0:
     42 ; AVX-NEXT:    vpsubd {{.*}}(%rip), %xmm0, %xmm0
     43 ; AVX-NEXT:    retq
     44   %1 = sub <4 x i32> %x, <i32 0, i32 1, i32 2, i32 3>
     45   ret <4 x i32> %1
     46 }
     47 
     48 ; Canonicalize (sub -1, x) -> ~x, i.e. (xor x, -1)
     49 define <4 x i32> @combine_vec_sub_negone(<4 x i32> %x) {
     50 ; SSE-LABEL: combine_vec_sub_negone:
     51 ; SSE:       # %bb.0:
     52 ; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
     53 ; SSE-NEXT:    pxor %xmm1, %xmm0
     54 ; SSE-NEXT:    retq
     55 ;
     56 ; AVX-LABEL: combine_vec_sub_negone:
     57 ; AVX:       # %bb.0:
     58 ; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
     59 ; AVX-NEXT:    vpxor %xmm1, %xmm0, %xmm0
     60 ; AVX-NEXT:    retq
     61   %1 = sub <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %x
     62   ret <4 x i32> %1
     63 }
     64 
     65 ; fold A-(A-B) -> B
     66 define <4 x i32> @combine_vec_sub_sub(<4 x i32> %a, <4 x i32> %b) {
     67 ; SSE-LABEL: combine_vec_sub_sub:
     68 ; SSE:       # %bb.0:
     69 ; SSE-NEXT:    movaps %xmm1, %xmm0
     70 ; SSE-NEXT:    retq
     71 ;
     72 ; AVX-LABEL: combine_vec_sub_sub:
     73 ; AVX:       # %bb.0:
     74 ; AVX-NEXT:    vmovaps %xmm1, %xmm0
     75 ; AVX-NEXT:    retq
     76   %1 = sub <4 x i32> %a, %b
     77   %2 = sub <4 x i32> %a, %1
     78   ret <4 x i32> %2
     79 }
     80 
     81 ; fold (A+B)-A -> B
     82 define <4 x i32> @combine_vec_sub_add0(<4 x i32> %a, <4 x i32> %b) {
     83 ; SSE-LABEL: combine_vec_sub_add0:
     84 ; SSE:       # %bb.0:
     85 ; SSE-NEXT:    movaps %xmm1, %xmm0
     86 ; SSE-NEXT:    retq
     87 ;
     88 ; AVX-LABEL: combine_vec_sub_add0:
     89 ; AVX:       # %bb.0:
     90 ; AVX-NEXT:    vmovaps %xmm1, %xmm0
     91 ; AVX-NEXT:    retq
     92   %1 = add <4 x i32> %a, %b
     93   %2 = sub <4 x i32> %1, %a
     94   ret <4 x i32> %2
     95 }
     96 
     97 ; fold (A+B)-B -> A
     98 define <4 x i32> @combine_vec_sub_add1(<4 x i32> %a, <4 x i32> %b) {
     99 ; SSE-LABEL: combine_vec_sub_add1:
    100 ; SSE:       # %bb.0:
    101 ; SSE-NEXT:    retq
    102 ;
    103 ; AVX-LABEL: combine_vec_sub_add1:
    104 ; AVX:       # %bb.0:
    105 ; AVX-NEXT:    retq
    106   %1 = add <4 x i32> %a, %b
    107   %2 = sub <4 x i32> %1, %b
    108   ret <4 x i32> %2
    109 }
    110 
    111 ; fold C2-(A+C1) -> (C2-C1)-A
    112 define <4 x i32> @combine_vec_sub_constant_add(<4 x i32> %a) {
    113 ; SSE-LABEL: combine_vec_sub_constant_add:
    114 ; SSE:       # %bb.0:
    115 ; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [3,1,4294967295,4294967293]
    116 ; SSE-NEXT:    psubd %xmm0, %xmm1
    117 ; SSE-NEXT:    movdqa %xmm1, %xmm0
    118 ; SSE-NEXT:    retq
    119 ;
    120 ; AVX-LABEL: combine_vec_sub_constant_add:
    121 ; AVX:       # %bb.0:
    122 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm1 = [3,1,4294967295,4294967293]
    123 ; AVX-NEXT:    vpsubd %xmm0, %xmm1, %xmm0
    124 ; AVX-NEXT:    retq
    125   %1 = add <4 x i32> %a, <i32 0, i32 1, i32 2, i32 3>
    126   %2 = sub <4 x i32> <i32 3, i32 2, i32 1, i32 0>, %1
    127   ret <4 x i32> %2
    128 }
    129 
    130 ; fold ((A+(B+C))-B) -> A+C
    131 define <4 x i32> @combine_vec_sub_add_add(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
    132 ; SSE-LABEL: combine_vec_sub_add_add:
    133 ; SSE:       # %bb.0:
    134 ; SSE-NEXT:    paddd %xmm2, %xmm0
    135 ; SSE-NEXT:    retq
    136 ;
    137 ; AVX-LABEL: combine_vec_sub_add_add:
    138 ; AVX:       # %bb.0:
    139 ; AVX-NEXT:    vpaddd %xmm2, %xmm0, %xmm0
    140 ; AVX-NEXT:    retq
    141   %1 = add <4 x i32> %b, %c
    142   %2 = add <4 x i32> %a, %1
    143   %3 = sub <4 x i32> %2, %b
    144   ret <4 x i32> %3
    145 }
    146 
    147 ; fold ((A+(B-C))-B) -> A-C
    148 define <4 x i32> @combine_vec_sub_add_sub(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
    149 ; SSE-LABEL: combine_vec_sub_add_sub:
    150 ; SSE:       # %bb.0:
    151 ; SSE-NEXT:    psubd %xmm2, %xmm0
    152 ; SSE-NEXT:    retq
    153 ;
    154 ; AVX-LABEL: combine_vec_sub_add_sub:
    155 ; AVX:       # %bb.0:
    156 ; AVX-NEXT:    vpsubd %xmm2, %xmm0, %xmm0
    157 ; AVX-NEXT:    retq
    158   %1 = sub <4 x i32> %b, %c
    159   %2 = add <4 x i32> %a, %1
    160   %3 = sub <4 x i32> %2, %b
    161   ret <4 x i32> %3
    162 }
    163 
    164 ; fold ((A-(B-C))-C) -> A-B
    165 define <4 x i32> @combine_vec_sub_sub_sub(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
    166 ; SSE-LABEL: combine_vec_sub_sub_sub:
    167 ; SSE:       # %bb.0:
    168 ; SSE-NEXT:    psubd %xmm1, %xmm0
    169 ; SSE-NEXT:    retq
    170 ;
    171 ; AVX-LABEL: combine_vec_sub_sub_sub:
    172 ; AVX:       # %bb.0:
    173 ; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
    174 ; AVX-NEXT:    retq
    175   %1 = sub <4 x i32> %b, %c
    176   %2 = sub <4 x i32> %a, %1
    177   %3 = sub <4 x i32> %2, %c
    178   ret <4 x i32> %3
    179 }
    180 
    181 ; fold undef-A -> undef
    182 define <4 x i32> @combine_vec_sub_undef0(<4 x i32> %a) {
    183 ; SSE-LABEL: combine_vec_sub_undef0:
    184 ; SSE:       # %bb.0:
    185 ; SSE-NEXT:    retq
    186 ;
    187 ; AVX-LABEL: combine_vec_sub_undef0:
    188 ; AVX:       # %bb.0:
    189 ; AVX-NEXT:    retq
    190   %1 = sub <4 x i32> undef, %a
    191   ret <4 x i32> %1
    192 }
    193 
    194 ; fold A-undef -> undef
    195 define <4 x i32> @combine_vec_sub_undef1(<4 x i32> %a) {
    196 ; SSE-LABEL: combine_vec_sub_undef1:
    197 ; SSE:       # %bb.0:
    198 ; SSE-NEXT:    retq
    199 ;
    200 ; AVX-LABEL: combine_vec_sub_undef1:
    201 ; AVX:       # %bb.0:
    202 ; AVX-NEXT:    retq
    203   %1 = sub <4 x i32> %a, undef
    204   ret <4 x i32> %1
    205 }
    206 
    207 ; sub X, (sext Y i1) -> add X, (and Y 1)
    208 define <4 x i32> @combine_vec_add_sext(<4 x i32> %x, <4 x i1> %y) {
    209 ; SSE-LABEL: combine_vec_add_sext:
    210 ; SSE:       # %bb.0:
    211 ; SSE-NEXT:    pslld $31, %xmm1
    212 ; SSE-NEXT:    psrad $31, %xmm1
    213 ; SSE-NEXT:    psubd %xmm1, %xmm0
    214 ; SSE-NEXT:    retq
    215 ;
    216 ; AVX-LABEL: combine_vec_add_sext:
    217 ; AVX:       # %bb.0:
    218 ; AVX-NEXT:    vpslld $31, %xmm1, %xmm1
    219 ; AVX-NEXT:    vpsrad $31, %xmm1, %xmm1
    220 ; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
    221 ; AVX-NEXT:    retq
    222   %1 = sext <4 x i1> %y to <4 x i32>
    223   %2 = sub <4 x i32> %x, %1
    224   ret <4 x i32> %2
    225 }
    226 
    227 ; sub X, (sextinreg Y i1) -> add X, (and Y 1)
    228 define <4 x i32> @combine_vec_sub_sextinreg(<4 x i32> %x, <4 x i32> %y) {
    229 ; SSE-LABEL: combine_vec_sub_sextinreg:
    230 ; SSE:       # %bb.0:
    231 ; SSE-NEXT:    pslld $31, %xmm1
    232 ; SSE-NEXT:    psrad $31, %xmm1
    233 ; SSE-NEXT:    psubd %xmm1, %xmm0
    234 ; SSE-NEXT:    retq
    235 ;
    236 ; AVX-LABEL: combine_vec_sub_sextinreg:
    237 ; AVX:       # %bb.0:
    238 ; AVX-NEXT:    vpslld $31, %xmm1, %xmm1
    239 ; AVX-NEXT:    vpsrad $31, %xmm1, %xmm1
    240 ; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
    241 ; AVX-NEXT:    retq
    242   %1 = shl <4 x i32> %y, <i32 31, i32 31, i32 31, i32 31>
    243   %2 = ashr <4 x i32> %1, <i32 31, i32 31, i32 31, i32 31>
    244   %3 = sub <4 x i32> %x, %2
    245   ret <4 x i32> %3
    246 }
    247