1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -disable-peephole -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefixes=CHECK,SDAG 3; RUN: llc -disable-peephole -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort=1 < %s | FileCheck %s --check-prefixes=CHECK,FAST 4; RUN: llc -disable-peephole -mtriple=x86_64-darwin-unknown -mcpu=knl < %s | FileCheck %s --check-prefixes=CHECK,SDAG 5 6define {i64, i1} @t1() nounwind { 7; CHECK-LABEL: t1: 8; CHECK: ## %bb.0: 9; CHECK-NEXT: movl $8, %ecx 10; CHECK-NEXT: movl $9, %eax 11; CHECK-NEXT: mulq %rcx 12; CHECK-NEXT: seto %dl 13; CHECK-NEXT: retq 14 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 8) 15 ret {i64, i1} %1 16} 17 18define {i64, i1} @t2() nounwind { 19; CHECK-LABEL: t2: 20; CHECK: ## %bb.0: 21; CHECK-NEXT: xorl %eax, %eax 22; CHECK-NEXT: xorl %edx, %edx 23; CHECK-NEXT: retq 24 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 0) 25 ret {i64, i1} %1 26} 27 28define {i64, i1} @t3() nounwind { 29; CHECK-LABEL: t3: 30; CHECK: ## %bb.0: 31; CHECK-NEXT: movq $-1, %rcx 32; CHECK-NEXT: movl $9, %eax 33; CHECK-NEXT: mulq %rcx 34; CHECK-NEXT: seto %dl 35; CHECK-NEXT: retq 36 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 -1) 37 ret {i64, i1} %1 38} 39 40; SMULO 41define zeroext i1 @smuloi8(i8 %v1, i8 %v2, i8* %res) { 42; SDAG-LABEL: smuloi8: 43; SDAG: ## %bb.0: 44; SDAG-NEXT: movl %edi, %eax 45; SDAG-NEXT: ## kill: def $al killed $al killed $eax 46; SDAG-NEXT: imulb %sil 47; SDAG-NEXT: seto %cl 48; SDAG-NEXT: movb %al, (%rdx) 49; SDAG-NEXT: movl %ecx, %eax 50; SDAG-NEXT: retq 51; 52; FAST-LABEL: smuloi8: 53; FAST: ## %bb.0: 54; FAST-NEXT: movl %edi, %eax 55; FAST-NEXT: ## kill: def $al killed $al killed $eax 56; FAST-NEXT: imulb %sil 57; FAST-NEXT: seto %cl 58; FAST-NEXT: movb %al, (%rdx) 59; FAST-NEXT: andb $1, %cl 60; FAST-NEXT: movzbl %cl, %eax 61; FAST-NEXT: retq 62 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2) 63 %val = extractvalue {i8, i1} %t, 0 64 %obit = extractvalue {i8, i1} %t, 1 65 store i8 %val, i8* %res 66 ret i1 %obit 67} 68 69define zeroext i1 @smuloi16(i16 %v1, i16 %v2, i16* %res) { 70; SDAG-LABEL: smuloi16: 71; SDAG: ## %bb.0: 72; SDAG-NEXT: imulw %si, %di 73; SDAG-NEXT: seto %al 74; SDAG-NEXT: movw %di, (%rdx) 75; SDAG-NEXT: retq 76; 77; FAST-LABEL: smuloi16: 78; FAST: ## %bb.0: 79; FAST-NEXT: imulw %si, %di 80; FAST-NEXT: seto %al 81; FAST-NEXT: movw %di, (%rdx) 82; FAST-NEXT: andb $1, %al 83; FAST-NEXT: movzbl %al, %eax 84; FAST-NEXT: retq 85 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2) 86 %val = extractvalue {i16, i1} %t, 0 87 %obit = extractvalue {i16, i1} %t, 1 88 store i16 %val, i16* %res 89 ret i1 %obit 90} 91 92define zeroext i1 @smuloi32(i32 %v1, i32 %v2, i32* %res) { 93; SDAG-LABEL: smuloi32: 94; SDAG: ## %bb.0: 95; SDAG-NEXT: imull %esi, %edi 96; SDAG-NEXT: seto %al 97; SDAG-NEXT: movl %edi, (%rdx) 98; SDAG-NEXT: retq 99; 100; FAST-LABEL: smuloi32: 101; FAST: ## %bb.0: 102; FAST-NEXT: imull %esi, %edi 103; FAST-NEXT: seto %al 104; FAST-NEXT: movl %edi, (%rdx) 105; FAST-NEXT: andb $1, %al 106; FAST-NEXT: movzbl %al, %eax 107; FAST-NEXT: retq 108 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 109 %val = extractvalue {i32, i1} %t, 0 110 %obit = extractvalue {i32, i1} %t, 1 111 store i32 %val, i32* %res 112 ret i1 %obit 113} 114 115define zeroext i1 @smuloi64(i64 %v1, i64 %v2, i64* %res) { 116; SDAG-LABEL: smuloi64: 117; SDAG: ## %bb.0: 118; SDAG-NEXT: imulq %rsi, %rdi 119; SDAG-NEXT: seto %al 120; SDAG-NEXT: movq %rdi, (%rdx) 121; SDAG-NEXT: retq 122; 123; FAST-LABEL: smuloi64: 124; FAST: ## %bb.0: 125; FAST-NEXT: imulq %rsi, %rdi 126; FAST-NEXT: seto %al 127; FAST-NEXT: movq %rdi, (%rdx) 128; FAST-NEXT: andb $1, %al 129; FAST-NEXT: movzbl %al, %eax 130; FAST-NEXT: retq 131 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 132 %val = extractvalue {i64, i1} %t, 0 133 %obit = extractvalue {i64, i1} %t, 1 134 store i64 %val, i64* %res 135 ret i1 %obit 136} 137 138; UMULO 139define zeroext i1 @umuloi8(i8 %v1, i8 %v2, i8* %res) { 140; SDAG-LABEL: umuloi8: 141; SDAG: ## %bb.0: 142; SDAG-NEXT: movl %edi, %eax 143; SDAG-NEXT: ## kill: def $al killed $al killed $eax 144; SDAG-NEXT: mulb %sil 145; SDAG-NEXT: seto %cl 146; SDAG-NEXT: movb %al, (%rdx) 147; SDAG-NEXT: movl %ecx, %eax 148; SDAG-NEXT: retq 149; 150; FAST-LABEL: umuloi8: 151; FAST: ## %bb.0: 152; FAST-NEXT: movl %edi, %eax 153; FAST-NEXT: ## kill: def $al killed $al killed $eax 154; FAST-NEXT: mulb %sil 155; FAST-NEXT: seto %cl 156; FAST-NEXT: movb %al, (%rdx) 157; FAST-NEXT: andb $1, %cl 158; FAST-NEXT: movzbl %cl, %eax 159; FAST-NEXT: retq 160 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2) 161 %val = extractvalue {i8, i1} %t, 0 162 %obit = extractvalue {i8, i1} %t, 1 163 store i8 %val, i8* %res 164 ret i1 %obit 165} 166 167define zeroext i1 @umuloi16(i16 %v1, i16 %v2, i16* %res) { 168; SDAG-LABEL: umuloi16: 169; SDAG: ## %bb.0: 170; SDAG-NEXT: movq %rdx, %rcx 171; SDAG-NEXT: movl %edi, %eax 172; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax 173; SDAG-NEXT: mulw %si 174; SDAG-NEXT: seto %dl 175; SDAG-NEXT: movw %ax, (%rcx) 176; SDAG-NEXT: movl %edx, %eax 177; SDAG-NEXT: retq 178; 179; FAST-LABEL: umuloi16: 180; FAST: ## %bb.0: 181; FAST-NEXT: movq %rdx, %rcx 182; FAST-NEXT: movl %edi, %eax 183; FAST-NEXT: ## kill: def $ax killed $ax killed $eax 184; FAST-NEXT: mulw %si 185; FAST-NEXT: seto %dl 186; FAST-NEXT: movw %ax, (%rcx) 187; FAST-NEXT: andb $1, %dl 188; FAST-NEXT: movzbl %dl, %eax 189; FAST-NEXT: retq 190 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2) 191 %val = extractvalue {i16, i1} %t, 0 192 %obit = extractvalue {i16, i1} %t, 1 193 store i16 %val, i16* %res 194 ret i1 %obit 195} 196 197define zeroext i1 @umuloi32(i32 %v1, i32 %v2, i32* %res) { 198; SDAG-LABEL: umuloi32: 199; SDAG: ## %bb.0: 200; SDAG-NEXT: movq %rdx, %rcx 201; SDAG-NEXT: movl %edi, %eax 202; SDAG-NEXT: mull %esi 203; SDAG-NEXT: seto %dl 204; SDAG-NEXT: movl %eax, (%rcx) 205; SDAG-NEXT: movl %edx, %eax 206; SDAG-NEXT: retq 207; 208; FAST-LABEL: umuloi32: 209; FAST: ## %bb.0: 210; FAST-NEXT: movq %rdx, %rcx 211; FAST-NEXT: movl %edi, %eax 212; FAST-NEXT: mull %esi 213; FAST-NEXT: seto %dl 214; FAST-NEXT: movl %eax, (%rcx) 215; FAST-NEXT: andb $1, %dl 216; FAST-NEXT: movzbl %dl, %eax 217; FAST-NEXT: retq 218 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 219 %val = extractvalue {i32, i1} %t, 0 220 %obit = extractvalue {i32, i1} %t, 1 221 store i32 %val, i32* %res 222 ret i1 %obit 223} 224 225define zeroext i1 @umuloi64(i64 %v1, i64 %v2, i64* %res) { 226; SDAG-LABEL: umuloi64: 227; SDAG: ## %bb.0: 228; SDAG-NEXT: movq %rdx, %rcx 229; SDAG-NEXT: movq %rdi, %rax 230; SDAG-NEXT: mulq %rsi 231; SDAG-NEXT: seto %dl 232; SDAG-NEXT: movq %rax, (%rcx) 233; SDAG-NEXT: movl %edx, %eax 234; SDAG-NEXT: retq 235; 236; FAST-LABEL: umuloi64: 237; FAST: ## %bb.0: 238; FAST-NEXT: movq %rdx, %rcx 239; FAST-NEXT: movq %rdi, %rax 240; FAST-NEXT: mulq %rsi 241; FAST-NEXT: seto %dl 242; FAST-NEXT: movq %rax, (%rcx) 243; FAST-NEXT: andb $1, %dl 244; FAST-NEXT: movzbl %dl, %eax 245; FAST-NEXT: retq 246 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 247 %val = extractvalue {i64, i1} %t, 0 248 %obit = extractvalue {i64, i1} %t, 1 249 store i64 %val, i64* %res 250 ret i1 %obit 251} 252 253; 254; Check the use of the overflow bit in combination with a select instruction. 255; 256define i32 @smuloselecti32(i32 %v1, i32 %v2) { 257; CHECK-LABEL: smuloselecti32: 258; CHECK: ## %bb.0: 259; CHECK-NEXT: movl %esi, %eax 260; CHECK-NEXT: movl %edi, %ecx 261; CHECK-NEXT: imull %esi, %ecx 262; CHECK-NEXT: cmovol %edi, %eax 263; CHECK-NEXT: retq 264 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 265 %obit = extractvalue {i32, i1} %t, 1 266 %ret = select i1 %obit, i32 %v1, i32 %v2 267 ret i32 %ret 268} 269 270define i64 @smuloselecti64(i64 %v1, i64 %v2) { 271; CHECK-LABEL: smuloselecti64: 272; CHECK: ## %bb.0: 273; CHECK-NEXT: movq %rsi, %rax 274; CHECK-NEXT: movq %rdi, %rcx 275; CHECK-NEXT: imulq %rsi, %rcx 276; CHECK-NEXT: cmovoq %rdi, %rax 277; CHECK-NEXT: retq 278 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 279 %obit = extractvalue {i64, i1} %t, 1 280 %ret = select i1 %obit, i64 %v1, i64 %v2 281 ret i64 %ret 282} 283 284define i32 @umuloselecti32(i32 %v1, i32 %v2) { 285; CHECK-LABEL: umuloselecti32: 286; CHECK: ## %bb.0: 287; CHECK-NEXT: movl %edi, %eax 288; CHECK-NEXT: mull %esi 289; CHECK-NEXT: cmovol %edi, %esi 290; CHECK-NEXT: movl %esi, %eax 291; CHECK-NEXT: retq 292 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 293 %obit = extractvalue {i32, i1} %t, 1 294 %ret = select i1 %obit, i32 %v1, i32 %v2 295 ret i32 %ret 296} 297 298define i64 @umuloselecti64(i64 %v1, i64 %v2) { 299; CHECK-LABEL: umuloselecti64: 300; CHECK: ## %bb.0: 301; CHECK-NEXT: movq %rdi, %rax 302; CHECK-NEXT: mulq %rsi 303; CHECK-NEXT: cmovoq %rdi, %rsi 304; CHECK-NEXT: movq %rsi, %rax 305; CHECK-NEXT: retq 306 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 307 %obit = extractvalue {i64, i1} %t, 1 308 %ret = select i1 %obit, i64 %v1, i64 %v2 309 ret i64 %ret 310} 311 312; 313; Check the use of the overflow bit in combination with a branch instruction. 314; 315define zeroext i1 @smulobri8(i8 %v1, i8 %v2) { 316; SDAG-LABEL: smulobri8: 317; SDAG: ## %bb.0: 318; SDAG-NEXT: movl %edi, %eax 319; SDAG-NEXT: ## kill: def $al killed $al killed $eax 320; SDAG-NEXT: imulb %sil 321; SDAG-NEXT: jo LBB15_1 322; SDAG-NEXT: ## %bb.2: ## %continue 323; SDAG-NEXT: movb $1, %al 324; SDAG-NEXT: retq 325; SDAG-NEXT: LBB15_1: ## %overflow 326; SDAG-NEXT: xorl %eax, %eax 327; SDAG-NEXT: retq 328; 329; FAST-LABEL: smulobri8: 330; FAST: ## %bb.0: 331; FAST-NEXT: movl %edi, %eax 332; FAST-NEXT: ## kill: def $al killed $al killed $eax 333; FAST-NEXT: imulb %sil 334; FAST-NEXT: seto %al 335; FAST-NEXT: testb $1, %al 336; FAST-NEXT: jne LBB15_1 337; FAST-NEXT: ## %bb.2: ## %continue 338; FAST-NEXT: movb $1, %al 339; FAST-NEXT: andb $1, %al 340; FAST-NEXT: movzbl %al, %eax 341; FAST-NEXT: retq 342; FAST-NEXT: LBB15_1: ## %overflow 343; FAST-NEXT: xorl %eax, %eax 344; FAST-NEXT: andb $1, %al 345; FAST-NEXT: movzbl %al, %eax 346; FAST-NEXT: retq 347 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2) 348 %val = extractvalue {i8, i1} %t, 0 349 %obit = extractvalue {i8, i1} %t, 1 350 br i1 %obit, label %overflow, label %continue, !prof !0 351 352overflow: 353 ret i1 false 354 355continue: 356 ret i1 true 357} 358 359define zeroext i1 @smulobri16(i16 %v1, i16 %v2) { 360; SDAG-LABEL: smulobri16: 361; SDAG: ## %bb.0: 362; SDAG-NEXT: imulw %si, %di 363; SDAG-NEXT: jo LBB16_1 364; SDAG-NEXT: ## %bb.2: ## %continue 365; SDAG-NEXT: movb $1, %al 366; SDAG-NEXT: retq 367; SDAG-NEXT: LBB16_1: ## %overflow 368; SDAG-NEXT: xorl %eax, %eax 369; SDAG-NEXT: retq 370; 371; FAST-LABEL: smulobri16: 372; FAST: ## %bb.0: 373; FAST-NEXT: imulw %si, %di 374; FAST-NEXT: seto %al 375; FAST-NEXT: testb $1, %al 376; FAST-NEXT: jne LBB16_1 377; FAST-NEXT: ## %bb.2: ## %continue 378; FAST-NEXT: movb $1, %al 379; FAST-NEXT: andb $1, %al 380; FAST-NEXT: movzbl %al, %eax 381; FAST-NEXT: retq 382; FAST-NEXT: LBB16_1: ## %overflow 383; FAST-NEXT: xorl %eax, %eax 384; FAST-NEXT: andb $1, %al 385; FAST-NEXT: movzbl %al, %eax 386; FAST-NEXT: retq 387 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2) 388 %val = extractvalue {i16, i1} %t, 0 389 %obit = extractvalue {i16, i1} %t, 1 390 br i1 %obit, label %overflow, label %continue, !prof !0 391 392overflow: 393 ret i1 false 394 395continue: 396 ret i1 true 397} 398 399define zeroext i1 @smulobri32(i32 %v1, i32 %v2) { 400; SDAG-LABEL: smulobri32: 401; SDAG: ## %bb.0: 402; SDAG-NEXT: imull %esi, %edi 403; SDAG-NEXT: jo LBB17_1 404; SDAG-NEXT: ## %bb.2: ## %continue 405; SDAG-NEXT: movb $1, %al 406; SDAG-NEXT: retq 407; SDAG-NEXT: LBB17_1: ## %overflow 408; SDAG-NEXT: xorl %eax, %eax 409; SDAG-NEXT: retq 410; 411; FAST-LABEL: smulobri32: 412; FAST: ## %bb.0: 413; FAST-NEXT: imull %esi, %edi 414; FAST-NEXT: jo LBB17_1 415; FAST-NEXT: ## %bb.2: ## %continue 416; FAST-NEXT: movb $1, %al 417; FAST-NEXT: andb $1, %al 418; FAST-NEXT: movzbl %al, %eax 419; FAST-NEXT: retq 420; FAST-NEXT: LBB17_1: ## %overflow 421; FAST-NEXT: xorl %eax, %eax 422; FAST-NEXT: andb $1, %al 423; FAST-NEXT: movzbl %al, %eax 424; FAST-NEXT: retq 425 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 426 %val = extractvalue {i32, i1} %t, 0 427 %obit = extractvalue {i32, i1} %t, 1 428 br i1 %obit, label %overflow, label %continue, !prof !0 429 430overflow: 431 ret i1 false 432 433continue: 434 ret i1 true 435} 436 437define zeroext i1 @smulobri64(i64 %v1, i64 %v2) { 438; SDAG-LABEL: smulobri64: 439; SDAG: ## %bb.0: 440; SDAG-NEXT: imulq %rsi, %rdi 441; SDAG-NEXT: jo LBB18_1 442; SDAG-NEXT: ## %bb.2: ## %continue 443; SDAG-NEXT: movb $1, %al 444; SDAG-NEXT: retq 445; SDAG-NEXT: LBB18_1: ## %overflow 446; SDAG-NEXT: xorl %eax, %eax 447; SDAG-NEXT: retq 448; 449; FAST-LABEL: smulobri64: 450; FAST: ## %bb.0: 451; FAST-NEXT: imulq %rsi, %rdi 452; FAST-NEXT: jo LBB18_1 453; FAST-NEXT: ## %bb.2: ## %continue 454; FAST-NEXT: movb $1, %al 455; FAST-NEXT: andb $1, %al 456; FAST-NEXT: movzbl %al, %eax 457; FAST-NEXT: retq 458; FAST-NEXT: LBB18_1: ## %overflow 459; FAST-NEXT: xorl %eax, %eax 460; FAST-NEXT: andb $1, %al 461; FAST-NEXT: movzbl %al, %eax 462; FAST-NEXT: retq 463 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 464 %val = extractvalue {i64, i1} %t, 0 465 %obit = extractvalue {i64, i1} %t, 1 466 br i1 %obit, label %overflow, label %continue, !prof !0 467 468overflow: 469 ret i1 false 470 471continue: 472 ret i1 true 473} 474 475define zeroext i1 @umulobri8(i8 %v1, i8 %v2) { 476; SDAG-LABEL: umulobri8: 477; SDAG: ## %bb.0: 478; SDAG-NEXT: movl %edi, %eax 479; SDAG-NEXT: ## kill: def $al killed $al killed $eax 480; SDAG-NEXT: mulb %sil 481; SDAG-NEXT: jo LBB19_1 482; SDAG-NEXT: ## %bb.2: ## %continue 483; SDAG-NEXT: movb $1, %al 484; SDAG-NEXT: retq 485; SDAG-NEXT: LBB19_1: ## %overflow 486; SDAG-NEXT: xorl %eax, %eax 487; SDAG-NEXT: retq 488; 489; FAST-LABEL: umulobri8: 490; FAST: ## %bb.0: 491; FAST-NEXT: movl %edi, %eax 492; FAST-NEXT: ## kill: def $al killed $al killed $eax 493; FAST-NEXT: mulb %sil 494; FAST-NEXT: seto %al 495; FAST-NEXT: testb $1, %al 496; FAST-NEXT: jne LBB19_1 497; FAST-NEXT: ## %bb.2: ## %continue 498; FAST-NEXT: movb $1, %al 499; FAST-NEXT: andb $1, %al 500; FAST-NEXT: movzbl %al, %eax 501; FAST-NEXT: retq 502; FAST-NEXT: LBB19_1: ## %overflow 503; FAST-NEXT: xorl %eax, %eax 504; FAST-NEXT: andb $1, %al 505; FAST-NEXT: movzbl %al, %eax 506; FAST-NEXT: retq 507 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2) 508 %val = extractvalue {i8, i1} %t, 0 509 %obit = extractvalue {i8, i1} %t, 1 510 br i1 %obit, label %overflow, label %continue, !prof !0 511 512overflow: 513 ret i1 false 514 515continue: 516 ret i1 true 517} 518 519define zeroext i1 @umulobri16(i16 %v1, i16 %v2) { 520; SDAG-LABEL: umulobri16: 521; SDAG: ## %bb.0: 522; SDAG-NEXT: movl %edi, %eax 523; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax 524; SDAG-NEXT: mulw %si 525; SDAG-NEXT: jo LBB20_1 526; SDAG-NEXT: ## %bb.2: ## %continue 527; SDAG-NEXT: movb $1, %al 528; SDAG-NEXT: retq 529; SDAG-NEXT: LBB20_1: ## %overflow 530; SDAG-NEXT: xorl %eax, %eax 531; SDAG-NEXT: retq 532; 533; FAST-LABEL: umulobri16: 534; FAST: ## %bb.0: 535; FAST-NEXT: movl %edi, %eax 536; FAST-NEXT: ## kill: def $ax killed $ax killed $eax 537; FAST-NEXT: mulw %si 538; FAST-NEXT: seto %al 539; FAST-NEXT: testb $1, %al 540; FAST-NEXT: jne LBB20_1 541; FAST-NEXT: ## %bb.2: ## %continue 542; FAST-NEXT: movb $1, %al 543; FAST-NEXT: andb $1, %al 544; FAST-NEXT: movzbl %al, %eax 545; FAST-NEXT: retq 546; FAST-NEXT: LBB20_1: ## %overflow 547; FAST-NEXT: xorl %eax, %eax 548; FAST-NEXT: andb $1, %al 549; FAST-NEXT: movzbl %al, %eax 550; FAST-NEXT: retq 551 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2) 552 %val = extractvalue {i16, i1} %t, 0 553 %obit = extractvalue {i16, i1} %t, 1 554 br i1 %obit, label %overflow, label %continue, !prof !0 555 556overflow: 557 ret i1 false 558 559continue: 560 ret i1 true 561} 562 563define zeroext i1 @umulobri32(i32 %v1, i32 %v2) { 564; SDAG-LABEL: umulobri32: 565; SDAG: ## %bb.0: 566; SDAG-NEXT: movl %edi, %eax 567; SDAG-NEXT: mull %esi 568; SDAG-NEXT: jo LBB21_1 569; SDAG-NEXT: ## %bb.2: ## %continue 570; SDAG-NEXT: movb $1, %al 571; SDAG-NEXT: retq 572; SDAG-NEXT: LBB21_1: ## %overflow 573; SDAG-NEXT: xorl %eax, %eax 574; SDAG-NEXT: retq 575; 576; FAST-LABEL: umulobri32: 577; FAST: ## %bb.0: 578; FAST-NEXT: movl %edi, %eax 579; FAST-NEXT: mull %esi 580; FAST-NEXT: jo LBB21_1 581; FAST-NEXT: ## %bb.2: ## %continue 582; FAST-NEXT: movb $1, %al 583; FAST-NEXT: andb $1, %al 584; FAST-NEXT: movzbl %al, %eax 585; FAST-NEXT: retq 586; FAST-NEXT: LBB21_1: ## %overflow 587; FAST-NEXT: xorl %eax, %eax 588; FAST-NEXT: andb $1, %al 589; FAST-NEXT: movzbl %al, %eax 590; FAST-NEXT: retq 591 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 592 %val = extractvalue {i32, i1} %t, 0 593 %obit = extractvalue {i32, i1} %t, 1 594 br i1 %obit, label %overflow, label %continue, !prof !0 595 596overflow: 597 ret i1 false 598 599continue: 600 ret i1 true 601} 602 603define zeroext i1 @umulobri64(i64 %v1, i64 %v2) { 604; SDAG-LABEL: umulobri64: 605; SDAG: ## %bb.0: 606; SDAG-NEXT: movq %rdi, %rax 607; SDAG-NEXT: mulq %rsi 608; SDAG-NEXT: jo LBB22_1 609; SDAG-NEXT: ## %bb.2: ## %continue 610; SDAG-NEXT: movb $1, %al 611; SDAG-NEXT: retq 612; SDAG-NEXT: LBB22_1: ## %overflow 613; SDAG-NEXT: xorl %eax, %eax 614; SDAG-NEXT: retq 615; 616; FAST-LABEL: umulobri64: 617; FAST: ## %bb.0: 618; FAST-NEXT: movq %rdi, %rax 619; FAST-NEXT: mulq %rsi 620; FAST-NEXT: jo LBB22_1 621; FAST-NEXT: ## %bb.2: ## %continue 622; FAST-NEXT: movb $1, %al 623; FAST-NEXT: andb $1, %al 624; FAST-NEXT: movzbl %al, %eax 625; FAST-NEXT: retq 626; FAST-NEXT: LBB22_1: ## %overflow 627; FAST-NEXT: xorl %eax, %eax 628; FAST-NEXT: andb $1, %al 629; FAST-NEXT: movzbl %al, %eax 630; FAST-NEXT: retq 631 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 632 %val = extractvalue {i64, i1} %t, 0 633 %obit = extractvalue {i64, i1} %t, 1 634 br i1 %obit, label %overflow, label %continue, !prof !0 635 636overflow: 637 ret i1 false 638 639continue: 640 ret i1 true 641} 642 643define i1 @bug27873(i64 %c1, i1 %c2) { 644; CHECK-LABEL: bug27873: 645; CHECK: ## %bb.0: 646; CHECK-NEXT: movq %rdi, %rax 647; CHECK-NEXT: movl $160, %ecx 648; CHECK-NEXT: mulq %rcx 649; CHECK-NEXT: seto %al 650; CHECK-NEXT: orb %sil, %al 651; CHECK-NEXT: retq 652 %mul = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %c1, i64 160) 653 %mul.overflow = extractvalue { i64, i1 } %mul, 1 654 %x1 = or i1 %c2, %mul.overflow 655 ret i1 %x1 656} 657 658define zeroext i1 @smuloi8_load(i8* %ptr1, i8 %v2, i8* %res) { 659; SDAG-LABEL: smuloi8_load: 660; SDAG: ## %bb.0: 661; SDAG-NEXT: movl %esi, %eax 662; SDAG-NEXT: ## kill: def $al killed $al killed $eax 663; SDAG-NEXT: imulb (%rdi) 664; SDAG-NEXT: seto %cl 665; SDAG-NEXT: movb %al, (%rdx) 666; SDAG-NEXT: movl %ecx, %eax 667; SDAG-NEXT: retq 668; 669; FAST-LABEL: smuloi8_load: 670; FAST: ## %bb.0: 671; FAST-NEXT: movb (%rdi), %al 672; FAST-NEXT: imulb %sil 673; FAST-NEXT: seto %cl 674; FAST-NEXT: movb %al, (%rdx) 675; FAST-NEXT: andb $1, %cl 676; FAST-NEXT: movzbl %cl, %eax 677; FAST-NEXT: retq 678 %v1 = load i8, i8* %ptr1 679 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2) 680 %val = extractvalue {i8, i1} %t, 0 681 %obit = extractvalue {i8, i1} %t, 1 682 store i8 %val, i8* %res 683 ret i1 %obit 684} 685 686define zeroext i1 @smuloi8_load2(i8 %v1, i8* %ptr2, i8* %res) { 687; SDAG-LABEL: smuloi8_load2: 688; SDAG: ## %bb.0: 689; SDAG-NEXT: movl %edi, %eax 690; SDAG-NEXT: ## kill: def $al killed $al killed $eax 691; SDAG-NEXT: imulb (%rsi) 692; SDAG-NEXT: seto %cl 693; SDAG-NEXT: movb %al, (%rdx) 694; SDAG-NEXT: movl %ecx, %eax 695; SDAG-NEXT: retq 696; 697; FAST-LABEL: smuloi8_load2: 698; FAST: ## %bb.0: 699; FAST-NEXT: movl %edi, %eax 700; FAST-NEXT: ## kill: def $al killed $al killed $eax 701; FAST-NEXT: imulb (%rsi) 702; FAST-NEXT: seto %cl 703; FAST-NEXT: movb %al, (%rdx) 704; FAST-NEXT: andb $1, %cl 705; FAST-NEXT: movzbl %cl, %eax 706; FAST-NEXT: retq 707 %v2 = load i8, i8* %ptr2 708 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2) 709 %val = extractvalue {i8, i1} %t, 0 710 %obit = extractvalue {i8, i1} %t, 1 711 store i8 %val, i8* %res 712 ret i1 %obit 713} 714 715define zeroext i1 @smuloi16_load(i16* %ptr1, i16 %v2, i16* %res) { 716; SDAG-LABEL: smuloi16_load: 717; SDAG: ## %bb.0: 718; SDAG-NEXT: imulw (%rdi), %si 719; SDAG-NEXT: seto %al 720; SDAG-NEXT: movw %si, (%rdx) 721; SDAG-NEXT: retq 722; 723; FAST-LABEL: smuloi16_load: 724; FAST: ## %bb.0: 725; FAST-NEXT: imulw (%rdi), %si 726; FAST-NEXT: seto %al 727; FAST-NEXT: movw %si, (%rdx) 728; FAST-NEXT: andb $1, %al 729; FAST-NEXT: movzbl %al, %eax 730; FAST-NEXT: retq 731 %v1 = load i16, i16* %ptr1 732 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2) 733 %val = extractvalue {i16, i1} %t, 0 734 %obit = extractvalue {i16, i1} %t, 1 735 store i16 %val, i16* %res 736 ret i1 %obit 737} 738 739define zeroext i1 @smuloi16_load2(i16 %v1, i16* %ptr2, i16* %res) { 740; SDAG-LABEL: smuloi16_load2: 741; SDAG: ## %bb.0: 742; SDAG-NEXT: imulw (%rsi), %di 743; SDAG-NEXT: seto %al 744; SDAG-NEXT: movw %di, (%rdx) 745; SDAG-NEXT: retq 746; 747; FAST-LABEL: smuloi16_load2: 748; FAST: ## %bb.0: 749; FAST-NEXT: imulw (%rsi), %di 750; FAST-NEXT: seto %al 751; FAST-NEXT: movw %di, (%rdx) 752; FAST-NEXT: andb $1, %al 753; FAST-NEXT: movzbl %al, %eax 754; FAST-NEXT: retq 755 %v2 = load i16, i16* %ptr2 756 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2) 757 %val = extractvalue {i16, i1} %t, 0 758 %obit = extractvalue {i16, i1} %t, 1 759 store i16 %val, i16* %res 760 ret i1 %obit 761} 762 763define zeroext i1 @smuloi32_load(i32* %ptr1, i32 %v2, i32* %res) { 764; SDAG-LABEL: smuloi32_load: 765; SDAG: ## %bb.0: 766; SDAG-NEXT: imull (%rdi), %esi 767; SDAG-NEXT: seto %al 768; SDAG-NEXT: movl %esi, (%rdx) 769; SDAG-NEXT: retq 770; 771; FAST-LABEL: smuloi32_load: 772; FAST: ## %bb.0: 773; FAST-NEXT: imull (%rdi), %esi 774; FAST-NEXT: seto %al 775; FAST-NEXT: movl %esi, (%rdx) 776; FAST-NEXT: andb $1, %al 777; FAST-NEXT: movzbl %al, %eax 778; FAST-NEXT: retq 779 %v1 = load i32, i32* %ptr1 780 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 781 %val = extractvalue {i32, i1} %t, 0 782 %obit = extractvalue {i32, i1} %t, 1 783 store i32 %val, i32* %res 784 ret i1 %obit 785} 786 787define zeroext i1 @smuloi32_load2(i32 %v1, i32* %ptr2, i32* %res) { 788; SDAG-LABEL: smuloi32_load2: 789; SDAG: ## %bb.0: 790; SDAG-NEXT: imull (%rsi), %edi 791; SDAG-NEXT: seto %al 792; SDAG-NEXT: movl %edi, (%rdx) 793; SDAG-NEXT: retq 794; 795; FAST-LABEL: smuloi32_load2: 796; FAST: ## %bb.0: 797; FAST-NEXT: imull (%rsi), %edi 798; FAST-NEXT: seto %al 799; FAST-NEXT: movl %edi, (%rdx) 800; FAST-NEXT: andb $1, %al 801; FAST-NEXT: movzbl %al, %eax 802; FAST-NEXT: retq 803 %v2 = load i32, i32* %ptr2 804 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 805 %val = extractvalue {i32, i1} %t, 0 806 %obit = extractvalue {i32, i1} %t, 1 807 store i32 %val, i32* %res 808 ret i1 %obit 809} 810 811define zeroext i1 @smuloi64_load(i64* %ptr1, i64 %v2, i64* %res) { 812; SDAG-LABEL: smuloi64_load: 813; SDAG: ## %bb.0: 814; SDAG-NEXT: imulq (%rdi), %rsi 815; SDAG-NEXT: seto %al 816; SDAG-NEXT: movq %rsi, (%rdx) 817; SDAG-NEXT: retq 818; 819; FAST-LABEL: smuloi64_load: 820; FAST: ## %bb.0: 821; FAST-NEXT: imulq (%rdi), %rsi 822; FAST-NEXT: seto %al 823; FAST-NEXT: movq %rsi, (%rdx) 824; FAST-NEXT: andb $1, %al 825; FAST-NEXT: movzbl %al, %eax 826; FAST-NEXT: retq 827 %v1 = load i64, i64* %ptr1 828 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 829 %val = extractvalue {i64, i1} %t, 0 830 %obit = extractvalue {i64, i1} %t, 1 831 store i64 %val, i64* %res 832 ret i1 %obit 833} 834 835define zeroext i1 @smuloi64_load2(i64 %v1, i64* %ptr2, i64* %res) { 836; SDAG-LABEL: smuloi64_load2: 837; SDAG: ## %bb.0: 838; SDAG-NEXT: imulq (%rsi), %rdi 839; SDAG-NEXT: seto %al 840; SDAG-NEXT: movq %rdi, (%rdx) 841; SDAG-NEXT: retq 842; 843; FAST-LABEL: smuloi64_load2: 844; FAST: ## %bb.0: 845; FAST-NEXT: imulq (%rsi), %rdi 846; FAST-NEXT: seto %al 847; FAST-NEXT: movq %rdi, (%rdx) 848; FAST-NEXT: andb $1, %al 849; FAST-NEXT: movzbl %al, %eax 850; FAST-NEXT: retq 851 %v2 = load i64, i64* %ptr2 852 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 853 %val = extractvalue {i64, i1} %t, 0 854 %obit = extractvalue {i64, i1} %t, 1 855 store i64 %val, i64* %res 856 ret i1 %obit 857} 858 859define zeroext i1 @umuloi8_load(i8* %ptr1, i8 %v2, i8* %res) { 860; SDAG-LABEL: umuloi8_load: 861; SDAG: ## %bb.0: 862; SDAG-NEXT: movl %esi, %eax 863; SDAG-NEXT: ## kill: def $al killed $al killed $eax 864; SDAG-NEXT: mulb (%rdi) 865; SDAG-NEXT: seto %cl 866; SDAG-NEXT: movb %al, (%rdx) 867; SDAG-NEXT: movl %ecx, %eax 868; SDAG-NEXT: retq 869; 870; FAST-LABEL: umuloi8_load: 871; FAST: ## %bb.0: 872; FAST-NEXT: movb (%rdi), %al 873; FAST-NEXT: mulb %sil 874; FAST-NEXT: seto %cl 875; FAST-NEXT: movb %al, (%rdx) 876; FAST-NEXT: andb $1, %cl 877; FAST-NEXT: movzbl %cl, %eax 878; FAST-NEXT: retq 879 %v1 = load i8, i8* %ptr1 880 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2) 881 %val = extractvalue {i8, i1} %t, 0 882 %obit = extractvalue {i8, i1} %t, 1 883 store i8 %val, i8* %res 884 ret i1 %obit 885} 886 887define zeroext i1 @umuloi8_load2(i8 %v1, i8* %ptr2, i8* %res) { 888; SDAG-LABEL: umuloi8_load2: 889; SDAG: ## %bb.0: 890; SDAG-NEXT: movl %edi, %eax 891; SDAG-NEXT: ## kill: def $al killed $al killed $eax 892; SDAG-NEXT: mulb (%rsi) 893; SDAG-NEXT: seto %cl 894; SDAG-NEXT: movb %al, (%rdx) 895; SDAG-NEXT: movl %ecx, %eax 896; SDAG-NEXT: retq 897; 898; FAST-LABEL: umuloi8_load2: 899; FAST: ## %bb.0: 900; FAST-NEXT: movl %edi, %eax 901; FAST-NEXT: ## kill: def $al killed $al killed $eax 902; FAST-NEXT: mulb (%rsi) 903; FAST-NEXT: seto %cl 904; FAST-NEXT: movb %al, (%rdx) 905; FAST-NEXT: andb $1, %cl 906; FAST-NEXT: movzbl %cl, %eax 907; FAST-NEXT: retq 908 %v2 = load i8, i8* %ptr2 909 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2) 910 %val = extractvalue {i8, i1} %t, 0 911 %obit = extractvalue {i8, i1} %t, 1 912 store i8 %val, i8* %res 913 ret i1 %obit 914} 915 916define zeroext i1 @umuloi16_load(i16* %ptr1, i16 %v2, i16* %res) { 917; SDAG-LABEL: umuloi16_load: 918; SDAG: ## %bb.0: 919; SDAG-NEXT: movq %rdx, %rcx 920; SDAG-NEXT: movl %esi, %eax 921; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax 922; SDAG-NEXT: mulw (%rdi) 923; SDAG-NEXT: seto %dl 924; SDAG-NEXT: movw %ax, (%rcx) 925; SDAG-NEXT: movl %edx, %eax 926; SDAG-NEXT: retq 927; 928; FAST-LABEL: umuloi16_load: 929; FAST: ## %bb.0: 930; FAST-NEXT: movq %rdx, %rcx 931; FAST-NEXT: movzwl (%rdi), %eax 932; FAST-NEXT: mulw %si 933; FAST-NEXT: seto %dl 934; FAST-NEXT: movw %ax, (%rcx) 935; FAST-NEXT: andb $1, %dl 936; FAST-NEXT: movzbl %dl, %eax 937; FAST-NEXT: retq 938 %v1 = load i16, i16* %ptr1 939 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2) 940 %val = extractvalue {i16, i1} %t, 0 941 %obit = extractvalue {i16, i1} %t, 1 942 store i16 %val, i16* %res 943 ret i1 %obit 944} 945 946define zeroext i1 @umuloi16_load2(i16 %v1, i16* %ptr2, i16* %res) { 947; SDAG-LABEL: umuloi16_load2: 948; SDAG: ## %bb.0: 949; SDAG-NEXT: movq %rdx, %rcx 950; SDAG-NEXT: movl %edi, %eax 951; SDAG-NEXT: ## kill: def $ax killed $ax killed $eax 952; SDAG-NEXT: mulw (%rsi) 953; SDAG-NEXT: seto %dl 954; SDAG-NEXT: movw %ax, (%rcx) 955; SDAG-NEXT: movl %edx, %eax 956; SDAG-NEXT: retq 957; 958; FAST-LABEL: umuloi16_load2: 959; FAST: ## %bb.0: 960; FAST-NEXT: movq %rdx, %rcx 961; FAST-NEXT: movl %edi, %eax 962; FAST-NEXT: ## kill: def $ax killed $ax killed $eax 963; FAST-NEXT: mulw (%rsi) 964; FAST-NEXT: seto %dl 965; FAST-NEXT: movw %ax, (%rcx) 966; FAST-NEXT: andb $1, %dl 967; FAST-NEXT: movzbl %dl, %eax 968; FAST-NEXT: retq 969 %v2 = load i16, i16* %ptr2 970 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2) 971 %val = extractvalue {i16, i1} %t, 0 972 %obit = extractvalue {i16, i1} %t, 1 973 store i16 %val, i16* %res 974 ret i1 %obit 975} 976 977define zeroext i1 @umuloi32_load(i32* %ptr1, i32 %v2, i32* %res) { 978; SDAG-LABEL: umuloi32_load: 979; SDAG: ## %bb.0: 980; SDAG-NEXT: movq %rdx, %rcx 981; SDAG-NEXT: movl %esi, %eax 982; SDAG-NEXT: mull (%rdi) 983; SDAG-NEXT: seto %dl 984; SDAG-NEXT: movl %eax, (%rcx) 985; SDAG-NEXT: movl %edx, %eax 986; SDAG-NEXT: retq 987; 988; FAST-LABEL: umuloi32_load: 989; FAST: ## %bb.0: 990; FAST-NEXT: movq %rdx, %rcx 991; FAST-NEXT: movl (%rdi), %eax 992; FAST-NEXT: mull %esi 993; FAST-NEXT: seto %dl 994; FAST-NEXT: movl %eax, (%rcx) 995; FAST-NEXT: andb $1, %dl 996; FAST-NEXT: movzbl %dl, %eax 997; FAST-NEXT: retq 998 %v1 = load i32, i32* %ptr1 999 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 1000 %val = extractvalue {i32, i1} %t, 0 1001 %obit = extractvalue {i32, i1} %t, 1 1002 store i32 %val, i32* %res 1003 ret i1 %obit 1004} 1005 1006define zeroext i1 @umuloi32_load2(i32 %v1, i32* %ptr2, i32* %res) { 1007; SDAG-LABEL: umuloi32_load2: 1008; SDAG: ## %bb.0: 1009; SDAG-NEXT: movq %rdx, %rcx 1010; SDAG-NEXT: movl %edi, %eax 1011; SDAG-NEXT: mull (%rsi) 1012; SDAG-NEXT: seto %dl 1013; SDAG-NEXT: movl %eax, (%rcx) 1014; SDAG-NEXT: movl %edx, %eax 1015; SDAG-NEXT: retq 1016; 1017; FAST-LABEL: umuloi32_load2: 1018; FAST: ## %bb.0: 1019; FAST-NEXT: movq %rdx, %rcx 1020; FAST-NEXT: movl %edi, %eax 1021; FAST-NEXT: mull (%rsi) 1022; FAST-NEXT: seto %dl 1023; FAST-NEXT: movl %eax, (%rcx) 1024; FAST-NEXT: andb $1, %dl 1025; FAST-NEXT: movzbl %dl, %eax 1026; FAST-NEXT: retq 1027 %v2 = load i32, i32* %ptr2 1028 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 1029 %val = extractvalue {i32, i1} %t, 0 1030 %obit = extractvalue {i32, i1} %t, 1 1031 store i32 %val, i32* %res 1032 ret i1 %obit 1033} 1034 1035define zeroext i1 @umuloi64_load(i64* %ptr1, i64 %v2, i64* %res) { 1036; SDAG-LABEL: umuloi64_load: 1037; SDAG: ## %bb.0: 1038; SDAG-NEXT: movq %rdx, %rcx 1039; SDAG-NEXT: movq %rsi, %rax 1040; SDAG-NEXT: mulq (%rdi) 1041; SDAG-NEXT: seto %dl 1042; SDAG-NEXT: movq %rax, (%rcx) 1043; SDAG-NEXT: movl %edx, %eax 1044; SDAG-NEXT: retq 1045; 1046; FAST-LABEL: umuloi64_load: 1047; FAST: ## %bb.0: 1048; FAST-NEXT: movq %rdx, %rcx 1049; FAST-NEXT: movq (%rdi), %rax 1050; FAST-NEXT: mulq %rsi 1051; FAST-NEXT: seto %dl 1052; FAST-NEXT: movq %rax, (%rcx) 1053; FAST-NEXT: andb $1, %dl 1054; FAST-NEXT: movzbl %dl, %eax 1055; FAST-NEXT: retq 1056 %v1 = load i64, i64* %ptr1 1057 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 1058 %val = extractvalue {i64, i1} %t, 0 1059 %obit = extractvalue {i64, i1} %t, 1 1060 store i64 %val, i64* %res 1061 ret i1 %obit 1062} 1063 1064define zeroext i1 @umuloi64_load2(i64 %v1, i64* %ptr2, i64* %res) { 1065; SDAG-LABEL: umuloi64_load2: 1066; SDAG: ## %bb.0: 1067; SDAG-NEXT: movq %rdx, %rcx 1068; SDAG-NEXT: movq %rdi, %rax 1069; SDAG-NEXT: mulq (%rsi) 1070; SDAG-NEXT: seto %dl 1071; SDAG-NEXT: movq %rax, (%rcx) 1072; SDAG-NEXT: movl %edx, %eax 1073; SDAG-NEXT: retq 1074; 1075; FAST-LABEL: umuloi64_load2: 1076; FAST: ## %bb.0: 1077; FAST-NEXT: movq %rdx, %rcx 1078; FAST-NEXT: movq %rdi, %rax 1079; FAST-NEXT: mulq (%rsi) 1080; FAST-NEXT: seto %dl 1081; FAST-NEXT: movq %rax, (%rcx) 1082; FAST-NEXT: andb $1, %dl 1083; FAST-NEXT: movzbl %dl, %eax 1084; FAST-NEXT: retq 1085 %v2 = load i64, i64* %ptr2 1086 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 1087 %val = extractvalue {i64, i1} %t, 0 1088 %obit = extractvalue {i64, i1} %t, 1 1089 store i64 %val, i64* %res 1090 ret i1 %obit 1091} 1092 1093declare {i8, i1} @llvm.smul.with.overflow.i8 (i8, i8 ) nounwind readnone 1094declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone 1095declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone 1096declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone 1097declare {i8, i1} @llvm.umul.with.overflow.i8 (i8, i8 ) nounwind readnone 1098declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone 1099declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone 1100declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone 1101 1102!0 = !{!"branch_weights", i32 0, i32 2147483647} 1103