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