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