1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefix=SDAG 3; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort=1 < %s | FileCheck %s --check-prefix=FAST 4; RUN: llc -mtriple=x86_64-darwin-unknown -mcpu=knl < %s | FileCheck %s --check-prefix=KNL 5 6define {i64, i1} @t1() nounwind { 7; SDAG-LABEL: t1: 8; SDAG: ## BB#0: 9; SDAG-NEXT: movl $8, %ecx 10; SDAG-NEXT: movl $9, %eax 11; SDAG-NEXT: mulq %rcx 12; SDAG-NEXT: seto %dl 13; SDAG-NEXT: retq 14; 15; FAST-LABEL: t1: 16; FAST: ## BB#0: 17; FAST-NEXT: movl $8, %ecx 18; FAST-NEXT: movl $9, %eax 19; FAST-NEXT: mulq %rcx 20; FAST-NEXT: seto %dl 21; FAST-NEXT: retq 22; 23; KNL-LABEL: t1: 24; KNL: ## BB#0: 25; KNL-NEXT: movl $8, %ecx 26; KNL-NEXT: movl $9, %eax 27; KNL-NEXT: mulq %rcx 28; KNL-NEXT: seto %dl 29; KNL-NEXT: retq 30 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 8) 31 ret {i64, i1} %1 32} 33 34define {i64, i1} @t2() nounwind { 35; SDAG-LABEL: t2: 36; SDAG: ## BB#0: 37; SDAG-NEXT: xorl %ecx, %ecx 38; SDAG-NEXT: movl $9, %eax 39; SDAG-NEXT: mulq %rcx 40; SDAG-NEXT: seto %dl 41; SDAG-NEXT: retq 42; 43; FAST-LABEL: t2: 44; FAST: ## BB#0: 45; FAST-NEXT: xorl %ecx, %ecx 46; FAST-NEXT: movl $9, %eax 47; FAST-NEXT: mulq %rcx 48; FAST-NEXT: seto %dl 49; FAST-NEXT: retq 50; 51; KNL-LABEL: t2: 52; KNL: ## BB#0: 53; KNL-NEXT: xorl %ecx, %ecx 54; KNL-NEXT: movl $9, %eax 55; KNL-NEXT: mulq %rcx 56; KNL-NEXT: seto %dl 57; KNL-NEXT: retq 58 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 0) 59 ret {i64, i1} %1 60} 61 62define {i64, i1} @t3() nounwind { 63; SDAG-LABEL: t3: 64; SDAG: ## BB#0: 65; SDAG-NEXT: movq $-1, %rcx 66; SDAG-NEXT: movl $9, %eax 67; SDAG-NEXT: mulq %rcx 68; SDAG-NEXT: seto %dl 69; SDAG-NEXT: retq 70; 71; FAST-LABEL: t3: 72; FAST: ## BB#0: 73; FAST-NEXT: movq $-1, %rcx 74; FAST-NEXT: movl $9, %eax 75; FAST-NEXT: mulq %rcx 76; FAST-NEXT: seto %dl 77; FAST-NEXT: retq 78; 79; KNL-LABEL: t3: 80; KNL: ## BB#0: 81; KNL-NEXT: movq $-1, %rcx 82; KNL-NEXT: movl $9, %eax 83; KNL-NEXT: mulq %rcx 84; KNL-NEXT: seto %dl 85; KNL-NEXT: retq 86 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 -1) 87 ret {i64, i1} %1 88} 89 90; SMULO 91define zeroext i1 @smuloi8(i8 %v1, i8 %v2, i8* %res) { 92; SDAG-LABEL: smuloi8: 93; SDAG: ## BB#0: 94; SDAG-NEXT: movl %edi, %eax 95; SDAG-NEXT: imulb %sil 96; SDAG-NEXT: seto %cl 97; SDAG-NEXT: movb %al, (%rdx) 98; SDAG-NEXT: movl %ecx, %eax 99; SDAG-NEXT: retq 100; 101; FAST-LABEL: smuloi8: 102; FAST: ## BB#0: 103; FAST-NEXT: movl %edi, %eax 104; FAST-NEXT: imulb %sil 105; FAST-NEXT: seto %cl 106; FAST-NEXT: movb %al, (%rdx) 107; FAST-NEXT: andb $1, %cl 108; FAST-NEXT: movzbl %cl, %eax 109; FAST-NEXT: retq 110; 111; KNL-LABEL: smuloi8: 112; KNL: ## BB#0: 113; KNL-NEXT: movl %edi, %eax 114; KNL-NEXT: imulb %sil 115; KNL-NEXT: seto %cl 116; KNL-NEXT: movb %al, (%rdx) 117; KNL-NEXT: movl %ecx, %eax 118; KNL-NEXT: retq 119 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2) 120 %val = extractvalue {i8, i1} %t, 0 121 %obit = extractvalue {i8, i1} %t, 1 122 store i8 %val, i8* %res 123 ret i1 %obit 124} 125 126define zeroext i1 @smuloi16(i16 %v1, i16 %v2, i16* %res) { 127; SDAG-LABEL: smuloi16: 128; SDAG: ## BB#0: 129; SDAG-NEXT: imulw %si, %di 130; SDAG-NEXT: seto %al 131; SDAG-NEXT: movw %di, (%rdx) 132; SDAG-NEXT: retq 133; 134; FAST-LABEL: smuloi16: 135; FAST: ## BB#0: 136; FAST-NEXT: imulw %si, %di 137; FAST-NEXT: seto %al 138; FAST-NEXT: movw %di, (%rdx) 139; FAST-NEXT: andb $1, %al 140; FAST-NEXT: movzbl %al, %eax 141; FAST-NEXT: retq 142; 143; KNL-LABEL: smuloi16: 144; KNL: ## BB#0: 145; KNL-NEXT: imulw %si, %di 146; KNL-NEXT: seto %al 147; KNL-NEXT: movw %di, (%rdx) 148; KNL-NEXT: retq 149 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2) 150 %val = extractvalue {i16, i1} %t, 0 151 %obit = extractvalue {i16, i1} %t, 1 152 store i16 %val, i16* %res 153 ret i1 %obit 154} 155 156define zeroext i1 @smuloi32(i32 %v1, i32 %v2, i32* %res) { 157; SDAG-LABEL: smuloi32: 158; SDAG: ## BB#0: 159; SDAG-NEXT: imull %esi, %edi 160; SDAG-NEXT: seto %al 161; SDAG-NEXT: movl %edi, (%rdx) 162; SDAG-NEXT: retq 163; 164; FAST-LABEL: smuloi32: 165; FAST: ## BB#0: 166; FAST-NEXT: imull %esi, %edi 167; FAST-NEXT: seto %al 168; FAST-NEXT: movl %edi, (%rdx) 169; FAST-NEXT: andb $1, %al 170; FAST-NEXT: movzbl %al, %eax 171; FAST-NEXT: retq 172; 173; KNL-LABEL: smuloi32: 174; KNL: ## BB#0: 175; KNL-NEXT: imull %esi, %edi 176; KNL-NEXT: seto %al 177; KNL-NEXT: movl %edi, (%rdx) 178; KNL-NEXT: retq 179 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 180 %val = extractvalue {i32, i1} %t, 0 181 %obit = extractvalue {i32, i1} %t, 1 182 store i32 %val, i32* %res 183 ret i1 %obit 184} 185 186define zeroext i1 @smuloi64(i64 %v1, i64 %v2, i64* %res) { 187; SDAG-LABEL: smuloi64: 188; SDAG: ## BB#0: 189; SDAG-NEXT: imulq %rsi, %rdi 190; SDAG-NEXT: seto %al 191; SDAG-NEXT: movq %rdi, (%rdx) 192; SDAG-NEXT: retq 193; 194; FAST-LABEL: smuloi64: 195; FAST: ## BB#0: 196; FAST-NEXT: imulq %rsi, %rdi 197; FAST-NEXT: seto %al 198; FAST-NEXT: movq %rdi, (%rdx) 199; FAST-NEXT: andb $1, %al 200; FAST-NEXT: movzbl %al, %eax 201; FAST-NEXT: retq 202; 203; KNL-LABEL: smuloi64: 204; KNL: ## BB#0: 205; KNL-NEXT: imulq %rsi, %rdi 206; KNL-NEXT: seto %al 207; KNL-NEXT: movq %rdi, (%rdx) 208; KNL-NEXT: retq 209 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 210 %val = extractvalue {i64, i1} %t, 0 211 %obit = extractvalue {i64, i1} %t, 1 212 store i64 %val, i64* %res 213 ret i1 %obit 214} 215 216; UMULO 217define zeroext i1 @umuloi8(i8 %v1, i8 %v2, i8* %res) { 218; SDAG-LABEL: umuloi8: 219; SDAG: ## BB#0: 220; SDAG-NEXT: movl %edi, %eax 221; SDAG-NEXT: mulb %sil 222; SDAG-NEXT: seto %cl 223; SDAG-NEXT: movb %al, (%rdx) 224; SDAG-NEXT: movl %ecx, %eax 225; SDAG-NEXT: retq 226; 227; FAST-LABEL: umuloi8: 228; FAST: ## BB#0: 229; FAST-NEXT: movl %edi, %eax 230; FAST-NEXT: mulb %sil 231; FAST-NEXT: seto %cl 232; FAST-NEXT: movb %al, (%rdx) 233; FAST-NEXT: andb $1, %cl 234; FAST-NEXT: movzbl %cl, %eax 235; FAST-NEXT: retq 236; 237; KNL-LABEL: umuloi8: 238; KNL: ## BB#0: 239; KNL-NEXT: movl %edi, %eax 240; KNL-NEXT: mulb %sil 241; KNL-NEXT: seto %cl 242; KNL-NEXT: movb %al, (%rdx) 243; KNL-NEXT: movl %ecx, %eax 244; KNL-NEXT: retq 245 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2) 246 %val = extractvalue {i8, i1} %t, 0 247 %obit = extractvalue {i8, i1} %t, 1 248 store i8 %val, i8* %res 249 ret i1 %obit 250} 251 252define zeroext i1 @umuloi16(i16 %v1, i16 %v2, i16* %res) { 253; SDAG-LABEL: umuloi16: 254; SDAG: ## BB#0: 255; SDAG-NEXT: movq %rdx, %rcx 256; SDAG-NEXT: movl %edi, %eax 257; SDAG-NEXT: mulw %si 258; SDAG-NEXT: seto %dl 259; SDAG-NEXT: movw %ax, (%rcx) 260; SDAG-NEXT: movl %edx, %eax 261; SDAG-NEXT: retq 262; 263; FAST-LABEL: umuloi16: 264; FAST: ## BB#0: 265; FAST-NEXT: movq %rdx, %rcx 266; FAST-NEXT: movl %edi, %eax 267; FAST-NEXT: mulw %si 268; FAST-NEXT: seto %dl 269; FAST-NEXT: movw %ax, (%rcx) 270; FAST-NEXT: andb $1, %dl 271; FAST-NEXT: movzbl %dl, %eax 272; FAST-NEXT: retq 273; 274; KNL-LABEL: umuloi16: 275; KNL: ## BB#0: 276; KNL-NEXT: movq %rdx, %rcx 277; KNL-NEXT: movl %edi, %eax 278; KNL-NEXT: mulw %si 279; KNL-NEXT: seto %dl 280; KNL-NEXT: movw %ax, (%rcx) 281; KNL-NEXT: movl %edx, %eax 282; KNL-NEXT: retq 283 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2) 284 %val = extractvalue {i16, i1} %t, 0 285 %obit = extractvalue {i16, i1} %t, 1 286 store i16 %val, i16* %res 287 ret i1 %obit 288} 289 290define zeroext i1 @umuloi32(i32 %v1, i32 %v2, i32* %res) { 291; SDAG-LABEL: umuloi32: 292; SDAG: ## BB#0: 293; SDAG-NEXT: movq %rdx, %rcx 294; SDAG-NEXT: movl %edi, %eax 295; SDAG-NEXT: mull %esi 296; SDAG-NEXT: seto %dl 297; SDAG-NEXT: movl %eax, (%rcx) 298; SDAG-NEXT: movl %edx, %eax 299; SDAG-NEXT: retq 300; 301; FAST-LABEL: umuloi32: 302; FAST: ## BB#0: 303; FAST-NEXT: movq %rdx, %rcx 304; FAST-NEXT: movl %edi, %eax 305; FAST-NEXT: mull %esi 306; FAST-NEXT: seto %dl 307; FAST-NEXT: movl %eax, (%rcx) 308; FAST-NEXT: andb $1, %dl 309; FAST-NEXT: movzbl %dl, %eax 310; FAST-NEXT: retq 311; 312; KNL-LABEL: umuloi32: 313; KNL: ## BB#0: 314; KNL-NEXT: movq %rdx, %rcx 315; KNL-NEXT: movl %edi, %eax 316; KNL-NEXT: mull %esi 317; KNL-NEXT: seto %dl 318; KNL-NEXT: movl %eax, (%rcx) 319; KNL-NEXT: movl %edx, %eax 320; KNL-NEXT: retq 321 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 322 %val = extractvalue {i32, i1} %t, 0 323 %obit = extractvalue {i32, i1} %t, 1 324 store i32 %val, i32* %res 325 ret i1 %obit 326} 327 328define zeroext i1 @umuloi64(i64 %v1, i64 %v2, i64* %res) { 329; SDAG-LABEL: umuloi64: 330; SDAG: ## BB#0: 331; SDAG-NEXT: movq %rdx, %rcx 332; SDAG-NEXT: movq %rdi, %rax 333; SDAG-NEXT: mulq %rsi 334; SDAG-NEXT: seto %dl 335; SDAG-NEXT: movq %rax, (%rcx) 336; SDAG-NEXT: movl %edx, %eax 337; SDAG-NEXT: retq 338; 339; FAST-LABEL: umuloi64: 340; FAST: ## BB#0: 341; FAST-NEXT: movq %rdx, %rcx 342; FAST-NEXT: movq %rdi, %rax 343; FAST-NEXT: mulq %rsi 344; FAST-NEXT: seto %dl 345; FAST-NEXT: movq %rax, (%rcx) 346; FAST-NEXT: andb $1, %dl 347; FAST-NEXT: movzbl %dl, %eax 348; FAST-NEXT: retq 349; 350; KNL-LABEL: umuloi64: 351; KNL: ## BB#0: 352; KNL-NEXT: movq %rdx, %rcx 353; KNL-NEXT: movq %rdi, %rax 354; KNL-NEXT: mulq %rsi 355; KNL-NEXT: seto %dl 356; KNL-NEXT: movq %rax, (%rcx) 357; KNL-NEXT: movl %edx, %eax 358; KNL-NEXT: retq 359 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 360 %val = extractvalue {i64, i1} %t, 0 361 %obit = extractvalue {i64, i1} %t, 1 362 store i64 %val, i64* %res 363 ret i1 %obit 364} 365 366; 367; Check the use of the overflow bit in combination with a select instruction. 368; 369define i32 @smuloselecti32(i32 %v1, i32 %v2) { 370; SDAG-LABEL: smuloselecti32: 371; SDAG: ## BB#0: 372; SDAG-NEXT: movl %edi, %eax 373; SDAG-NEXT: imull %esi, %eax 374; SDAG-NEXT: cmovol %edi, %esi 375; SDAG-NEXT: movl %esi, %eax 376; SDAG-NEXT: retq 377; 378; FAST-LABEL: smuloselecti32: 379; FAST: ## BB#0: 380; FAST-NEXT: movl %edi, %eax 381; FAST-NEXT: imull %esi, %eax 382; FAST-NEXT: cmovol %edi, %esi 383; FAST-NEXT: movl %esi, %eax 384; FAST-NEXT: retq 385; 386; KNL-LABEL: smuloselecti32: 387; KNL: ## BB#0: 388; KNL-NEXT: movl %edi, %eax 389; KNL-NEXT: imull %esi, %eax 390; KNL-NEXT: cmovol %edi, %esi 391; KNL-NEXT: movl %esi, %eax 392; KNL-NEXT: retq 393 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 394 %obit = extractvalue {i32, i1} %t, 1 395 %ret = select i1 %obit, i32 %v1, i32 %v2 396 ret i32 %ret 397} 398 399define i64 @smuloselecti64(i64 %v1, i64 %v2) { 400; SDAG-LABEL: smuloselecti64: 401; SDAG: ## BB#0: 402; SDAG-NEXT: movq %rdi, %rax 403; SDAG-NEXT: imulq %rsi, %rax 404; SDAG-NEXT: cmovoq %rdi, %rsi 405; SDAG-NEXT: movq %rsi, %rax 406; SDAG-NEXT: retq 407; 408; FAST-LABEL: smuloselecti64: 409; FAST: ## BB#0: 410; FAST-NEXT: movq %rdi, %rax 411; FAST-NEXT: imulq %rsi, %rax 412; FAST-NEXT: cmovoq %rdi, %rsi 413; FAST-NEXT: movq %rsi, %rax 414; FAST-NEXT: retq 415; 416; KNL-LABEL: smuloselecti64: 417; KNL: ## BB#0: 418; KNL-NEXT: movq %rdi, %rax 419; KNL-NEXT: imulq %rsi, %rax 420; KNL-NEXT: cmovoq %rdi, %rsi 421; KNL-NEXT: movq %rsi, %rax 422; KNL-NEXT: retq 423 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 424 %obit = extractvalue {i64, i1} %t, 1 425 %ret = select i1 %obit, i64 %v1, i64 %v2 426 ret i64 %ret 427} 428 429define i32 @umuloselecti32(i32 %v1, i32 %v2) { 430; SDAG-LABEL: umuloselecti32: 431; SDAG: ## BB#0: 432; SDAG-NEXT: movl %edi, %eax 433; SDAG-NEXT: mull %esi 434; SDAG-NEXT: cmovol %edi, %esi 435; SDAG-NEXT: movl %esi, %eax 436; SDAG-NEXT: retq 437; 438; FAST-LABEL: umuloselecti32: 439; FAST: ## BB#0: 440; FAST-NEXT: movl %edi, %eax 441; FAST-NEXT: mull %esi 442; FAST-NEXT: cmovol %edi, %esi 443; FAST-NEXT: movl %esi, %eax 444; FAST-NEXT: retq 445; 446; KNL-LABEL: umuloselecti32: 447; KNL: ## BB#0: 448; KNL-NEXT: movl %edi, %eax 449; KNL-NEXT: mull %esi 450; KNL-NEXT: cmovol %edi, %esi 451; KNL-NEXT: movl %esi, %eax 452; KNL-NEXT: retq 453 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 454 %obit = extractvalue {i32, i1} %t, 1 455 %ret = select i1 %obit, i32 %v1, i32 %v2 456 ret i32 %ret 457} 458 459define i64 @umuloselecti64(i64 %v1, i64 %v2) { 460; SDAG-LABEL: umuloselecti64: 461; SDAG: ## BB#0: 462; SDAG-NEXT: movq %rdi, %rax 463; SDAG-NEXT: mulq %rsi 464; SDAG-NEXT: cmovoq %rdi, %rsi 465; SDAG-NEXT: movq %rsi, %rax 466; SDAG-NEXT: retq 467; 468; FAST-LABEL: umuloselecti64: 469; FAST: ## BB#0: 470; FAST-NEXT: movq %rdi, %rax 471; FAST-NEXT: mulq %rsi 472; FAST-NEXT: cmovoq %rdi, %rsi 473; FAST-NEXT: movq %rsi, %rax 474; FAST-NEXT: retq 475; 476; KNL-LABEL: umuloselecti64: 477; KNL: ## BB#0: 478; KNL-NEXT: movq %rdi, %rax 479; KNL-NEXT: mulq %rsi 480; KNL-NEXT: cmovoq %rdi, %rsi 481; KNL-NEXT: movq %rsi, %rax 482; KNL-NEXT: retq 483 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 484 %obit = extractvalue {i64, i1} %t, 1 485 %ret = select i1 %obit, i64 %v1, i64 %v2 486 ret i64 %ret 487} 488 489; 490; Check the use of the overflow bit in combination with a branch instruction. 491; 492define zeroext i1 @smulobri32(i32 %v1, i32 %v2) { 493; SDAG-LABEL: smulobri32: 494; SDAG: ## BB#0: 495; SDAG-NEXT: imull %esi, %edi 496; SDAG-NEXT: jo LBB15_1 497; SDAG-NEXT: ## BB#2: ## %continue 498; SDAG-NEXT: movb $1, %al 499; SDAG-NEXT: retq 500; SDAG-NEXT: LBB15_1: ## %overflow 501; SDAG-NEXT: xorl %eax, %eax 502; SDAG-NEXT: retq 503; 504; FAST-LABEL: smulobri32: 505; FAST: ## BB#0: 506; FAST-NEXT: imull %esi, %edi 507; FAST-NEXT: jo LBB15_1 508; FAST-NEXT: ## BB#2: ## %continue 509; FAST-NEXT: movb $1, %al 510; FAST-NEXT: andb $1, %al 511; FAST-NEXT: movzbl %al, %eax 512; FAST-NEXT: retq 513; FAST-NEXT: LBB15_1: ## %overflow 514; FAST-NEXT: xorl %eax, %eax 515; FAST-NEXT: andb $1, %al 516; FAST-NEXT: movzbl %al, %eax 517; FAST-NEXT: retq 518; 519; KNL-LABEL: smulobri32: 520; KNL: ## BB#0: 521; KNL-NEXT: imull %esi, %edi 522; KNL-NEXT: jo LBB15_1 523; KNL-NEXT: ## BB#2: ## %continue 524; KNL-NEXT: movb $1, %al 525; KNL-NEXT: retq 526; KNL-NEXT: LBB15_1: ## %overflow 527; KNL-NEXT: xorl %eax, %eax 528; KNL-NEXT: retq 529 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 530 %val = extractvalue {i32, i1} %t, 0 531 %obit = extractvalue {i32, i1} %t, 1 532 br i1 %obit, label %overflow, label %continue, !prof !0 533 534overflow: 535 ret i1 false 536 537continue: 538 ret i1 true 539} 540 541define zeroext i1 @smulobri64(i64 %v1, i64 %v2) { 542; SDAG-LABEL: smulobri64: 543; SDAG: ## BB#0: 544; SDAG-NEXT: imulq %rsi, %rdi 545; SDAG-NEXT: jo LBB16_1 546; SDAG-NEXT: ## BB#2: ## %continue 547; SDAG-NEXT: movb $1, %al 548; SDAG-NEXT: retq 549; SDAG-NEXT: LBB16_1: ## %overflow 550; SDAG-NEXT: xorl %eax, %eax 551; SDAG-NEXT: retq 552; 553; FAST-LABEL: smulobri64: 554; FAST: ## BB#0: 555; FAST-NEXT: imulq %rsi, %rdi 556; FAST-NEXT: jo LBB16_1 557; FAST-NEXT: ## BB#2: ## %continue 558; FAST-NEXT: movb $1, %al 559; FAST-NEXT: andb $1, %al 560; FAST-NEXT: movzbl %al, %eax 561; FAST-NEXT: retq 562; FAST-NEXT: LBB16_1: ## %overflow 563; FAST-NEXT: xorl %eax, %eax 564; FAST-NEXT: andb $1, %al 565; FAST-NEXT: movzbl %al, %eax 566; FAST-NEXT: retq 567; 568; KNL-LABEL: smulobri64: 569; KNL: ## BB#0: 570; KNL-NEXT: imulq %rsi, %rdi 571; KNL-NEXT: jo LBB16_1 572; KNL-NEXT: ## BB#2: ## %continue 573; KNL-NEXT: movb $1, %al 574; KNL-NEXT: retq 575; KNL-NEXT: LBB16_1: ## %overflow 576; KNL-NEXT: xorl %eax, %eax 577; KNL-NEXT: retq 578 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 579 %val = extractvalue {i64, i1} %t, 0 580 %obit = extractvalue {i64, i1} %t, 1 581 br i1 %obit, label %overflow, label %continue, !prof !0 582 583overflow: 584 ret i1 false 585 586continue: 587 ret i1 true 588} 589 590define zeroext i1 @umulobri32(i32 %v1, i32 %v2) { 591; SDAG-LABEL: umulobri32: 592; SDAG: ## BB#0: 593; SDAG-NEXT: movl %edi, %eax 594; SDAG-NEXT: mull %esi 595; SDAG-NEXT: jo LBB17_1 596; SDAG-NEXT: ## BB#2: ## %continue 597; SDAG-NEXT: movb $1, %al 598; SDAG-NEXT: retq 599; SDAG-NEXT: LBB17_1: ## %overflow 600; SDAG-NEXT: xorl %eax, %eax 601; SDAG-NEXT: retq 602; 603; FAST-LABEL: umulobri32: 604; FAST: ## BB#0: 605; FAST-NEXT: movl %edi, %eax 606; FAST-NEXT: mull %esi 607; FAST-NEXT: jo LBB17_1 608; FAST-NEXT: ## BB#2: ## %continue 609; FAST-NEXT: movb $1, %al 610; FAST-NEXT: andb $1, %al 611; FAST-NEXT: movzbl %al, %eax 612; FAST-NEXT: retq 613; FAST-NEXT: LBB17_1: ## %overflow 614; FAST-NEXT: xorl %eax, %eax 615; FAST-NEXT: andb $1, %al 616; FAST-NEXT: movzbl %al, %eax 617; FAST-NEXT: retq 618; 619; KNL-LABEL: umulobri32: 620; KNL: ## BB#0: 621; KNL-NEXT: movl %edi, %eax 622; KNL-NEXT: mull %esi 623; KNL-NEXT: jo LBB17_1 624; KNL-NEXT: ## BB#2: ## %continue 625; KNL-NEXT: movb $1, %al 626; KNL-NEXT: retq 627; KNL-NEXT: LBB17_1: ## %overflow 628; KNL-NEXT: xorl %eax, %eax 629; KNL-NEXT: retq 630 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 631 %val = extractvalue {i32, i1} %t, 0 632 %obit = extractvalue {i32, i1} %t, 1 633 br i1 %obit, label %overflow, label %continue, !prof !0 634 635overflow: 636 ret i1 false 637 638continue: 639 ret i1 true 640} 641 642define zeroext i1 @umulobri64(i64 %v1, i64 %v2) { 643; SDAG-LABEL: umulobri64: 644; SDAG: ## BB#0: 645; SDAG-NEXT: movq %rdi, %rax 646; SDAG-NEXT: mulq %rsi 647; SDAG-NEXT: jo LBB18_1 648; SDAG-NEXT: ## BB#2: ## %continue 649; SDAG-NEXT: movb $1, %al 650; SDAG-NEXT: retq 651; SDAG-NEXT: LBB18_1: ## %overflow 652; SDAG-NEXT: xorl %eax, %eax 653; SDAG-NEXT: retq 654; 655; FAST-LABEL: umulobri64: 656; FAST: ## BB#0: 657; FAST-NEXT: movq %rdi, %rax 658; FAST-NEXT: mulq %rsi 659; FAST-NEXT: jo LBB18_1 660; FAST-NEXT: ## BB#2: ## %continue 661; FAST-NEXT: movb $1, %al 662; FAST-NEXT: andb $1, %al 663; FAST-NEXT: movzbl %al, %eax 664; FAST-NEXT: retq 665; FAST-NEXT: LBB18_1: ## %overflow 666; FAST-NEXT: xorl %eax, %eax 667; FAST-NEXT: andb $1, %al 668; FAST-NEXT: movzbl %al, %eax 669; FAST-NEXT: retq 670; 671; KNL-LABEL: umulobri64: 672; KNL: ## BB#0: 673; KNL-NEXT: movq %rdi, %rax 674; KNL-NEXT: mulq %rsi 675; KNL-NEXT: jo LBB18_1 676; KNL-NEXT: ## BB#2: ## %continue 677; KNL-NEXT: movb $1, %al 678; KNL-NEXT: retq 679; KNL-NEXT: LBB18_1: ## %overflow 680; KNL-NEXT: xorl %eax, %eax 681; KNL-NEXT: retq 682 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 683 %val = extractvalue {i64, i1} %t, 0 684 %obit = extractvalue {i64, i1} %t, 1 685 br i1 %obit, label %overflow, label %continue, !prof !0 686 687overflow: 688 ret i1 false 689 690continue: 691 ret i1 true 692} 693 694define i1 @bug27873(i64 %c1, i1 %c2) { 695; SDAG-LABEL: bug27873: 696; SDAG: ## BB#0: 697; SDAG-NEXT: movl $160, %ecx 698; SDAG-NEXT: movq %rdi, %rax 699; SDAG-NEXT: mulq %rcx 700; SDAG-NEXT: seto %al 701; SDAG-NEXT: orb %sil, %al 702; SDAG-NEXT: retq 703; 704; FAST-LABEL: bug27873: 705; FAST: ## BB#0: 706; FAST-NEXT: movl $160, %ecx 707; FAST-NEXT: movq %rdi, %rax 708; FAST-NEXT: mulq %rcx 709; FAST-NEXT: seto %al 710; FAST-NEXT: orb %sil, %al 711; FAST-NEXT: retq 712; 713; KNL-LABEL: bug27873: 714; KNL: ## BB#0: 715; KNL-NEXT: andl $1, %esi 716; KNL-NEXT: kmovw %esi, %k0 717; KNL-NEXT: movl $160, %ecx 718; KNL-NEXT: movq %rdi, %rax 719; KNL-NEXT: mulq %rcx 720; KNL-NEXT: seto %al 721; KNL-NEXT: andl $1, %eax 722; KNL-NEXT: kmovw %eax, %k1 723; KNL-NEXT: korw %k1, %k0, %k0 724; KNL-NEXT: kmovw %k0, %eax 725; KNL-NEXT: ## kill: %AL<def> %AL<kill> %EAX<kill> 726; KNL-NEXT: retq 727 %mul = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %c1, i64 160) 728 %mul.overflow = extractvalue { i64, i1 } %mul, 1 729 %x1 = or i1 %c2, %mul.overflow 730 ret i1 %x1 731} 732 733declare {i8, i1} @llvm.smul.with.overflow.i8 (i8, i8 ) nounwind readnone 734declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone 735declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone 736declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone 737declare {i8, i1} @llvm.umul.with.overflow.i8 (i8, i8 ) nounwind readnone 738declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone 739declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone 740declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone 741 742!0 = !{!"branch_weights", i32 0, i32 2147483647} 743