1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s --check-prefix=X64 3 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 | FileCheck %s --check-prefix=X64 4 ; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s --check-prefix=X86 5 6 define i32 @mul4_32(i32 %A) { 7 ; X64-LABEL: mul4_32: 8 ; X64: # %bb.0: 9 ; X64-NEXT: # kill: def $edi killed $edi def $rdi 10 ; X64-NEXT: leal (,%rdi,4), %eax 11 ; X64-NEXT: retq 12 ; 13 ; X86-LABEL: mul4_32: 14 ; X86: # %bb.0: 15 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 16 ; X86-NEXT: shll $2, %eax 17 ; X86-NEXT: retl 18 %mul = mul i32 %A, 4 19 ret i32 %mul 20 } 21 22 define i64 @mul4_64(i64 %A) { 23 ; X64-LABEL: mul4_64: 24 ; X64: # %bb.0: 25 ; X64-NEXT: leaq (,%rdi,4), %rax 26 ; X64-NEXT: retq 27 ; 28 ; X86-LABEL: mul4_64: 29 ; X86: # %bb.0: 30 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 31 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 32 ; X86-NEXT: shldl $2, %eax, %edx 33 ; X86-NEXT: shll $2, %eax 34 ; X86-NEXT: retl 35 %mul = mul i64 %A, 4 36 ret i64 %mul 37 } 38 39 define i32 @mul4096_32(i32 %A) { 40 ; X64-LABEL: mul4096_32: 41 ; X64: # %bb.0: 42 ; X64-NEXT: shll $12, %edi 43 ; X64-NEXT: movl %edi, %eax 44 ; X64-NEXT: retq 45 ; 46 ; X86-LABEL: mul4096_32: 47 ; X86: # %bb.0: 48 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 49 ; X86-NEXT: shll $12, %eax 50 ; X86-NEXT: retl 51 %mul = mul i32 %A, 4096 52 ret i32 %mul 53 } 54 55 define i64 @mul4096_64(i64 %A) { 56 ; X64-LABEL: mul4096_64: 57 ; X64: # %bb.0: 58 ; X64-NEXT: shlq $12, %rdi 59 ; X64-NEXT: movq %rdi, %rax 60 ; X64-NEXT: retq 61 ; 62 ; X86-LABEL: mul4096_64: 63 ; X86: # %bb.0: 64 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 65 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 66 ; X86-NEXT: shldl $12, %eax, %edx 67 ; X86-NEXT: shll $12, %eax 68 ; X86-NEXT: retl 69 %mul = mul i64 %A, 4096 70 ret i64 %mul 71 } 72 73 define i32 @mulmin4096_32(i32 %A) { 74 ; X64-LABEL: mulmin4096_32: 75 ; X64: # %bb.0: 76 ; X64-NEXT: shll $12, %edi 77 ; X64-NEXT: negl %edi 78 ; X64-NEXT: movl %edi, %eax 79 ; X64-NEXT: retq 80 ; 81 ; X86-LABEL: mulmin4096_32: 82 ; X86: # %bb.0: 83 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 84 ; X86-NEXT: shll $12, %eax 85 ; X86-NEXT: negl %eax 86 ; X86-NEXT: retl 87 %mul = mul i32 %A, -4096 88 ret i32 %mul 89 } 90 91 define i64 @mulmin4096_64(i64 %A) { 92 ; X64-LABEL: mulmin4096_64: 93 ; X64: # %bb.0: 94 ; X64-NEXT: shlq $12, %rdi 95 ; X64-NEXT: negq %rdi 96 ; X64-NEXT: movq %rdi, %rax 97 ; X64-NEXT: retq 98 ; 99 ; X86-LABEL: mulmin4096_64: 100 ; X86: # %bb.0: 101 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 102 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 103 ; X86-NEXT: shldl $12, %eax, %ecx 104 ; X86-NEXT: shll $12, %eax 105 ; X86-NEXT: xorl %edx, %edx 106 ; X86-NEXT: negl %eax 107 ; X86-NEXT: sbbl %ecx, %edx 108 ; X86-NEXT: retl 109 %mul = mul i64 %A, -4096 110 ret i64 %mul 111 } 112 113 define i32 @mul3_32(i32 %A) { 114 ; X64-LABEL: mul3_32: 115 ; X64: # %bb.0: 116 ; X64-NEXT: # kill: def $edi killed $edi def $rdi 117 ; X64-NEXT: leal (%rdi,%rdi,2), %eax 118 ; X64-NEXT: retq 119 ; 120 ; X86-LABEL: mul3_32: 121 ; X86: # %bb.0: 122 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 123 ; X86-NEXT: leal (%eax,%eax,2), %eax 124 ; X86-NEXT: retl 125 ; But why?! 126 %mul = mul i32 %A, 3 127 ret i32 %mul 128 } 129 130 define i64 @mul3_64(i64 %A) { 131 ; X64-LABEL: mul3_64: 132 ; X64: # %bb.0: 133 ; X64-NEXT: leaq (%rdi,%rdi,2), %rax 134 ; X64-NEXT: retq 135 ; 136 ; X86-LABEL: mul3_64: 137 ; X86: # %bb.0: 138 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 139 ; X86-NEXT: leal (%eax,%eax,2), %ecx 140 ; X86-NEXT: movl $3, %eax 141 ; X86-NEXT: mull {{[0-9]+}}(%esp) 142 ; X86-NEXT: addl %ecx, %edx 143 ; X86-NEXT: retl 144 %mul = mul i64 %A, 3 145 ret i64 %mul 146 } 147 148 define i32 @mul40_32(i32 %A) { 149 ; X64-LABEL: mul40_32: 150 ; X64: # %bb.0: 151 ; X64-NEXT: # kill: def $edi killed $edi def $rdi 152 ; X64-NEXT: shll $3, %edi 153 ; X64-NEXT: leal (%rdi,%rdi,4), %eax 154 ; X64-NEXT: retq 155 ; 156 ; X86-LABEL: mul40_32: 157 ; X86: # %bb.0: 158 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 159 ; X86-NEXT: shll $3, %eax 160 ; X86-NEXT: leal (%eax,%eax,4), %eax 161 ; X86-NEXT: retl 162 %mul = mul i32 %A, 40 163 ret i32 %mul 164 } 165 166 define i64 @mul40_64(i64 %A) { 167 ; X64-LABEL: mul40_64: 168 ; X64: # %bb.0: 169 ; X64-NEXT: shlq $3, %rdi 170 ; X64-NEXT: leaq (%rdi,%rdi,4), %rax 171 ; X64-NEXT: retq 172 ; 173 ; X86-LABEL: mul40_64: 174 ; X86: # %bb.0: 175 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 176 ; X86-NEXT: leal (%eax,%eax,4), %ecx 177 ; X86-NEXT: movl $40, %eax 178 ; X86-NEXT: mull {{[0-9]+}}(%esp) 179 ; X86-NEXT: leal (%edx,%ecx,8), %edx 180 ; X86-NEXT: retl 181 %mul = mul i64 %A, 40 182 ret i64 %mul 183 } 184 185 define i32 @mul4_32_minsize(i32 %A) minsize { 186 ; X64-LABEL: mul4_32_minsize: 187 ; X64: # %bb.0: 188 ; X64-NEXT: # kill: def $edi killed $edi def $rdi 189 ; X64-NEXT: leal (,%rdi,4), %eax 190 ; X64-NEXT: retq 191 ; 192 ; X86-LABEL: mul4_32_minsize: 193 ; X86: # %bb.0: 194 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 195 ; X86-NEXT: shll $2, %eax 196 ; X86-NEXT: retl 197 %mul = mul i32 %A, 4 198 ret i32 %mul 199 } 200 201 define i32 @mul40_32_minsize(i32 %A) minsize { 202 ; X64-LABEL: mul40_32_minsize: 203 ; X64: # %bb.0: 204 ; X64-NEXT: imull $40, %edi, %eax 205 ; X64-NEXT: retq 206 ; 207 ; X86-LABEL: mul40_32_minsize: 208 ; X86: # %bb.0: 209 ; X86-NEXT: imull $40, {{[0-9]+}}(%esp), %eax 210 ; X86-NEXT: retl 211 %mul = mul i32 %A, 40 212 ret i32 %mul 213 } 214 215 define i32 @mul33_32(i32 %A) { 216 ; X64-LABEL: mul33_32: 217 ; X64: # %bb.0: 218 ; X64-NEXT: # kill: def $edi killed $edi def $rdi 219 ; X64-NEXT: movl %edi, %eax 220 ; X64-NEXT: shll $5, %eax 221 ; X64-NEXT: leal (%rax,%rdi), %eax 222 ; X64-NEXT: retq 223 ; 224 ; X86-LABEL: mul33_32: 225 ; X86: # %bb.0: 226 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 227 ; X86-NEXT: movl %ecx, %eax 228 ; X86-NEXT: shll $5, %eax 229 ; X86-NEXT: addl %ecx, %eax 230 ; X86-NEXT: retl 231 %mul = mul i32 %A, 33 232 ret i32 %mul 233 } 234 235 define i32 @mul31_32(i32 %A) { 236 ; X64-LABEL: mul31_32: 237 ; X64: # %bb.0: 238 ; X64-NEXT: movl %edi, %eax 239 ; X64-NEXT: shll $5, %eax 240 ; X64-NEXT: subl %edi, %eax 241 ; X64-NEXT: retq 242 ; 243 ; X86-LABEL: mul31_32: 244 ; X86: # %bb.0: 245 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 246 ; X86-NEXT: movl %ecx, %eax 247 ; X86-NEXT: shll $5, %eax 248 ; X86-NEXT: subl %ecx, %eax 249 ; X86-NEXT: retl 250 %mul = mul i32 %A, 31 251 ret i32 %mul 252 } 253 254 define i32 @mul0_32(i32 %A) { 255 ; X64-LABEL: mul0_32: 256 ; X64: # %bb.0: 257 ; X64-NEXT: xorl %eax, %eax 258 ; X64-NEXT: retq 259 ; 260 ; X86-LABEL: mul0_32: 261 ; X86: # %bb.0: 262 ; X86-NEXT: xorl %eax, %eax 263 ; X86-NEXT: retl 264 %mul = mul i32 %A, 0 265 ret i32 %mul 266 } 267 268 define i32 @mul4294967295_32(i32 %A) { 269 ; X64-LABEL: mul4294967295_32: 270 ; X64: # %bb.0: 271 ; X64-NEXT: negl %edi 272 ; X64-NEXT: movl %edi, %eax 273 ; X64-NEXT: retq 274 ; 275 ; X86-LABEL: mul4294967295_32: 276 ; X86: # %bb.0: 277 ; X86-NEXT: xorl %eax, %eax 278 ; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 279 ; X86-NEXT: retl 280 %mul = mul i32 %A, 4294967295 281 ret i32 %mul 282 } 283 284 define i64 @mul18446744073709551615_64(i64 %A) { 285 ; X64-LABEL: mul18446744073709551615_64: 286 ; X64: # %bb.0: 287 ; X64-NEXT: negq %rdi 288 ; X64-NEXT: movq %rdi, %rax 289 ; X64-NEXT: retq 290 ; 291 ; X86-LABEL: mul18446744073709551615_64: 292 ; X86: # %bb.0: 293 ; X86-NEXT: xorl %edx, %edx 294 ; X86-NEXT: xorl %eax, %eax 295 ; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 296 ; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 297 ; X86-NEXT: retl 298 %mul = mul i64 %A, 18446744073709551615 299 ret i64 %mul 300 } 301 302 define i32 @test(i32 %a) { 303 ; X64-LABEL: test: 304 ; X64: # %bb.0: # %entry 305 ; X64-NEXT: movl %edi, %eax 306 ; X64-NEXT: shll $5, %eax 307 ; X64-NEXT: subl %edi, %eax 308 ; X64-NEXT: retq 309 ; 310 ; X86-LABEL: test: 311 ; X86: # %bb.0: # %entry 312 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 313 ; X86-NEXT: movl %ecx, %eax 314 ; X86-NEXT: shll $5, %eax 315 ; X86-NEXT: subl %ecx, %eax 316 ; X86-NEXT: retl 317 entry: 318 %tmp3 = mul i32 %a, 31 319 ret i32 %tmp3 320 } 321 322 define i32 @test1(i32 %a) { 323 ; X64-LABEL: test1: 324 ; X64: # %bb.0: # %entry 325 ; X64-NEXT: movl %edi, %eax 326 ; X64-NEXT: shll $5, %eax 327 ; X64-NEXT: subl %eax, %edi 328 ; X64-NEXT: movl %edi, %eax 329 ; X64-NEXT: retq 330 ; 331 ; X86-LABEL: test1: 332 ; X86: # %bb.0: # %entry 333 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 334 ; X86-NEXT: movl %eax, %ecx 335 ; X86-NEXT: shll $5, %ecx 336 ; X86-NEXT: subl %ecx, %eax 337 ; X86-NEXT: retl 338 entry: 339 %tmp3 = mul i32 %a, -31 340 ret i32 %tmp3 341 } 342 343 344 define i32 @test2(i32 %a) { 345 ; X64-LABEL: test2: 346 ; X64: # %bb.0: # %entry 347 ; X64-NEXT: # kill: def $edi killed $edi def $rdi 348 ; X64-NEXT: movl %edi, %eax 349 ; X64-NEXT: shll $5, %eax 350 ; X64-NEXT: leal (%rax,%rdi), %eax 351 ; X64-NEXT: retq 352 ; 353 ; X86-LABEL: test2: 354 ; X86: # %bb.0: # %entry 355 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 356 ; X86-NEXT: movl %ecx, %eax 357 ; X86-NEXT: shll $5, %eax 358 ; X86-NEXT: addl %ecx, %eax 359 ; X86-NEXT: retl 360 entry: 361 %tmp3 = mul i32 %a, 33 362 ret i32 %tmp3 363 } 364 365 define i32 @test3(i32 %a) { 366 ; X64-LABEL: test3: 367 ; X64: # %bb.0: # %entry 368 ; X64-NEXT: # kill: def $edi killed $edi def $rdi 369 ; X64-NEXT: movl %edi, %eax 370 ; X64-NEXT: shll $5, %eax 371 ; X64-NEXT: leal (%rax,%rdi), %eax 372 ; X64-NEXT: negl %eax 373 ; X64-NEXT: retq 374 ; 375 ; X86-LABEL: test3: 376 ; X86: # %bb.0: # %entry 377 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 378 ; X86-NEXT: movl %ecx, %eax 379 ; X86-NEXT: shll $5, %eax 380 ; X86-NEXT: addl %ecx, %eax 381 ; X86-NEXT: negl %eax 382 ; X86-NEXT: retl 383 entry: 384 %tmp3 = mul i32 %a, -33 385 ret i32 %tmp3 386 } 387 388 define i64 @test4(i64 %a) { 389 ; X64-LABEL: test4: 390 ; X64: # %bb.0: # %entry 391 ; X64-NEXT: movq %rdi, %rax 392 ; X64-NEXT: shlq $5, %rax 393 ; X64-NEXT: subq %rdi, %rax 394 ; X64-NEXT: retq 395 ; 396 ; X86-LABEL: test4: 397 ; X86: # %bb.0: # %entry 398 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 399 ; X86-NEXT: movl %eax, %ecx 400 ; X86-NEXT: shll $5, %ecx 401 ; X86-NEXT: subl %eax, %ecx 402 ; X86-NEXT: movl $31, %eax 403 ; X86-NEXT: mull {{[0-9]+}}(%esp) 404 ; X86-NEXT: addl %ecx, %edx 405 ; X86-NEXT: retl 406 entry: 407 %tmp3 = mul i64 %a, 31 408 ret i64 %tmp3 409 } 410 411 define i64 @test5(i64 %a) { 412 ; X64-LABEL: test5: 413 ; X64: # %bb.0: # %entry 414 ; X64-NEXT: movq %rdi, %rax 415 ; X64-NEXT: shlq $5, %rax 416 ; X64-NEXT: subq %rax, %rdi 417 ; X64-NEXT: movq %rdi, %rax 418 ; X64-NEXT: retq 419 ; 420 ; X86-LABEL: test5: 421 ; X86: # %bb.0: # %entry 422 ; X86-NEXT: pushl %esi 423 ; X86-NEXT: .cfi_def_cfa_offset 8 424 ; X86-NEXT: .cfi_offset %esi, -8 425 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 426 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 427 ; X86-NEXT: movl %esi, %eax 428 ; X86-NEXT: shll $5, %eax 429 ; X86-NEXT: subl %eax, %esi 430 ; X86-NEXT: movl $-31, %edx 431 ; X86-NEXT: movl %ecx, %eax 432 ; X86-NEXT: mull %edx 433 ; X86-NEXT: subl %ecx, %edx 434 ; X86-NEXT: addl %esi, %edx 435 ; X86-NEXT: popl %esi 436 ; X86-NEXT: .cfi_def_cfa_offset 4 437 ; X86-NEXT: retl 438 entry: 439 %tmp3 = mul i64 %a, -31 440 ret i64 %tmp3 441 } 442 443 444 define i64 @test6(i64 %a) { 445 ; X64-LABEL: test6: 446 ; X64: # %bb.0: # %entry 447 ; X64-NEXT: movq %rdi, %rax 448 ; X64-NEXT: shlq $5, %rax 449 ; X64-NEXT: leaq (%rax,%rdi), %rax 450 ; X64-NEXT: retq 451 ; 452 ; X86-LABEL: test6: 453 ; X86: # %bb.0: # %entry 454 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 455 ; X86-NEXT: movl %eax, %ecx 456 ; X86-NEXT: shll $5, %ecx 457 ; X86-NEXT: addl %eax, %ecx 458 ; X86-NEXT: movl $33, %eax 459 ; X86-NEXT: mull {{[0-9]+}}(%esp) 460 ; X86-NEXT: addl %ecx, %edx 461 ; X86-NEXT: retl 462 entry: 463 %tmp3 = mul i64 %a, 33 464 ret i64 %tmp3 465 } 466 467 define i64 @test7(i64 %a) { 468 ; X64-LABEL: test7: 469 ; X64: # %bb.0: # %entry 470 ; X64-NEXT: movq %rdi, %rax 471 ; X64-NEXT: shlq $5, %rax 472 ; X64-NEXT: leaq (%rax,%rdi), %rax 473 ; X64-NEXT: negq %rax 474 ; X64-NEXT: retq 475 ; 476 ; X86-LABEL: test7: 477 ; X86: # %bb.0: # %entry 478 ; X86-NEXT: pushl %esi 479 ; X86-NEXT: .cfi_def_cfa_offset 8 480 ; X86-NEXT: .cfi_offset %esi, -8 481 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 482 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 483 ; X86-NEXT: movl %eax, %esi 484 ; X86-NEXT: shll $5, %esi 485 ; X86-NEXT: addl %eax, %esi 486 ; X86-NEXT: movl $-33, %edx 487 ; X86-NEXT: movl %ecx, %eax 488 ; X86-NEXT: mull %edx 489 ; X86-NEXT: subl %ecx, %edx 490 ; X86-NEXT: subl %esi, %edx 491 ; X86-NEXT: popl %esi 492 ; X86-NEXT: .cfi_def_cfa_offset 4 493 ; X86-NEXT: retl 494 entry: 495 %tmp3 = mul i64 %a, -33 496 ret i64 %tmp3 497 } 498 499 define i64 @testOverflow(i64 %a) { 500 ; X64-LABEL: testOverflow: 501 ; X64: # %bb.0: # %entry 502 ; X64-NEXT: movq %rdi, %rax 503 ; X64-NEXT: shlq $63, %rax 504 ; X64-NEXT: subq %rdi, %rax 505 ; X64-NEXT: retq 506 ; 507 ; X86-LABEL: testOverflow: 508 ; X86: # %bb.0: # %entry 509 ; X86-NEXT: pushl %esi 510 ; X86-NEXT: .cfi_def_cfa_offset 8 511 ; X86-NEXT: .cfi_offset %esi, -8 512 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 513 ; X86-NEXT: movl $-1, %edx 514 ; X86-NEXT: movl %ecx, %eax 515 ; X86-NEXT: mull %edx 516 ; X86-NEXT: movl %ecx, %esi 517 ; X86-NEXT: shll $31, %esi 518 ; X86-NEXT: subl %ecx, %esi 519 ; X86-NEXT: addl %esi, %edx 520 ; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 521 ; X86-NEXT: popl %esi 522 ; X86-NEXT: .cfi_def_cfa_offset 4 523 ; X86-NEXT: retl 524 entry: 525 %tmp3 = mul i64 %a, 9223372036854775807 526 ret i64 %tmp3 527 } 528 529 define i64 @testNegOverflow(i64 %a) { 530 ; X64-LABEL: testNegOverflow: 531 ; X64: # %bb.0: # %entry 532 ; X64-NEXT: movq %rdi, %rax 533 ; X64-NEXT: shlq $63, %rax 534 ; X64-NEXT: subq %rax, %rdi 535 ; X64-NEXT: movq %rdi, %rax 536 ; X64-NEXT: retq 537 ; 538 ; X86-LABEL: testNegOverflow: 539 ; X86: # %bb.0: # %entry 540 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 541 ; X86-NEXT: movl $1, %edx 542 ; X86-NEXT: movl %ecx, %eax 543 ; X86-NEXT: mull %edx 544 ; X86-NEXT: shll $31, %ecx 545 ; X86-NEXT: addl %ecx, %edx 546 ; X86-NEXT: addl {{[0-9]+}}(%esp), %edx 547 ; X86-NEXT: retl 548 entry: 549 %tmp3 = mul i64 %a, -9223372036854775807 550 ret i64 %tmp3 551 } 552