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