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: movl %edi, %eax 221; X64-NEXT: shll $5, %eax 222; X64-NEXT: addl %edi, %eax 223; X64-NEXT: retq 224; 225; X86-LABEL: mul33_32: 226; X86: # %bb.0: 227; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 228; X86-NEXT: movl %ecx, %eax 229; X86-NEXT: shll $5, %eax 230; X86-NEXT: addl %ecx, %eax 231; X86-NEXT: retl 232 %mul = mul i32 %A, 33 233 ret i32 %mul 234} 235 236define i32 @mul31_32(i32 %A) { 237; X64-LABEL: mul31_32: 238; X64: # %bb.0: 239; X64-NEXT: movl %edi, %eax 240; X64-NEXT: shll $5, %eax 241; X64-NEXT: subl %edi, %eax 242; X64-NEXT: retq 243; 244; X86-LABEL: mul31_32: 245; X86: # %bb.0: 246; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 247; X86-NEXT: movl %ecx, %eax 248; X86-NEXT: shll $5, %eax 249; X86-NEXT: subl %ecx, %eax 250; X86-NEXT: retl 251 %mul = mul i32 %A, 31 252 ret i32 %mul 253} 254 255define i32 @mul0_32(i32 %A) { 256; X64-LABEL: mul0_32: 257; X64: # %bb.0: 258; X64-NEXT: xorl %eax, %eax 259; X64-NEXT: retq 260; 261; X86-LABEL: mul0_32: 262; X86: # %bb.0: 263; X86-NEXT: xorl %eax, %eax 264; X86-NEXT: retl 265 %mul = mul i32 %A, 0 266 ret i32 %mul 267} 268 269define i32 @mul4294967295_32(i32 %A) { 270; X64-LABEL: mul4294967295_32: 271; X64: # %bb.0: 272; X64-NEXT: movl %edi, %eax 273; X64-NEXT: negl %eax 274; X64-NEXT: retq 275; 276; X86-LABEL: mul4294967295_32: 277; X86: # %bb.0: 278; X86-NEXT: xorl %eax, %eax 279; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 280; X86-NEXT: retl 281 %mul = mul i32 %A, 4294967295 282 ret i32 %mul 283} 284 285define i64 @mul18446744073709551615_64(i64 %A) { 286; X64-LABEL: mul18446744073709551615_64: 287; X64: # %bb.0: 288; X64-NEXT: movq %rdi, %rax 289; X64-NEXT: negq %rax 290; X64-NEXT: retq 291; 292; X86-LABEL: mul18446744073709551615_64: 293; X86: # %bb.0: 294; X86-NEXT: xorl %edx, %edx 295; X86-NEXT: xorl %eax, %eax 296; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 297; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 298; X86-NEXT: retl 299 %mul = mul i64 %A, 18446744073709551615 300 ret i64 %mul 301} 302 303define i32 @test(i32 %a) { 304; X64-LABEL: test: 305; X64: # %bb.0: # %entry 306; X64-NEXT: movl %edi, %eax 307; X64-NEXT: shll $5, %eax 308; X64-NEXT: subl %edi, %eax 309; X64-NEXT: retq 310; 311; X86-LABEL: test: 312; X86: # %bb.0: # %entry 313; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 314; X86-NEXT: movl %ecx, %eax 315; X86-NEXT: shll $5, %eax 316; X86-NEXT: subl %ecx, %eax 317; X86-NEXT: retl 318entry: 319 %tmp3 = mul i32 %a, 31 320 ret i32 %tmp3 321} 322 323define i32 @test1(i32 %a) { 324; X64-LABEL: test1: 325; X64: # %bb.0: # %entry 326; X64-NEXT: movl %edi, %eax 327; X64-NEXT: movl %edi, %ecx 328; X64-NEXT: shll $5, %ecx 329; X64-NEXT: subl %ecx, %eax 330; X64-NEXT: retq 331; 332; X86-LABEL: test1: 333; X86: # %bb.0: # %entry 334; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 335; X86-NEXT: movl %eax, %ecx 336; X86-NEXT: shll $5, %ecx 337; X86-NEXT: subl %ecx, %eax 338; X86-NEXT: retl 339entry: 340 %tmp3 = mul i32 %a, -31 341 ret i32 %tmp3 342} 343 344 345define i32 @test2(i32 %a) { 346; X64-LABEL: test2: 347; X64: # %bb.0: # %entry 348; X64-NEXT: movl %edi, %eax 349; X64-NEXT: shll $5, %eax 350; X64-NEXT: addl %edi, %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 360entry: 361 %tmp3 = mul i32 %a, 33 362 ret i32 %tmp3 363} 364 365define i32 @test3(i32 %a) { 366; X64-LABEL: test3: 367; X64: # %bb.0: # %entry 368; X64-NEXT: movl %edi, %eax 369; X64-NEXT: shll $5, %eax 370; X64-NEXT: addl %edi, %eax 371; X64-NEXT: negl %eax 372; X64-NEXT: retq 373; 374; X86-LABEL: test3: 375; X86: # %bb.0: # %entry 376; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 377; X86-NEXT: movl %ecx, %eax 378; X86-NEXT: shll $5, %eax 379; X86-NEXT: addl %ecx, %eax 380; X86-NEXT: negl %eax 381; X86-NEXT: retl 382entry: 383 %tmp3 = mul i32 %a, -33 384 ret i32 %tmp3 385} 386 387define i64 @test4(i64 %a) { 388; X64-LABEL: test4: 389; X64: # %bb.0: # %entry 390; X64-NEXT: movq %rdi, %rax 391; X64-NEXT: shlq $5, %rax 392; X64-NEXT: subq %rdi, %rax 393; X64-NEXT: retq 394; 395; X86-LABEL: test4: 396; X86: # %bb.0: # %entry 397; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 398; X86-NEXT: movl %eax, %ecx 399; X86-NEXT: shll $5, %ecx 400; X86-NEXT: subl %eax, %ecx 401; X86-NEXT: movl $31, %eax 402; X86-NEXT: mull {{[0-9]+}}(%esp) 403; X86-NEXT: addl %ecx, %edx 404; X86-NEXT: retl 405entry: 406 %tmp3 = mul i64 %a, 31 407 ret i64 %tmp3 408} 409 410define i64 @test5(i64 %a) { 411; X64-LABEL: test5: 412; X64: # %bb.0: # %entry 413; X64-NEXT: movq %rdi, %rax 414; X64-NEXT: movq %rdi, %rcx 415; X64-NEXT: shlq $5, %rcx 416; X64-NEXT: subq %rcx, %rax 417; X64-NEXT: retq 418; 419; X86-LABEL: test5: 420; X86: # %bb.0: # %entry 421; X86-NEXT: pushl %esi 422; X86-NEXT: .cfi_def_cfa_offset 8 423; X86-NEXT: .cfi_offset %esi, -8 424; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 425; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 426; X86-NEXT: movl %esi, %eax 427; X86-NEXT: shll $5, %eax 428; X86-NEXT: subl %eax, %esi 429; X86-NEXT: movl $-31, %edx 430; X86-NEXT: movl %ecx, %eax 431; X86-NEXT: mull %edx 432; X86-NEXT: subl %ecx, %edx 433; X86-NEXT: addl %esi, %edx 434; X86-NEXT: popl %esi 435; X86-NEXT: .cfi_def_cfa_offset 4 436; X86-NEXT: retl 437entry: 438 %tmp3 = mul i64 %a, -31 439 ret i64 %tmp3 440} 441 442 443define i64 @test6(i64 %a) { 444; X64-LABEL: test6: 445; X64: # %bb.0: # %entry 446; X64-NEXT: movq %rdi, %rax 447; X64-NEXT: shlq $5, %rax 448; X64-NEXT: addq %rdi, %rax 449; X64-NEXT: retq 450; 451; X86-LABEL: test6: 452; X86: # %bb.0: # %entry 453; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 454; X86-NEXT: movl %eax, %ecx 455; X86-NEXT: shll $5, %ecx 456; X86-NEXT: addl %eax, %ecx 457; X86-NEXT: movl $33, %eax 458; X86-NEXT: mull {{[0-9]+}}(%esp) 459; X86-NEXT: addl %ecx, %edx 460; X86-NEXT: retl 461entry: 462 %tmp3 = mul i64 %a, 33 463 ret i64 %tmp3 464} 465 466define i64 @test7(i64 %a) { 467; X64-LABEL: test7: 468; X64: # %bb.0: # %entry 469; X64-NEXT: movq %rdi, %rax 470; X64-NEXT: shlq $5, %rax 471; X64-NEXT: addq %rdi, %rax 472; X64-NEXT: negq %rax 473; X64-NEXT: retq 474; 475; X86-LABEL: test7: 476; X86: # %bb.0: # %entry 477; X86-NEXT: pushl %esi 478; X86-NEXT: .cfi_def_cfa_offset 8 479; X86-NEXT: .cfi_offset %esi, -8 480; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 481; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 482; X86-NEXT: movl %eax, %esi 483; X86-NEXT: shll $5, %esi 484; X86-NEXT: addl %eax, %esi 485; X86-NEXT: movl $-33, %edx 486; X86-NEXT: movl %ecx, %eax 487; X86-NEXT: mull %edx 488; X86-NEXT: subl %ecx, %edx 489; X86-NEXT: subl %esi, %edx 490; X86-NEXT: popl %esi 491; X86-NEXT: .cfi_def_cfa_offset 4 492; X86-NEXT: retl 493entry: 494 %tmp3 = mul i64 %a, -33 495 ret i64 %tmp3 496} 497 498define i64 @testOverflow(i64 %a) { 499; X64-LABEL: testOverflow: 500; X64: # %bb.0: # %entry 501; X64-NEXT: movq %rdi, %rax 502; X64-NEXT: shlq $63, %rax 503; X64-NEXT: subq %rdi, %rax 504; X64-NEXT: retq 505; 506; X86-LABEL: testOverflow: 507; X86: # %bb.0: # %entry 508; X86-NEXT: pushl %esi 509; X86-NEXT: .cfi_def_cfa_offset 8 510; X86-NEXT: .cfi_offset %esi, -8 511; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 512; X86-NEXT: movl $-1, %edx 513; X86-NEXT: movl %ecx, %eax 514; X86-NEXT: mull %edx 515; X86-NEXT: movl %ecx, %esi 516; X86-NEXT: shll $31, %esi 517; X86-NEXT: subl %ecx, %esi 518; X86-NEXT: addl %esi, %edx 519; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 520; X86-NEXT: popl %esi 521; X86-NEXT: .cfi_def_cfa_offset 4 522; X86-NEXT: retl 523entry: 524 %tmp3 = mul i64 %a, 9223372036854775807 525 ret i64 %tmp3 526} 527 528define i64 @testNegOverflow(i64 %a) { 529; X64-LABEL: testNegOverflow: 530; X64: # %bb.0: # %entry 531; X64-NEXT: movq %rdi, %rax 532; X64-NEXT: shlq $63, %rax 533; X64-NEXT: addq %rdi, %rax 534; X64-NEXT: retq 535; 536; X86-LABEL: testNegOverflow: 537; X86: # %bb.0: # %entry 538; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 539; X86-NEXT: movl %eax, %edx 540; X86-NEXT: shll $31, %edx 541; X86-NEXT: addl {{[0-9]+}}(%esp), %edx 542; X86-NEXT: retl 543entry: 544 %tmp3 = mul i64 %a, -9223372036854775807 545 ret i64 %tmp3 546} 547