Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt < %s -instcombine -S | FileCheck %s
      2 
      3 ; Check that instcombine rewrites multiply by a vector
      4 ; of known constant power-of-2 elements with vector shift.
      5 
      6 define <4 x i8> @Zero_i8(<4 x i8> %InVec)  {
      7 entry:
      8   %mul = mul <4 x i8> %InVec, <i8 0, i8 0, i8 0, i8 0>
      9   ret <4 x i8> %mul
     10 }
     11 
     12 ; CHECK-LABEL: @Zero_i8(
     13 ; CHECK: ret <4 x i8> zeroinitializer
     14 
     15 define <4 x i8> @Identity_i8(<4 x i8> %InVec)  {
     16 entry:
     17   %mul = mul <4 x i8> %InVec, <i8 1, i8 1, i8 1, i8 1>
     18   ret <4 x i8> %mul
     19 }
     20 
     21 ; CHECK-LABEL: @Identity_i8(
     22 ; CHECK: ret <4 x i8> %InVec
     23 
     24 define <4 x i8> @AddToSelf_i8(<4 x i8> %InVec)  {
     25 entry:
     26   %mul = mul <4 x i8> %InVec, <i8 2, i8 2, i8 2, i8 2>
     27   ret <4 x i8> %mul
     28 }
     29 
     30 ; CHECK-LABEL: @AddToSelf_i8(
     31 ; CHECK: shl <4 x i8> %InVec, <i8 1, i8 1, i8 1, i8 1>
     32 ; CHECK: ret
     33 
     34 define <4 x i8> @SplatPow2Test1_i8(<4 x i8> %InVec)  {
     35 entry:
     36   %mul = mul <4 x i8> %InVec, <i8 4, i8 4, i8 4, i8 4>
     37   ret <4 x i8> %mul
     38 }
     39 
     40 ; CHECK-LABEL: @SplatPow2Test1_i8(
     41 ; CHECK: shl <4 x i8> %InVec, <i8 2, i8 2, i8 2, i8 2>
     42 ; CHECK: ret
     43 
     44 define <4 x i8> @SplatPow2Test2_i8(<4 x i8> %InVec)  {
     45 entry:
     46   %mul = mul <4 x i8> %InVec, <i8 8, i8 8, i8 8, i8 8>
     47   ret <4 x i8> %mul
     48 }
     49 
     50 ; CHECK-LABEL: @SplatPow2Test2_i8(
     51 ; CHECK: shl <4 x i8> %InVec, <i8 3, i8 3, i8 3, i8 3>
     52 ; CHECK: ret
     53 
     54 define <4 x i8> @MulTest1_i8(<4 x i8> %InVec)  {
     55 entry:
     56   %mul = mul <4 x i8> %InVec, <i8 1, i8 2, i8 4, i8 8>
     57   ret <4 x i8> %mul
     58 }
     59 
     60 ; CHECK-LABEL: @MulTest1_i8(
     61 ; CHECK: shl <4 x i8> %InVec, <i8 0, i8 1, i8 2, i8 3>
     62 ; CHECK: ret
     63 
     64 define <4 x i8> @MulTest2_i8(<4 x i8> %InVec)  {
     65 entry:
     66   %mul = mul <4 x i8> %InVec, <i8 3, i8 3, i8 3, i8 3>
     67   ret <4 x i8> %mul
     68 }
     69 
     70 ; CHECK-LABEL: @MulTest2_i8(
     71 ; CHECK: mul <4 x i8> %InVec, <i8 3, i8 3, i8 3, i8 3>
     72 ; CHECK: ret
     73 
     74 define <4 x i8> @MulTest3_i8(<4 x i8> %InVec)  {
     75 entry:
     76   %mul = mul <4 x i8> %InVec, <i8 4, i8 4, i8 2, i8 2>
     77   ret <4 x i8> %mul
     78 }
     79 
     80 ; CHECK-LABEL: @MulTest3_i8(
     81 ; CHECK: shl <4 x i8> %InVec, <i8 2, i8 2, i8 1, i8 1>
     82 ; CHECK: ret
     83 
     84 
     85 define <4 x i8> @MulTest4_i8(<4 x i8> %InVec)  {
     86 entry:
     87   %mul = mul <4 x i8> %InVec, <i8 4, i8 4, i8 0, i8 1>
     88   ret <4 x i8> %mul
     89 }
     90 
     91 ; CHECK-LABEL: @MulTest4_i8(
     92 ; CHECK: mul <4 x i8> %InVec, <i8 4, i8 4, i8 0, i8 1>
     93 ; CHECK: ret
     94 
     95 define <4 x i16> @Zero_i16(<4 x i16> %InVec)  {
     96 entry:
     97   %mul = mul <4 x i16> %InVec, <i16 0, i16 0, i16 0, i16 0>
     98   ret <4 x i16> %mul
     99 }
    100 
    101 ; CHECK-LABEL: @Zero_i16(
    102 ; CHECK: ret <4 x i16> zeroinitializer
    103 
    104 define <4 x i16> @Identity_i16(<4 x i16> %InVec)  {
    105 entry:
    106   %mul = mul <4 x i16> %InVec, <i16 1, i16 1, i16 1, i16 1>
    107   ret <4 x i16> %mul
    108 }
    109 
    110 ; CHECK-LABEL: @Identity_i16(
    111 ; CHECK: ret <4 x i16> %InVec
    112 
    113 define <4 x i16> @AddToSelf_i16(<4 x i16> %InVec)  {
    114 entry:
    115   %mul = mul <4 x i16> %InVec, <i16 2, i16 2, i16 2, i16 2>
    116   ret <4 x i16> %mul
    117 }
    118 
    119 ; CHECK-LABEL: @AddToSelf_i16(
    120 ; CHECK: shl <4 x i16> %InVec, <i16 1, i16 1, i16 1, i16 1>
    121 ; CHECK: ret
    122 
    123 define <4 x i16> @SplatPow2Test1_i16(<4 x i16> %InVec)  {
    124 entry:
    125   %mul = mul <4 x i16> %InVec, <i16 4, i16 4, i16 4, i16 4>
    126   ret <4 x i16> %mul
    127 }
    128 
    129 ; CHECK-LABEL: @SplatPow2Test1_i16(
    130 ; CHECK: shl <4 x i16> %InVec, <i16 2, i16 2, i16 2, i16 2>
    131 ; CHECK: ret
    132 
    133 define <4 x i16> @SplatPow2Test2_i16(<4 x i16> %InVec)  {
    134 entry:
    135   %mul = mul <4 x i16> %InVec, <i16 8, i16 8, i16 8, i16 8>
    136   ret <4 x i16> %mul
    137 }
    138 
    139 ; CHECK-LABEL: @SplatPow2Test2_i16(
    140 ; CHECK: shl <4 x i16> %InVec, <i16 3, i16 3, i16 3, i16 3>
    141 ; CHECK: ret
    142 
    143 define <4 x i16> @MulTest1_i16(<4 x i16> %InVec)  {
    144 entry:
    145   %mul = mul <4 x i16> %InVec, <i16 1, i16 2, i16 4, i16 8>
    146   ret <4 x i16> %mul
    147 }
    148 
    149 ; CHECK-LABEL: @MulTest1_i16(
    150 ; CHECK: shl <4 x i16> %InVec, <i16 0, i16 1, i16 2, i16 3>
    151 ; CHECK: ret
    152 
    153 define <4 x i16> @MulTest2_i16(<4 x i16> %InVec)  {
    154 entry:
    155   %mul = mul <4 x i16> %InVec, <i16 3, i16 3, i16 3, i16 3>
    156   ret <4 x i16> %mul
    157 }
    158 
    159 ; CHECK-LABEL: @MulTest2_i16(
    160 ; CHECK: mul <4 x i16> %InVec, <i16 3, i16 3, i16 3, i16 3>
    161 ; CHECK: ret
    162 
    163 define <4 x i16> @MulTest3_i16(<4 x i16> %InVec)  {
    164 entry:
    165   %mul = mul <4 x i16> %InVec, <i16 4, i16 4, i16 2, i16 2>
    166   ret <4 x i16> %mul
    167 }
    168 
    169 ; CHECK-LABEL: @MulTest3_i16(
    170 ; CHECK: shl <4 x i16> %InVec, <i16 2, i16 2, i16 1, i16 1>
    171 ; CHECK: ret
    172 
    173 define <4 x i16> @MulTest4_i16(<4 x i16> %InVec)  {
    174 entry:
    175   %mul = mul <4 x i16> %InVec, <i16 4, i16 4, i16 0, i16 2>
    176   ret <4 x i16> %mul
    177 }
    178 
    179 ; CHECK-LABEL: @MulTest4_i16(
    180 ; CHECK: mul <4 x i16> %InVec, <i16 4, i16 4, i16 0, i16 2>
    181 ; CHECK: ret
    182 
    183 define <4 x i32> @Zero_i32(<4 x i32> %InVec)  {
    184 entry:
    185   %mul = mul <4 x i32> %InVec, <i32 0, i32 0, i32 0, i32 0>
    186   ret <4 x i32> %mul
    187 }
    188 
    189 ; CHECK-LABEL: @Zero_i32(
    190 ; CHECK: ret <4 x i32> zeroinitializer
    191 
    192 define <4 x i32> @Identity_i32(<4 x i32> %InVec)  {
    193 entry:
    194   %mul = mul <4 x i32> %InVec, <i32 1, i32 1, i32 1, i32 1>
    195   ret <4 x i32> %mul
    196 }
    197 
    198 ; CHECK-LABEL: @Identity_i32(
    199 ; CHECK: ret <4 x i32> %InVec
    200 
    201 define <4 x i32> @AddToSelf_i32(<4 x i32> %InVec)  {
    202 entry:
    203   %mul = mul <4 x i32> %InVec, <i32 2, i32 2, i32 2, i32 2>
    204   ret <4 x i32> %mul
    205 }
    206 
    207 ; CHECK-LABEL: @AddToSelf_i32(
    208 ; CHECK: shl <4 x i32> %InVec, <i32 1, i32 1, i32 1, i32 1>
    209 ; CHECK: ret
    210 
    211 
    212 define <4 x i32> @SplatPow2Test1_i32(<4 x i32> %InVec)  {
    213 entry:
    214   %mul = mul <4 x i32> %InVec, <i32 4, i32 4, i32 4, i32 4>
    215   ret <4 x i32> %mul
    216 }
    217 
    218 ; CHECK-LABEL: @SplatPow2Test1_i32(
    219 ; CHECK: shl <4 x i32> %InVec, <i32 2, i32 2, i32 2, i32 2>
    220 ; CHECK: ret
    221 
    222 define <4 x i32> @SplatPow2Test2_i32(<4 x i32> %InVec)  {
    223 entry:
    224   %mul = mul <4 x i32> %InVec, <i32 8, i32 8, i32 8, i32 8>
    225   ret <4 x i32> %mul
    226 }
    227 
    228 ; CHECK-LABEL: @SplatPow2Test2_i32(
    229 ; CHECK: shl <4 x i32> %InVec, <i32 3, i32 3, i32 3, i32 3>
    230 ; CHECK: ret
    231 
    232 define <4 x i32> @MulTest1_i32(<4 x i32> %InVec)  {
    233 entry:
    234   %mul = mul <4 x i32> %InVec, <i32 1, i32 2, i32 4, i32 8>
    235   ret <4 x i32> %mul
    236 }
    237 
    238 ; CHECK-LABEL: @MulTest1_i32(
    239 ; CHECK: shl <4 x i32> %InVec, <i32 0, i32 1, i32 2, i32 3>
    240 ; CHECK: ret
    241 
    242 define <4 x i32> @MulTest2_i32(<4 x i32> %InVec)  {
    243 entry:
    244   %mul = mul <4 x i32> %InVec, <i32 3, i32 3, i32 3, i32 3>
    245   ret <4 x i32> %mul
    246 }
    247 
    248 ; CHECK-LABEL: @MulTest2_i32(
    249 ; CHECK: mul <4 x i32> %InVec, <i32 3, i32 3, i32 3, i32 3>
    250 ; CHECK: ret
    251 
    252 define <4 x i32> @MulTest3_i32(<4 x i32> %InVec)  {
    253 entry:
    254   %mul = mul <4 x i32> %InVec, <i32 4, i32 4, i32 2, i32 2>
    255   ret <4 x i32> %mul
    256 }
    257 
    258 ; CHECK-LABEL: @MulTest3_i32(
    259 ; CHECK: shl <4 x i32> %InVec, <i32 2, i32 2, i32 1, i32 1>
    260 ; CHECK: ret
    261 
    262 
    263 define <4 x i32> @MulTest4_i32(<4 x i32> %InVec)  {
    264 entry:
    265   %mul = mul <4 x i32> %InVec, <i32 4, i32 4, i32 0, i32 1>
    266   ret <4 x i32> %mul
    267 }
    268 
    269 ; CHECK-LABEL: @MulTest4_i32(
    270 ; CHECK: mul <4 x i32> %InVec, <i32 4, i32 4, i32 0, i32 1>
    271 ; CHECK: ret
    272 
    273 define <4 x i64> @Zero_i64(<4 x i64> %InVec)  {
    274 entry:
    275   %mul = mul <4 x i64> %InVec, <i64 0, i64 0, i64 0, i64 0>
    276   ret <4 x i64> %mul
    277 }
    278 
    279 ; CHECK-LABEL: @Zero_i64(
    280 ; CHECK: ret <4 x i64> zeroinitializer
    281 
    282 define <4 x i64> @Identity_i64(<4 x i64> %InVec)  {
    283 entry:
    284   %mul = mul <4 x i64> %InVec, <i64 1, i64 1, i64 1, i64 1>
    285   ret <4 x i64> %mul
    286 }
    287 
    288 ; CHECK-LABEL: @Identity_i64(
    289 ; CHECK: ret <4 x i64> %InVec
    290 
    291 define <4 x i64> @AddToSelf_i64(<4 x i64> %InVec)  {
    292 entry:
    293   %mul = mul <4 x i64> %InVec, <i64 2, i64 2, i64 2, i64 2>
    294   ret <4 x i64> %mul
    295 }
    296 
    297 ; CHECK-LABEL: @AddToSelf_i64(
    298 ; CHECK: shl <4 x i64> %InVec, <i64 1, i64 1, i64 1, i64 1>
    299 ; CHECK: ret
    300 
    301 define <4 x i64> @SplatPow2Test1_i64(<4 x i64> %InVec)  {
    302 entry:
    303   %mul = mul <4 x i64> %InVec, <i64 4, i64 4, i64 4, i64 4>
    304   ret <4 x i64> %mul
    305 }
    306 
    307 ; CHECK-LABEL: @SplatPow2Test1_i64(
    308 ; CHECK: shl <4 x i64> %InVec, <i64 2, i64 2, i64 2, i64 2>
    309 ; CHECK: ret
    310 
    311 define <4 x i64> @SplatPow2Test2_i64(<4 x i64> %InVec)  {
    312 entry:
    313   %mul = mul <4 x i64> %InVec, <i64 8, i64 8, i64 8, i64 8>
    314   ret <4 x i64> %mul
    315 }
    316 
    317 ; CHECK-LABEL: @SplatPow2Test2_i64(
    318 ; CHECK: shl <4 x i64> %InVec, <i64 3, i64 3, i64 3, i64 3>
    319 ; CHECK: ret
    320 
    321 define <4 x i64> @MulTest1_i64(<4 x i64> %InVec)  {
    322 entry:
    323   %mul = mul <4 x i64> %InVec, <i64 1, i64 2, i64 4, i64 8>
    324   ret <4 x i64> %mul
    325 }
    326 
    327 ; CHECK-LABEL: @MulTest1_i64(
    328 ; CHECK: shl <4 x i64> %InVec, <i64 0, i64 1, i64 2, i64 3>
    329 ; CHECK: ret
    330 
    331 define <4 x i64> @MulTest2_i64(<4 x i64> %InVec)  {
    332 entry:
    333   %mul = mul <4 x i64> %InVec, <i64 3, i64 3, i64 3, i64 3>
    334   ret <4 x i64> %mul
    335 }
    336 
    337 ; CHECK-LABEL: @MulTest2_i64(
    338 ; CHECK: mul <4 x i64> %InVec, <i64 3, i64 3, i64 3, i64 3>
    339 ; CHECK: ret
    340 
    341 define <4 x i64> @MulTest3_i64(<4 x i64> %InVec)  {
    342 entry:
    343   %mul = mul <4 x i64> %InVec, <i64 4, i64 4, i64 2, i64 2>
    344   ret <4 x i64> %mul
    345 }
    346 
    347 ; CHECK-LABEL: @MulTest3_i64(
    348 ; CHECK: shl <4 x i64> %InVec, <i64 2, i64 2, i64 1, i64 1>
    349 ; CHECK: ret
    350 
    351 define <4 x i64> @MulTest4_i64(<4 x i64> %InVec)  {
    352 entry:
    353   %mul = mul <4 x i64> %InVec, <i64 4, i64 4, i64 0, i64 1>
    354   ret <4 x i64> %mul
    355 }
    356 
    357 ; CHECK-LABEL: @MulTest4_i64(
    358 ; CHECK: mul <4 x i64> %InVec, <i64 4, i64 4, i64 0, i64 1>
    359 ; CHECK: ret
    360 
    361 ; Test also that the following rewriting rule works with vectors
    362 ; of integers as well:
    363 ;   ((X << C1)*C2) == (X * (C2 << C1))
    364 
    365 define <4 x i8> @ShiftMulTest1(<4 x i8> %InVec) {
    366 entry:
    367   %shl = shl <4 x i8> %InVec, <i8 2, i8 2, i8 2, i8 2>
    368   %mul = mul <4 x i8> %shl, <i8 3, i8 3, i8 3, i8 3>
    369   ret <4 x i8> %mul
    370 }
    371 
    372 ; CHECK-LABEL: @ShiftMulTest1(
    373 ; CHECK: mul <4 x i8> %InVec, <i8 12, i8 12, i8 12, i8 12>
    374 ; CHECK: ret
    375 
    376 define <4 x i16> @ShiftMulTest2(<4 x i16> %InVec) {
    377 entry:
    378   %shl = shl <4 x i16> %InVec, <i16 2, i16 2, i16 2, i16 2>
    379   %mul = mul <4 x i16> %shl, <i16 3, i16 3, i16 3, i16 3>
    380   ret <4 x i16> %mul
    381 }
    382 
    383 ; CHECK-LABEL: @ShiftMulTest2(
    384 ; CHECK: mul <4 x i16> %InVec, <i16 12, i16 12, i16 12, i16 12>
    385 ; CHECK: ret
    386 
    387 define <4 x i32> @ShiftMulTest3(<4 x i32> %InVec) {
    388 entry:
    389   %shl = shl <4 x i32> %InVec, <i32 2, i32 2, i32 2, i32 2>
    390   %mul = mul <4 x i32> %shl, <i32 3, i32 3, i32 3, i32 3>
    391   ret <4 x i32> %mul
    392 }
    393 
    394 ; CHECK-LABEL: @ShiftMulTest3(
    395 ; CHECK: mul <4 x i32> %InVec, <i32 12, i32 12, i32 12, i32 12>
    396 ; CHECK: ret
    397 
    398 define <4 x i64> @ShiftMulTest4(<4 x i64> %InVec) {
    399 entry:
    400   %shl = shl <4 x i64> %InVec, <i64 2, i64 2, i64 2, i64 2>
    401   %mul = mul <4 x i64> %shl, <i64 3, i64 3, i64 3, i64 3>
    402   ret <4 x i64> %mul
    403 }
    404 
    405 ; CHECK-LABEL: @ShiftMulTest4(
    406 ; CHECK: mul <4 x i64> %InVec, <i64 12, i64 12, i64 12, i64 12>
    407 ; CHECK: ret
    408 
    409