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 8define 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 16define 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 24define 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 32define 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 41define 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 50define 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. 61define 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 70define 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 79define 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 88define 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 97define 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 107define 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 117define 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 127define 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 137define 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 147define 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 157define 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 166define 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 174define 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 182define 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 191define 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 199define 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 208define 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 216define 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 224define 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 233define 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 245define 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 253define 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 261define 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 269define 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 277define 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 285define 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 293define 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 301define 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 310define 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 318define 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 326define 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 334define 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 341define 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 349define 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 357define 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