Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc < %s -mtriple=aarch64-eabi | FileCheck %s
      2 
      3 ; Convert mul x, pow2 to shift.
      4 ; Convert mul x, pow2 +/- 1 to shift + add/sub.
      5 ; Convert mul x, (pow2 + 1) * pow2 to shift + add + shift.
      6 ; Lowering other positive constants are not supported yet.
      7 
      8 define i32 @test2(i32 %x) {
      9 ; CHECK-LABEL: test2
     10 ; CHECK: lsl w0, w0, #1
     11 
     12   %mul = shl nsw i32 %x, 1
     13   ret i32 %mul
     14 }
     15 
     16 define i32 @test3(i32 %x) {
     17 ; CHECK-LABEL: test3
     18 ; CHECK: add w0, w0, w0, lsl #1
     19 
     20   %mul = mul nsw i32 %x, 3
     21   ret i32 %mul
     22 }
     23 
     24 define i32 @test4(i32 %x) {
     25 ; CHECK-LABEL: test4
     26 ; CHECK: lsl w0, w0, #2
     27 
     28   %mul = shl nsw i32 %x, 2
     29   ret i32 %mul
     30 }
     31 
     32 define i32 @test5(i32 %x) {
     33 ; CHECK-LABEL: test5
     34 ; CHECK: add w0, w0, w0, lsl #2
     35 
     36 
     37   %mul = mul nsw i32 %x, 5
     38   ret i32 %mul
     39 }
     40 
     41 define i32 @test6_32b(i32 %x) {
     42 ; CHECK-LABEL: test6
     43 ; CHECK: add {{w[0-9]+}}, w0, w0, lsl #1
     44 ; CHECK: lsl w0, {{w[0-9]+}}, #1
     45 
     46   %mul = mul nsw i32 %x, 6 
     47   ret i32 %mul
     48 }
     49 
     50 define i64 @test6_64b(i64 %x) {
     51 ; CHECK-LABEL: test6_64b
     52 ; CHECK: add {{x[0-9]+}}, x0, x0, lsl #1
     53 ; CHECK: lsl x0, {{x[0-9]+}}, #1
     54 
     55   %mul = mul nsw i64 %x, 6 
     56   ret i64 %mul
     57 }
     58 
     59 ; mul that appears together with add, sub, s(z)ext is not supported to be 
     60 ; converted to the combination of lsl, add/sub yet.
     61 define i64 @test6_umull(i32 %x) {
     62 ; CHECK-LABEL: test6_umull
     63 ; CHECK: umull x0, w0, {{w[0-9]+}} 
     64 
     65   %ext = zext i32 %x to i64
     66   %mul = mul nsw i64 %ext, 6 
     67   ret i64 %mul
     68 }
     69 
     70 define i64 @test6_smull(i32 %x) {
     71 ; CHECK-LABEL: test6_smull
     72 ; CHECK: smull x0, w0, {{w[0-9]+}} 
     73 
     74   %ext = sext i32 %x to i64
     75   %mul = mul nsw i64 %ext, 6 
     76   ret i64 %mul
     77 }
     78 
     79 define i32 @test6_madd(i32 %x, i32 %y) {
     80 ; CHECK-LABEL: test6_madd
     81 ; CHECK: madd w0, w0, {{w[0-9]+}}, w1 
     82 
     83   %mul = mul nsw i32 %x, 6 
     84   %add = add i32 %mul, %y
     85   ret i32 %add
     86 }
     87 
     88 define i32 @test6_msub(i32 %x, i32 %y) {
     89 ; CHECK-LABEL: test6_msub
     90 ; CHECK: msub w0, w0, {{w[0-9]+}}, w1 
     91 
     92   %mul = mul nsw i32 %x, 6 
     93   %sub = sub i32 %y, %mul
     94   ret i32 %sub
     95 }
     96 
     97 define i64 @test6_umaddl(i32 %x, i64 %y) {
     98 ; CHECK-LABEL: test6_umaddl
     99 ; CHECK: umaddl x0, w0, {{w[0-9]+}}, x1 
    100 
    101   %ext = zext i32 %x to i64
    102   %mul = mul nsw i64 %ext, 6 
    103   %add = add i64 %mul, %y
    104   ret i64 %add
    105 }
    106 
    107 define i64 @test6_smaddl(i32 %x, i64 %y) {
    108 ; CHECK-LABEL: test6_smaddl
    109 ; CHECK: smaddl x0, w0, {{w[0-9]+}}, x1
    110 
    111   %ext = sext i32 %x to i64
    112   %mul = mul nsw i64 %ext, 6 
    113   %add = add i64 %mul, %y
    114   ret i64 %add
    115 }
    116 
    117 define i64 @test6_umsubl(i32 %x, i64 %y) {
    118 ; CHECK-LABEL: test6_umsubl
    119 ; CHECK: umsubl x0, w0, {{w[0-9]+}}, x1
    120 
    121   %ext = zext i32 %x to i64
    122   %mul = mul nsw i64 %ext, 6 
    123   %sub = sub i64 %y, %mul
    124   ret i64 %sub
    125 }
    126 
    127 define i64 @test6_smsubl(i32 %x, i64 %y) {
    128 ; CHECK-LABEL: test6_smsubl
    129 ; CHECK: smsubl x0, w0, {{w[0-9]+}}, x1 
    130 
    131   %ext = sext i32 %x to i64
    132   %mul = mul nsw i64 %ext, 6 
    133   %sub = sub i64 %y, %mul
    134   ret i64 %sub
    135 }
    136 
    137 define i64 @test6_umnegl(i32 %x) {
    138 ; CHECK-LABEL: test6_umnegl
    139 ; CHECK: umnegl x0, w0, {{w[0-9]+}} 
    140 
    141   %ext = zext i32 %x to i64
    142   %mul = mul nsw i64 %ext, 6 
    143   %sub = sub i64 0, %mul
    144   ret i64 %sub
    145 }
    146 
    147 define i64 @test6_smnegl(i32 %x) {
    148 ; CHECK-LABEL: test6_smnegl
    149 ; CHECK: smnegl x0, w0, {{w[0-9]+}} 
    150 
    151   %ext = sext i32 %x to i64
    152   %mul = mul nsw i64 %ext, 6 
    153   %sub = sub i64 0, %mul
    154   ret i64 %sub
    155 }
    156 
    157 define i32 @test7(i32 %x) {
    158 ; CHECK-LABEL: test7
    159 ; CHECK: lsl {{w[0-9]+}}, w0, #3
    160 ; CHECK: sub w0, {{w[0-9]+}}, w0
    161 
    162   %mul = mul nsw i32 %x, 7
    163   ret i32 %mul
    164 }
    165 
    166 define i32 @test8(i32 %x) {
    167 ; CHECK-LABEL: test8
    168 ; CHECK: lsl w0, w0, #3
    169 
    170   %mul = shl nsw i32 %x, 3
    171   ret i32 %mul
    172 }
    173 
    174 define i32 @test9(i32 %x) {
    175 ; CHECK-LABEL: test9
    176 ; CHECK: add w0, w0, w0, lsl #3
    177 
    178   %mul = mul nsw i32 %x, 9 
    179   ret i32 %mul
    180 }
    181 
    182 define i32 @test10(i32 %x) {
    183 ; CHECK-LABEL: test10
    184 ; CHECK: add {{w[0-9]+}}, w0, w0, lsl #2
    185 ; CHECK: lsl w0, {{w[0-9]+}}, #1
    186 
    187   %mul = mul nsw i32 %x, 10
    188   ret i32 %mul
    189 }
    190 
    191 define i32 @test11(i32 %x) {
    192 ; CHECK-LABEL: test11
    193 ; CHECK: mul w0, w0, {{w[0-9]+}}
    194 
    195   %mul = mul nsw i32 %x, 11
    196   ret i32 %mul
    197 }
    198 
    199 define i32 @test12(i32 %x) {
    200 ; CHECK-LABEL: test12
    201 ; CHECK: add {{w[0-9]+}}, w0, w0, lsl #1
    202 ; CHECK: lsl w0, {{w[0-9]+}}, #2
    203 
    204   %mul = mul nsw i32 %x, 12
    205   ret i32 %mul
    206 }
    207 
    208 define i32 @test13(i32 %x) {
    209 ; CHECK-LABEL: test13
    210 ; CHECK: mul w0, w0, {{w[0-9]+}}
    211 
    212   %mul = mul nsw i32 %x, 13
    213   ret i32 %mul
    214 }
    215 
    216 define i32 @test14(i32 %x) {
    217 ; CHECK-LABEL: test14
    218 ; CHECK: mul w0, w0, {{w[0-9]+}}
    219 
    220   %mul = mul nsw i32 %x, 14 
    221   ret i32 %mul
    222 }
    223 
    224 define i32 @test15(i32 %x) {
    225 ; CHECK-LABEL: test15
    226 ; CHECK: lsl {{w[0-9]+}}, w0, #4
    227 ; CHECK: sub w0, {{w[0-9]+}}, w0
    228 
    229   %mul = mul nsw i32 %x, 15
    230   ret i32 %mul
    231 }
    232 
    233 define i32 @test16(i32 %x) {
    234 ; CHECK-LABEL: test16
    235 ; CHECK: lsl w0, w0, #4
    236 
    237   %mul = mul nsw i32 %x, 16
    238   ret i32 %mul
    239 }
    240 
    241 ; Convert mul x, -pow2 to shift.
    242 ; Convert mul x, -(pow2 +/- 1) to shift + add/sub.
    243 ; Lowering other negative constants are not supported yet.
    244 
    245 define i32 @ntest2(i32 %x) {
    246 ; CHECK-LABEL: ntest2
    247 ; CHECK: neg w0, w0, lsl #1
    248 
    249   %mul = mul nsw i32 %x, -2
    250   ret i32 %mul
    251 }
    252 
    253 define i32 @ntest3(i32 %x) {
    254 ; CHECK-LABEL: ntest3
    255 ; CHECK: sub w0, w0, w0, lsl #2
    256 
    257   %mul = mul nsw i32 %x, -3
    258   ret i32 %mul
    259 }
    260 
    261 define i32 @ntest4(i32 %x) {
    262 ; CHECK-LABEL: ntest4
    263 ; CHECK:neg w0, w0, lsl #2
    264 
    265   %mul = mul nsw i32 %x, -4
    266   ret i32 %mul
    267 }
    268 
    269 define i32 @ntest5(i32 %x) {
    270 ; CHECK-LABEL: ntest5
    271 ; CHECK: add {{w[0-9]+}}, w0, w0, lsl #2
    272 ; CHECK: neg w0, {{w[0-9]+}}
    273   %mul = mul nsw i32 %x, -5
    274   ret i32 %mul
    275 }
    276 
    277 define i32 @ntest6(i32 %x) {
    278 ; CHECK-LABEL: ntest6
    279 ; CHECK: mul w0, w0, {{w[0-9]+}}
    280 
    281   %mul = mul nsw i32 %x, -6
    282   ret i32 %mul
    283 }
    284 
    285 define i32 @ntest7(i32 %x) {
    286 ; CHECK-LABEL: ntest7
    287 ; CHECK: sub w0, w0, w0, lsl #3
    288 
    289   %mul = mul nsw i32 %x, -7
    290   ret i32 %mul
    291 }
    292 
    293 define i32 @ntest8(i32 %x) {
    294 ; CHECK-LABEL: ntest8
    295 ; CHECK: neg w0, w0, lsl #3
    296 
    297   %mul = mul nsw i32 %x, -8
    298   ret i32 %mul
    299 }
    300 
    301 define i32 @ntest9(i32 %x) {
    302 ; CHECK-LABEL: ntest9
    303 ; CHECK: add {{w[0-9]+}}, w0, w0, lsl #3
    304 ; CHECK: neg w0, {{w[0-9]+}}
    305 
    306   %mul = mul nsw i32 %x, -9
    307   ret i32 %mul
    308 }
    309 
    310 define i32 @ntest10(i32 %x) {
    311 ; CHECK-LABEL: ntest10
    312 ; CHECK: mul w0, w0, {{w[0-9]+}}
    313 
    314   %mul = mul nsw i32 %x, -10
    315   ret i32 %mul
    316 }
    317 
    318 define i32 @ntest11(i32 %x) {
    319 ; CHECK-LABEL: ntest11
    320 ; CHECK: mul w0, w0, {{w[0-9]+}}
    321 
    322   %mul = mul nsw i32 %x, -11
    323   ret i32 %mul
    324 }
    325 
    326 define i32 @ntest12(i32 %x) {
    327 ; CHECK-LABEL: ntest12
    328 ; CHECK: mul w0, w0, {{w[0-9]+}}
    329 
    330   %mul = mul nsw i32 %x, -12
    331   ret i32 %mul
    332 }
    333 
    334 define i32 @ntest13(i32 %x) {
    335 ; CHECK-LABEL: ntest13
    336 ; CHECK: mul w0, w0, {{w[0-9]+}}
    337   %mul = mul nsw i32 %x, -13
    338   ret i32 %mul
    339 }
    340 
    341 define i32 @ntest14(i32 %x) {
    342 ; CHECK-LABEL: ntest14
    343 ; CHECK: mul w0, w0, {{w[0-9]+}}
    344 
    345   %mul = mul nsw i32 %x, -14
    346   ret i32 %mul
    347 }
    348 
    349 define i32 @ntest15(i32 %x) {
    350 ; CHECK-LABEL: ntest15
    351 ; CHECK: sub w0, w0, w0, lsl #4
    352 
    353   %mul = mul nsw i32 %x, -15
    354   ret i32 %mul
    355 }
    356 
    357 define i32 @ntest16(i32 %x) {
    358 ; CHECK-LABEL: ntest16
    359 ; CHECK: neg w0, w0, lsl #4
    360 
    361   %mul = mul nsw i32 %x, -16
    362   ret i32 %mul
    363 }
    364