2268 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -disable-peephole -mtriple=x86_64-linux-unknown < %s | FileCheck %s --check-prefixes=CHECK,LINUX,SDAG3; RUN: llc -disable-peephole -mtriple=x86_64-linux-unknown -fast-isel -fast-isel-abort=1 < %s | FileCheck %s --check-prefixes=CHECK,LINUX,FAST4; RUN: llc -disable-peephole -mtriple=x86_64-linux-unknown -mcpu=knl < %s | FileCheck %s --check-prefixes=CHECK,LINUX,SDAG5; RUN: llc -disable-peephole -mtriple=x86_64-pc-win32 < %s | FileCheck %s --check-prefixes=CHECK,WIN646; RUN: llc -disable-peephole -mtriple=i386-pc-win32 < %s | FileCheck %s --check-prefix=WIN327 8define {i64, i1} @t1() nounwind {9; CHECK-LABEL: t1:10; CHECK: # %bb.0:11; CHECK-NEXT: movl $72, %eax12; CHECK-NEXT: xorl %edx, %edx13; CHECK-NEXT: retq14;15; WIN32-LABEL: t1:16; WIN32: # %bb.0:17; WIN32-NEXT: movl $72, %eax18; WIN32-NEXT: xorl %edx, %edx19; WIN32-NEXT: xorl %ecx, %ecx20; WIN32-NEXT: retl21 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 8)22 ret {i64, i1} %123}24 25define {i64, i1} @t2() nounwind {26; CHECK-LABEL: t2:27; CHECK: # %bb.0:28; CHECK-NEXT: xorl %eax, %eax29; CHECK-NEXT: xorl %edx, %edx30; CHECK-NEXT: retq31;32; WIN32-LABEL: t2:33; WIN32: # %bb.0:34; WIN32-NEXT: xorl %eax, %eax35; WIN32-NEXT: xorl %edx, %edx36; WIN32-NEXT: xorl %ecx, %ecx37; WIN32-NEXT: retl38 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 0)39 ret {i64, i1} %140}41 42define {i64, i1} @t3() nounwind {43; CHECK-LABEL: t3:44; CHECK: # %bb.0:45; CHECK-NEXT: movq $-9, %rax46; CHECK-NEXT: movb $1, %dl47; CHECK-NEXT: retq48;49; WIN32-LABEL: t3:50; WIN32: # %bb.0:51; WIN32-NEXT: movl $-9, %eax52; WIN32-NEXT: movl $-1, %edx53; WIN32-NEXT: movb $1, %cl54; WIN32-NEXT: retl55 %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 -1)56 ret {i64, i1} %157}58 59; SMULO60define zeroext i1 @smuloi8(i8 %v1, i8 %v2, ptr %res) {61; SDAG-LABEL: smuloi8:62; SDAG: # %bb.0:63; SDAG-NEXT: movl %edi, %eax64; SDAG-NEXT: # kill: def $al killed $al killed $eax65; SDAG-NEXT: imulb %sil66; SDAG-NEXT: seto %cl67; SDAG-NEXT: movb %al, (%rdx)68; SDAG-NEXT: movl %ecx, %eax69; SDAG-NEXT: retq70;71; FAST-LABEL: smuloi8:72; FAST: # %bb.0:73; FAST-NEXT: movl %edi, %eax74; FAST-NEXT: # kill: def $al killed $al killed $eax75; FAST-NEXT: imulb %sil76; FAST-NEXT: seto %cl77; FAST-NEXT: movb %al, (%rdx)78; FAST-NEXT: andb $1, %cl79; FAST-NEXT: movl %ecx, %eax80; FAST-NEXT: retq81;82; WIN64-LABEL: smuloi8:83; WIN64: # %bb.0:84; WIN64-NEXT: movl %ecx, %eax85; WIN64-NEXT: imulb %dl86; WIN64-NEXT: seto %cl87; WIN64-NEXT: movb %al, (%r8)88; WIN64-NEXT: movl %ecx, %eax89; WIN64-NEXT: retq90;91; WIN32-LABEL: smuloi8:92; WIN32: # %bb.0:93; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx94; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax95; WIN32-NEXT: imulb {{[0-9]+}}(%esp)96; WIN32-NEXT: seto %cl97; WIN32-NEXT: movb %al, (%edx)98; WIN32-NEXT: movl %ecx, %eax99; WIN32-NEXT: retl100 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)101 %val = extractvalue {i8, i1} %t, 0102 %obit = extractvalue {i8, i1} %t, 1103 store i8 %val, ptr %res104 ret i1 %obit105}106 107define zeroext i1 @smuloi16(i16 %v1, i16 %v2, ptr %res) {108; SDAG-LABEL: smuloi16:109; SDAG: # %bb.0:110; SDAG-NEXT: imulw %si, %di111; SDAG-NEXT: seto %al112; SDAG-NEXT: movw %di, (%rdx)113; SDAG-NEXT: retq114;115; FAST-LABEL: smuloi16:116; FAST: # %bb.0:117; FAST-NEXT: imulw %si, %di118; FAST-NEXT: seto %al119; FAST-NEXT: movw %di, (%rdx)120; FAST-NEXT: andb $1, %al121; FAST-NEXT: retq122;123; WIN64-LABEL: smuloi16:124; WIN64: # %bb.0:125; WIN64-NEXT: imulw %dx, %cx126; WIN64-NEXT: seto %al127; WIN64-NEXT: movw %cx, (%r8)128; WIN64-NEXT: retq129;130; WIN32-LABEL: smuloi16:131; WIN32: # %bb.0:132; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx133; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %edx134; WIN32-NEXT: imulw {{[0-9]+}}(%esp), %dx135; WIN32-NEXT: seto %al136; WIN32-NEXT: movw %dx, (%ecx)137; WIN32-NEXT: retl138 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)139 %val = extractvalue {i16, i1} %t, 0140 %obit = extractvalue {i16, i1} %t, 1141 store i16 %val, ptr %res142 ret i1 %obit143}144 145define zeroext i1 @smuloi32(i32 %v1, i32 %v2, ptr %res) {146; SDAG-LABEL: smuloi32:147; SDAG: # %bb.0:148; SDAG-NEXT: imull %esi, %edi149; SDAG-NEXT: seto %al150; SDAG-NEXT: movl %edi, (%rdx)151; SDAG-NEXT: retq152;153; FAST-LABEL: smuloi32:154; FAST: # %bb.0:155; FAST-NEXT: imull %esi, %edi156; FAST-NEXT: seto %al157; FAST-NEXT: movl %edi, (%rdx)158; FAST-NEXT: andb $1, %al159; FAST-NEXT: retq160;161; WIN64-LABEL: smuloi32:162; WIN64: # %bb.0:163; WIN64-NEXT: imull %edx, %ecx164; WIN64-NEXT: seto %al165; WIN64-NEXT: movl %ecx, (%r8)166; WIN64-NEXT: retq167;168; WIN32-LABEL: smuloi32:169; WIN32: # %bb.0:170; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx171; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx172; WIN32-NEXT: imull {{[0-9]+}}(%esp), %edx173; WIN32-NEXT: seto %al174; WIN32-NEXT: movl %edx, (%ecx)175; WIN32-NEXT: retl176 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)177 %val = extractvalue {i32, i1} %t, 0178 %obit = extractvalue {i32, i1} %t, 1179 store i32 %val, ptr %res180 ret i1 %obit181}182 183define zeroext i1 @smuloi64(i64 %v1, i64 %v2, ptr %res) {184; SDAG-LABEL: smuloi64:185; SDAG: # %bb.0:186; SDAG-NEXT: imulq %rsi, %rdi187; SDAG-NEXT: seto %al188; SDAG-NEXT: movq %rdi, (%rdx)189; SDAG-NEXT: retq190;191; FAST-LABEL: smuloi64:192; FAST: # %bb.0:193; FAST-NEXT: imulq %rsi, %rdi194; FAST-NEXT: seto %al195; FAST-NEXT: movq %rdi, (%rdx)196; FAST-NEXT: andb $1, %al197; FAST-NEXT: retq198;199; WIN64-LABEL: smuloi64:200; WIN64: # %bb.0:201; WIN64-NEXT: imulq %rdx, %rcx202; WIN64-NEXT: seto %al203; WIN64-NEXT: movq %rcx, (%r8)204; WIN64-NEXT: retq205;206; WIN32-LABEL: smuloi64:207; WIN32: # %bb.0:208; WIN32-NEXT: pushl %ebp209; WIN32-NEXT: pushl %ebx210; WIN32-NEXT: pushl %edi211; WIN32-NEXT: pushl %esi212; WIN32-NEXT: subl $8, %esp213; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebx214; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax215; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi216; WIN32-NEXT: movl %edi, %esi217; WIN32-NEXT: sarl $31, %esi218; WIN32-NEXT: imull %ebx, %esi219; WIN32-NEXT: mull %ebx220; WIN32-NEXT: movl %edx, %ecx221; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill222; WIN32-NEXT: movl %edi, %eax223; WIN32-NEXT: mull %ebx224; WIN32-NEXT: movl %edx, %ebx225; WIN32-NEXT: movl %eax, %ebp226; WIN32-NEXT: addl %ecx, %ebp227; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx228; WIN32-NEXT: adcl %esi, %ebx229; WIN32-NEXT: movl %ebx, %edi230; WIN32-NEXT: sarl $31, %edi231; WIN32-NEXT: movl %ecx, %esi232; WIN32-NEXT: sarl $31, %esi233; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax234; WIN32-NEXT: imull %eax, %esi235; WIN32-NEXT: mull %ecx236; WIN32-NEXT: movl %edx, %ecx237; WIN32-NEXT: addl %ebp, %eax238; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill239; WIN32-NEXT: adcl %esi, %ecx240; WIN32-NEXT: movl %ecx, %ebp241; WIN32-NEXT: sarl $31, %ebp242; WIN32-NEXT: addl %ebx, %ecx243; WIN32-NEXT: adcl %edi, %ebp244; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax245; WIN32-NEXT: imull {{[0-9]+}}(%esp)246; WIN32-NEXT: addl %ecx, %eax247; WIN32-NEXT: adcl %ebp, %edx248; WIN32-NEXT: movl (%esp), %esi # 4-byte Reload249; WIN32-NEXT: movl %esi, %ecx250; WIN32-NEXT: sarl $31, %ecx251; WIN32-NEXT: xorl %ecx, %edx252; WIN32-NEXT: xorl %eax, %ecx253; WIN32-NEXT: orl %edx, %ecx254; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax255; WIN32-NEXT: movl %esi, 4(%eax)256; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload257; WIN32-NEXT: movl %ecx, (%eax)258; WIN32-NEXT: setne %al259; WIN32-NEXT: addl $8, %esp260; WIN32-NEXT: popl %esi261; WIN32-NEXT: popl %edi262; WIN32-NEXT: popl %ebx263; WIN32-NEXT: popl %ebp264; WIN32-NEXT: retl265 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)266 %val = extractvalue {i64, i1} %t, 0267 %obit = extractvalue {i64, i1} %t, 1268 store i64 %val, ptr %res269 ret i1 %obit270}271 272; UMULO273define zeroext i1 @umuloi8(i8 %v1, i8 %v2, ptr %res) {274; SDAG-LABEL: umuloi8:275; SDAG: # %bb.0:276; SDAG-NEXT: movl %edi, %eax277; SDAG-NEXT: # kill: def $al killed $al killed $eax278; SDAG-NEXT: mulb %sil279; SDAG-NEXT: seto %cl280; SDAG-NEXT: movb %al, (%rdx)281; SDAG-NEXT: movl %ecx, %eax282; SDAG-NEXT: retq283;284; FAST-LABEL: umuloi8:285; FAST: # %bb.0:286; FAST-NEXT: movl %edi, %eax287; FAST-NEXT: # kill: def $al killed $al killed $eax288; FAST-NEXT: mulb %sil289; FAST-NEXT: seto %cl290; FAST-NEXT: movb %al, (%rdx)291; FAST-NEXT: andb $1, %cl292; FAST-NEXT: movl %ecx, %eax293; FAST-NEXT: retq294;295; WIN64-LABEL: umuloi8:296; WIN64: # %bb.0:297; WIN64-NEXT: movl %ecx, %eax298; WIN64-NEXT: mulb %dl299; WIN64-NEXT: seto %cl300; WIN64-NEXT: movb %al, (%r8)301; WIN64-NEXT: movl %ecx, %eax302; WIN64-NEXT: retq303;304; WIN32-LABEL: umuloi8:305; WIN32: # %bb.0:306; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx307; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax308; WIN32-NEXT: mulb {{[0-9]+}}(%esp)309; WIN32-NEXT: seto %cl310; WIN32-NEXT: movb %al, (%edx)311; WIN32-NEXT: movl %ecx, %eax312; WIN32-NEXT: retl313 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)314 %val = extractvalue {i8, i1} %t, 0315 %obit = extractvalue {i8, i1} %t, 1316 store i8 %val, ptr %res317 ret i1 %obit318}319 320define zeroext i1 @umuloi16(i16 %v1, i16 %v2, ptr %res) {321; SDAG-LABEL: umuloi16:322; SDAG: # %bb.0:323; SDAG-NEXT: movq %rdx, %rcx324; SDAG-NEXT: movl %edi, %eax325; SDAG-NEXT: # kill: def $ax killed $ax killed $eax326; SDAG-NEXT: mulw %si327; SDAG-NEXT: seto %dl328; SDAG-NEXT: movw %ax, (%rcx)329; SDAG-NEXT: movl %edx, %eax330; SDAG-NEXT: retq331;332; FAST-LABEL: umuloi16:333; FAST: # %bb.0:334; FAST-NEXT: movq %rdx, %rcx335; FAST-NEXT: movl %edi, %eax336; FAST-NEXT: # kill: def $ax killed $ax killed $eax337; FAST-NEXT: mulw %si338; FAST-NEXT: seto %dl339; FAST-NEXT: movw %ax, (%rcx)340; FAST-NEXT: andb $1, %dl341; FAST-NEXT: movl %edx, %eax342; FAST-NEXT: retq343;344; WIN64-LABEL: umuloi16:345; WIN64: # %bb.0:346; WIN64-NEXT: movl %ecx, %eax347; WIN64-NEXT: mulw %dx348; WIN64-NEXT: seto %cl349; WIN64-NEXT: movw %ax, (%r8)350; WIN64-NEXT: movl %ecx, %eax351; WIN64-NEXT: retq352;353; WIN32-LABEL: umuloi16:354; WIN32: # %bb.0:355; WIN32-NEXT: pushl %esi356; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi357; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax358; WIN32-NEXT: mulw {{[0-9]+}}(%esp)359; WIN32-NEXT: seto %cl360; WIN32-NEXT: movw %ax, (%esi)361; WIN32-NEXT: movl %ecx, %eax362; WIN32-NEXT: popl %esi363; WIN32-NEXT: retl364 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)365 %val = extractvalue {i16, i1} %t, 0366 %obit = extractvalue {i16, i1} %t, 1367 store i16 %val, ptr %res368 ret i1 %obit369}370 371define zeroext i1 @umuloi32(i32 %v1, i32 %v2, ptr %res) {372; SDAG-LABEL: umuloi32:373; SDAG: # %bb.0:374; SDAG-NEXT: movq %rdx, %rcx375; SDAG-NEXT: movl %edi, %eax376; SDAG-NEXT: mull %esi377; SDAG-NEXT: seto %dl378; SDAG-NEXT: movl %eax, (%rcx)379; SDAG-NEXT: movl %edx, %eax380; SDAG-NEXT: retq381;382; FAST-LABEL: umuloi32:383; FAST: # %bb.0:384; FAST-NEXT: movq %rdx, %rcx385; FAST-NEXT: movl %edi, %eax386; FAST-NEXT: mull %esi387; FAST-NEXT: seto %dl388; FAST-NEXT: movl %eax, (%rcx)389; FAST-NEXT: andb $1, %dl390; FAST-NEXT: movl %edx, %eax391; FAST-NEXT: retq392;393; WIN64-LABEL: umuloi32:394; WIN64: # %bb.0:395; WIN64-NEXT: movl %ecx, %eax396; WIN64-NEXT: mull %edx397; WIN64-NEXT: seto %cl398; WIN64-NEXT: movl %eax, (%r8)399; WIN64-NEXT: movl %ecx, %eax400; WIN64-NEXT: retq401;402; WIN32-LABEL: umuloi32:403; WIN32: # %bb.0:404; WIN32-NEXT: pushl %esi405; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi406; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax407; WIN32-NEXT: mull {{[0-9]+}}(%esp)408; WIN32-NEXT: seto %cl409; WIN32-NEXT: movl %eax, (%esi)410; WIN32-NEXT: movl %ecx, %eax411; WIN32-NEXT: popl %esi412; WIN32-NEXT: retl413 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)414 %val = extractvalue {i32, i1} %t, 0415 %obit = extractvalue {i32, i1} %t, 1416 store i32 %val, ptr %res417 ret i1 %obit418}419 420define zeroext i1 @umuloi64(i64 %v1, i64 %v2, ptr %res) {421; SDAG-LABEL: umuloi64:422; SDAG: # %bb.0:423; SDAG-NEXT: movq %rdx, %rcx424; SDAG-NEXT: movq %rdi, %rax425; SDAG-NEXT: mulq %rsi426; SDAG-NEXT: seto %dl427; SDAG-NEXT: movq %rax, (%rcx)428; SDAG-NEXT: movl %edx, %eax429; SDAG-NEXT: retq430;431; FAST-LABEL: umuloi64:432; FAST: # %bb.0:433; FAST-NEXT: movq %rdx, %rcx434; FAST-NEXT: movq %rdi, %rax435; FAST-NEXT: mulq %rsi436; FAST-NEXT: seto %dl437; FAST-NEXT: movq %rax, (%rcx)438; FAST-NEXT: andb $1, %dl439; FAST-NEXT: movl %edx, %eax440; FAST-NEXT: retq441;442; WIN64-LABEL: umuloi64:443; WIN64: # %bb.0:444; WIN64-NEXT: movq %rcx, %rax445; WIN64-NEXT: mulq %rdx446; WIN64-NEXT: seto %cl447; WIN64-NEXT: movq %rax, (%r8)448; WIN64-NEXT: movl %ecx, %eax449; WIN64-NEXT: retq450;451; WIN32-LABEL: umuloi64:452; WIN32: # %bb.0:453; WIN32-NEXT: pushl %ebp454; WIN32-NEXT: pushl %ebx455; WIN32-NEXT: pushl %edi456; WIN32-NEXT: pushl %esi457; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp458; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax459; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi460; WIN32-NEXT: testl %esi, %esi461; WIN32-NEXT: setne %dl462; WIN32-NEXT: testl %eax, %eax463; WIN32-NEXT: setne %cl464; WIN32-NEXT: andb %dl, %cl465; WIN32-NEXT: mull {{[0-9]+}}(%esp)466; WIN32-NEXT: movl %eax, %edi467; WIN32-NEXT: seto %bl468; WIN32-NEXT: movl %esi, %eax469; WIN32-NEXT: mull %ebp470; WIN32-NEXT: seto %ch471; WIN32-NEXT: orb %bl, %ch472; WIN32-NEXT: orb %cl, %ch473; WIN32-NEXT: leal (%edi,%eax), %esi474; WIN32-NEXT: movl %ebp, %eax475; WIN32-NEXT: mull {{[0-9]+}}(%esp)476; WIN32-NEXT: addl %esi, %edx477; WIN32-NEXT: setb %cl478; WIN32-NEXT: orb %ch, %cl479; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi480; WIN32-NEXT: movl %eax, (%esi)481; WIN32-NEXT: movl %edx, 4(%esi)482; WIN32-NEXT: movl %ecx, %eax483; WIN32-NEXT: popl %esi484; WIN32-NEXT: popl %edi485; WIN32-NEXT: popl %ebx486; WIN32-NEXT: popl %ebp487; WIN32-NEXT: retl488 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)489 %val = extractvalue {i64, i1} %t, 0490 %obit = extractvalue {i64, i1} %t, 1491 store i64 %val, ptr %res492 ret i1 %obit493}494 495;496; Check the use of the overflow bit in combination with a select instruction.497;498define i32 @smuloselecti32(i32 %v1, i32 %v2) {499; LINUX-LABEL: smuloselecti32:500; LINUX: # %bb.0:501; LINUX-NEXT: movl %esi, %eax502; LINUX-NEXT: movl %edi, %ecx503; LINUX-NEXT: imull %esi, %ecx504; LINUX-NEXT: cmovol %edi, %eax505; LINUX-NEXT: retq506;507; WIN64-LABEL: smuloselecti32:508; WIN64: # %bb.0:509; WIN64-NEXT: movl %edx, %eax510; WIN64-NEXT: movl %ecx, %edx511; WIN64-NEXT: imull %eax, %edx512; WIN64-NEXT: cmovol %ecx, %eax513; WIN64-NEXT: retq514;515; WIN32-LABEL: smuloselecti32:516; WIN32: # %bb.0:517; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx518; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax519; WIN32-NEXT: movl %eax, %edx520; WIN32-NEXT: imull %ecx, %edx521; WIN32-NEXT: jo LBB11_2522; WIN32-NEXT: # %bb.1:523; WIN32-NEXT: movl %ecx, %eax524; WIN32-NEXT: LBB11_2:525; WIN32-NEXT: retl526 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)527 %obit = extractvalue {i32, i1} %t, 1528 %ret = select i1 %obit, i32 %v1, i32 %v2529 ret i32 %ret530}531 532define i64 @smuloselecti64(i64 %v1, i64 %v2) {533; LINUX-LABEL: smuloselecti64:534; LINUX: # %bb.0:535; LINUX-NEXT: movq %rsi, %rax536; LINUX-NEXT: movq %rdi, %rcx537; LINUX-NEXT: imulq %rsi, %rcx538; LINUX-NEXT: cmovoq %rdi, %rax539; LINUX-NEXT: retq540;541; WIN64-LABEL: smuloselecti64:542; WIN64: # %bb.0:543; WIN64-NEXT: movq %rdx, %rax544; WIN64-NEXT: movq %rcx, %rdx545; WIN64-NEXT: imulq %rax, %rdx546; WIN64-NEXT: cmovoq %rcx, %rax547; WIN64-NEXT: retq548;549; WIN32-LABEL: smuloselecti64:550; WIN32: # %bb.0:551; WIN32-NEXT: pushl %ebp552; WIN32-NEXT: pushl %ebx553; WIN32-NEXT: pushl %edi554; WIN32-NEXT: pushl %esi555; WIN32-NEXT: pushl %eax556; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi557; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax558; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebx559; WIN32-NEXT: movl %ebx, %esi560; WIN32-NEXT: sarl $31, %esi561; WIN32-NEXT: imull %edi, %esi562; WIN32-NEXT: mull %edi563; WIN32-NEXT: movl %edx, %ecx564; WIN32-NEXT: movl %ebx, %eax565; WIN32-NEXT: mull %edi566; WIN32-NEXT: movl %edx, %ebx567; WIN32-NEXT: movl %eax, %ebp568; WIN32-NEXT: addl %ecx, %ebp569; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx570; WIN32-NEXT: adcl %esi, %ebx571; WIN32-NEXT: movl %ebx, %eax572; WIN32-NEXT: sarl $31, %eax573; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill574; WIN32-NEXT: movl %ecx, %esi575; WIN32-NEXT: sarl $31, %esi576; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax577; WIN32-NEXT: imull %eax, %esi578; WIN32-NEXT: mull %ecx579; WIN32-NEXT: movl %edx, %ecx580; WIN32-NEXT: movl %eax, %edi581; WIN32-NEXT: addl %ebp, %edi582; WIN32-NEXT: adcl %esi, %ecx583; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi584; WIN32-NEXT: movl %ecx, %ebp585; WIN32-NEXT: sarl $31, %ebp586; WIN32-NEXT: addl %ebx, %ecx587; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebx588; WIN32-NEXT: adcl (%esp), %ebp # 4-byte Folded Reload589; WIN32-NEXT: movl %esi, %eax590; WIN32-NEXT: imull %ebx591; WIN32-NEXT: addl %ecx, %eax592; WIN32-NEXT: adcl %ebp, %edx593; WIN32-NEXT: sarl $31, %edi594; WIN32-NEXT: xorl %edi, %edx595; WIN32-NEXT: xorl %eax, %edi596; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax597; WIN32-NEXT: orl %edx, %edi598; WIN32-NEXT: jne LBB12_2599; WIN32-NEXT: # %bb.1:600; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax601; WIN32-NEXT: movl %ebx, %esi602; WIN32-NEXT: LBB12_2:603; WIN32-NEXT: movl %esi, %edx604; WIN32-NEXT: addl $4, %esp605; WIN32-NEXT: popl %esi606; WIN32-NEXT: popl %edi607; WIN32-NEXT: popl %ebx608; WIN32-NEXT: popl %ebp609; WIN32-NEXT: retl610 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)611 %obit = extractvalue {i64, i1} %t, 1612 %ret = select i1 %obit, i64 %v1, i64 %v2613 ret i64 %ret614}615 616define i32 @umuloselecti32(i32 %v1, i32 %v2) {617; LINUX-LABEL: umuloselecti32:618; LINUX: # %bb.0:619; LINUX-NEXT: movl %edi, %eax620; LINUX-NEXT: mull %esi621; LINUX-NEXT: cmovol %edi, %esi622; LINUX-NEXT: movl %esi, %eax623; LINUX-NEXT: retq624;625; WIN64-LABEL: umuloselecti32:626; WIN64: # %bb.0:627; WIN64-NEXT: movl %edx, %r8d628; WIN64-NEXT: movl %ecx, %eax629; WIN64-NEXT: mull %edx630; WIN64-NEXT: cmovol %ecx, %r8d631; WIN64-NEXT: movl %r8d, %eax632; WIN64-NEXT: retq633;634; WIN32-LABEL: umuloselecti32:635; WIN32: # %bb.0:636; WIN32-NEXT: pushl %esi637; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx638; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi639; WIN32-NEXT: movl %ecx, %eax640; WIN32-NEXT: mull %esi641; WIN32-NEXT: jo LBB13_2642; WIN32-NEXT: # %bb.1:643; WIN32-NEXT: movl %esi, %ecx644; WIN32-NEXT: LBB13_2:645; WIN32-NEXT: movl %ecx, %eax646; WIN32-NEXT: popl %esi647; WIN32-NEXT: retl648 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)649 %obit = extractvalue {i32, i1} %t, 1650 %ret = select i1 %obit, i32 %v1, i32 %v2651 ret i32 %ret652}653 654define i64 @umuloselecti64(i64 %v1, i64 %v2) {655; LINUX-LABEL: umuloselecti64:656; LINUX: # %bb.0:657; LINUX-NEXT: movq %rdi, %rax658; LINUX-NEXT: mulq %rsi659; LINUX-NEXT: cmovoq %rdi, %rsi660; LINUX-NEXT: movq %rsi, %rax661; LINUX-NEXT: retq662;663; WIN64-LABEL: umuloselecti64:664; WIN64: # %bb.0:665; WIN64-NEXT: movq %rdx, %r8666; WIN64-NEXT: movq %rcx, %rax667; WIN64-NEXT: mulq %rdx668; WIN64-NEXT: cmovoq %rcx, %r8669; WIN64-NEXT: movq %r8, %rax670; WIN64-NEXT: retq671;672; WIN32-LABEL: umuloselecti64:673; WIN32: # %bb.0:674; WIN32-NEXT: pushl %ebp675; WIN32-NEXT: pushl %ebx676; WIN32-NEXT: pushl %edi677; WIN32-NEXT: pushl %esi678; WIN32-NEXT: pushl %eax679; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx680; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi681; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi682; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp683; WIN32-NEXT: testl %ebp, %ebp684; WIN32-NEXT: setne %al685; WIN32-NEXT: testl %esi, %esi686; WIN32-NEXT: setne %bl687; WIN32-NEXT: andb %al, %bl688; WIN32-NEXT: movl %esi, %eax689; WIN32-NEXT: mull %edi690; WIN32-NEXT: movl %edi, %edx691; WIN32-NEXT: movl %eax, %edi692; WIN32-NEXT: seto {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Spill693; WIN32-NEXT: movl %ebp, %eax694; WIN32-NEXT: movl %edx, %ebp695; WIN32-NEXT: mull %ecx696; WIN32-NEXT: seto %bh697; WIN32-NEXT: orb {{[-0-9]+}}(%e{{[sb]}}p), %bh # 1-byte Folded Reload698; WIN32-NEXT: orb %bl, %bh699; WIN32-NEXT: addl %eax, %edi700; WIN32-NEXT: movl %ecx, %eax701; WIN32-NEXT: mull %ebp702; WIN32-NEXT: addl %edi, %edx703; WIN32-NEXT: setb %al704; WIN32-NEXT: orb %bh, %al705; WIN32-NEXT: testb %al, %al706; WIN32-NEXT: jne LBB14_2707; WIN32-NEXT: # %bb.1:708; WIN32-NEXT: movl %ebp, %ecx709; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi710; WIN32-NEXT: LBB14_2:711; WIN32-NEXT: movl %ecx, %eax712; WIN32-NEXT: movl %esi, %edx713; WIN32-NEXT: addl $4, %esp714; WIN32-NEXT: popl %esi715; WIN32-NEXT: popl %edi716; WIN32-NEXT: popl %ebx717; WIN32-NEXT: popl %ebp718; WIN32-NEXT: retl719 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)720 %obit = extractvalue {i64, i1} %t, 1721 %ret = select i1 %obit, i64 %v1, i64 %v2722 ret i64 %ret723}724 725;726; Check the use of the overflow bit in combination with a branch instruction.727;728define zeroext i1 @smulobri8(i8 %v1, i8 %v2) {729; SDAG-LABEL: smulobri8:730; SDAG: # %bb.0:731; SDAG-NEXT: movl %edi, %eax732; SDAG-NEXT: # kill: def $al killed $al killed $eax733; SDAG-NEXT: imulb %sil734; SDAG-NEXT: jo .LBB15_1735; SDAG-NEXT: # %bb.2: # %continue736; SDAG-NEXT: movb $1, %al737; SDAG-NEXT: retq738; SDAG-NEXT: .LBB15_1: # %overflow739; SDAG-NEXT: xorl %eax, %eax740; SDAG-NEXT: retq741;742; FAST-LABEL: smulobri8:743; FAST: # %bb.0:744; FAST-NEXT: movl %edi, %eax745; FAST-NEXT: # kill: def $al killed $al killed $eax746; FAST-NEXT: imulb %sil747; FAST-NEXT: seto %al748; FAST-NEXT: testb $1, %al749; FAST-NEXT: jne .LBB15_1750; FAST-NEXT: # %bb.2: # %continue751; FAST-NEXT: movb $1, %al752; FAST-NEXT: andb $1, %al753; FAST-NEXT: retq754; FAST-NEXT: .LBB15_1: # %overflow755; FAST-NEXT: xorl %eax, %eax756; FAST-NEXT: andb $1, %al757; FAST-NEXT: # kill: def $al killed $al killed $eax758; FAST-NEXT: retq759;760; WIN64-LABEL: smulobri8:761; WIN64: # %bb.0:762; WIN64-NEXT: movl %ecx, %eax763; WIN64-NEXT: imulb %dl764; WIN64-NEXT: jo .LBB15_1765; WIN64-NEXT: # %bb.2: # %continue766; WIN64-NEXT: movb $1, %al767; WIN64-NEXT: retq768; WIN64-NEXT: .LBB15_1: # %overflow769; WIN64-NEXT: xorl %eax, %eax770; WIN64-NEXT: retq771;772; WIN32-LABEL: smulobri8:773; WIN32: # %bb.0:774; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax775; WIN32-NEXT: imulb {{[0-9]+}}(%esp)776; WIN32-NEXT: jo LBB15_1777; WIN32-NEXT: # %bb.2: # %continue778; WIN32-NEXT: movb $1, %al779; WIN32-NEXT: retl780; WIN32-NEXT: LBB15_1: # %overflow781; WIN32-NEXT: xorl %eax, %eax782; WIN32-NEXT: retl783 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)784 %val = extractvalue {i8, i1} %t, 0785 %obit = extractvalue {i8, i1} %t, 1786 br i1 %obit, label %overflow, label %continue, !prof !0787 788overflow:789 ret i1 false790 791continue:792 ret i1 true793}794 795define zeroext i1 @smulobri16(i16 %v1, i16 %v2) {796; SDAG-LABEL: smulobri16:797; SDAG: # %bb.0:798; SDAG-NEXT: imulw %si, %di799; SDAG-NEXT: jo .LBB16_1800; SDAG-NEXT: # %bb.2: # %continue801; SDAG-NEXT: movb $1, %al802; SDAG-NEXT: retq803; SDAG-NEXT: .LBB16_1: # %overflow804; SDAG-NEXT: xorl %eax, %eax805; SDAG-NEXT: retq806;807; FAST-LABEL: smulobri16:808; FAST: # %bb.0:809; FAST-NEXT: imulw %si, %di810; FAST-NEXT: seto %al811; FAST-NEXT: testb $1, %al812; FAST-NEXT: jne .LBB16_1813; FAST-NEXT: # %bb.2: # %continue814; FAST-NEXT: movb $1, %al815; FAST-NEXT: andb $1, %al816; FAST-NEXT: retq817; FAST-NEXT: .LBB16_1: # %overflow818; FAST-NEXT: xorl %eax, %eax819; FAST-NEXT: andb $1, %al820; FAST-NEXT: # kill: def $al killed $al killed $eax821; FAST-NEXT: retq822;823; WIN64-LABEL: smulobri16:824; WIN64: # %bb.0:825; WIN64-NEXT: imulw %dx, %cx826; WIN64-NEXT: jo .LBB16_1827; WIN64-NEXT: # %bb.2: # %continue828; WIN64-NEXT: movb $1, %al829; WIN64-NEXT: retq830; WIN64-NEXT: .LBB16_1: # %overflow831; WIN64-NEXT: xorl %eax, %eax832; WIN64-NEXT: retq833;834; WIN32-LABEL: smulobri16:835; WIN32: # %bb.0:836; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax837; WIN32-NEXT: imulw {{[0-9]+}}(%esp), %ax838; WIN32-NEXT: jo LBB16_1839; WIN32-NEXT: # %bb.2: # %continue840; WIN32-NEXT: movb $1, %al841; WIN32-NEXT: retl842; WIN32-NEXT: LBB16_1: # %overflow843; WIN32-NEXT: xorl %eax, %eax844; WIN32-NEXT: retl845 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)846 %val = extractvalue {i16, i1} %t, 0847 %obit = extractvalue {i16, i1} %t, 1848 br i1 %obit, label %overflow, label %continue, !prof !0849 850overflow:851 ret i1 false852 853continue:854 ret i1 true855}856 857define zeroext i1 @smulobri32(i32 %v1, i32 %v2) {858; SDAG-LABEL: smulobri32:859; SDAG: # %bb.0:860; SDAG-NEXT: imull %esi, %edi861; SDAG-NEXT: jo .LBB17_1862; SDAG-NEXT: # %bb.2: # %continue863; SDAG-NEXT: movb $1, %al864; SDAG-NEXT: retq865; SDAG-NEXT: .LBB17_1: # %overflow866; SDAG-NEXT: xorl %eax, %eax867; SDAG-NEXT: retq868;869; FAST-LABEL: smulobri32:870; FAST: # %bb.0:871; FAST-NEXT: imull %esi, %edi872; FAST-NEXT: jo .LBB17_1873; FAST-NEXT: # %bb.2: # %continue874; FAST-NEXT: movb $1, %al875; FAST-NEXT: andb $1, %al876; FAST-NEXT: retq877; FAST-NEXT: .LBB17_1: # %overflow878; FAST-NEXT: xorl %eax, %eax879; FAST-NEXT: andb $1, %al880; FAST-NEXT: # kill: def $al killed $al killed $eax881; FAST-NEXT: retq882;883; WIN64-LABEL: smulobri32:884; WIN64: # %bb.0:885; WIN64-NEXT: imull %edx, %ecx886; WIN64-NEXT: jo .LBB17_1887; WIN64-NEXT: # %bb.2: # %continue888; WIN64-NEXT: movb $1, %al889; WIN64-NEXT: retq890; WIN64-NEXT: .LBB17_1: # %overflow891; WIN64-NEXT: xorl %eax, %eax892; WIN64-NEXT: retq893;894; WIN32-LABEL: smulobri32:895; WIN32: # %bb.0:896; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax897; WIN32-NEXT: imull {{[0-9]+}}(%esp), %eax898; WIN32-NEXT: jo LBB17_1899; WIN32-NEXT: # %bb.2: # %continue900; WIN32-NEXT: movb $1, %al901; WIN32-NEXT: retl902; WIN32-NEXT: LBB17_1: # %overflow903; WIN32-NEXT: xorl %eax, %eax904; WIN32-NEXT: retl905 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)906 %val = extractvalue {i32, i1} %t, 0907 %obit = extractvalue {i32, i1} %t, 1908 br i1 %obit, label %overflow, label %continue, !prof !0909 910overflow:911 ret i1 false912 913continue:914 ret i1 true915}916 917define zeroext i1 @smulobri64(i64 %v1, i64 %v2) {918; SDAG-LABEL: smulobri64:919; SDAG: # %bb.0:920; SDAG-NEXT: imulq %rsi, %rdi921; SDAG-NEXT: jo .LBB18_1922; SDAG-NEXT: # %bb.2: # %continue923; SDAG-NEXT: movb $1, %al924; SDAG-NEXT: retq925; SDAG-NEXT: .LBB18_1: # %overflow926; SDAG-NEXT: xorl %eax, %eax927; SDAG-NEXT: retq928;929; FAST-LABEL: smulobri64:930; FAST: # %bb.0:931; FAST-NEXT: imulq %rsi, %rdi932; FAST-NEXT: jo .LBB18_1933; FAST-NEXT: # %bb.2: # %continue934; FAST-NEXT: movb $1, %al935; FAST-NEXT: andb $1, %al936; FAST-NEXT: retq937; FAST-NEXT: .LBB18_1: # %overflow938; FAST-NEXT: xorl %eax, %eax939; FAST-NEXT: andb $1, %al940; FAST-NEXT: # kill: def $al killed $al killed $eax941; FAST-NEXT: retq942;943; WIN64-LABEL: smulobri64:944; WIN64: # %bb.0:945; WIN64-NEXT: imulq %rdx, %rcx946; WIN64-NEXT: jo .LBB18_1947; WIN64-NEXT: # %bb.2: # %continue948; WIN64-NEXT: movb $1, %al949; WIN64-NEXT: retq950; WIN64-NEXT: .LBB18_1: # %overflow951; WIN64-NEXT: xorl %eax, %eax952; WIN64-NEXT: retq953;954; WIN32-LABEL: smulobri64:955; WIN32: # %bb.0:956; WIN32-NEXT: pushl %ebp957; WIN32-NEXT: pushl %ebx958; WIN32-NEXT: pushl %edi959; WIN32-NEXT: pushl %esi960; WIN32-NEXT: pushl %eax961; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi962; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi963; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp964; WIN32-NEXT: movl %ebp, %ecx965; WIN32-NEXT: sarl $31, %ecx966; WIN32-NEXT: imull %edi, %ecx967; WIN32-NEXT: movl %esi, %eax968; WIN32-NEXT: mull %edi969; WIN32-NEXT: movl %edx, %ebx970; WIN32-NEXT: movl %ebp, %eax971; WIN32-NEXT: mull %edi972; WIN32-NEXT: movl %edx, %edi973; WIN32-NEXT: movl %eax, %ebp974; WIN32-NEXT: addl %ebx, %ebp975; WIN32-NEXT: adcl %ecx, %edi976; WIN32-NEXT: movl %edi, %eax977; WIN32-NEXT: sarl $31, %eax978; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill979; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx980; WIN32-NEXT: movl %edx, %ecx981; WIN32-NEXT: sarl $31, %ecx982; WIN32-NEXT: imull %esi, %ecx983; WIN32-NEXT: movl %esi, %eax984; WIN32-NEXT: mull %edx985; WIN32-NEXT: movl %edx, %ebx986; WIN32-NEXT: movl %eax, %esi987; WIN32-NEXT: addl %ebp, %esi988; WIN32-NEXT: adcl %ecx, %ebx989; WIN32-NEXT: movl %ebx, %ebp990; WIN32-NEXT: sarl $31, %ebp991; WIN32-NEXT: addl %edi, %ebx992; WIN32-NEXT: adcl (%esp), %ebp # 4-byte Folded Reload993; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax994; WIN32-NEXT: imull {{[0-9]+}}(%esp)995; WIN32-NEXT: addl %ebx, %eax996; WIN32-NEXT: adcl %ebp, %edx997; WIN32-NEXT: sarl $31, %esi998; WIN32-NEXT: xorl %esi, %edx999; WIN32-NEXT: xorl %eax, %esi1000; WIN32-NEXT: orl %edx, %esi1001; WIN32-NEXT: jne LBB18_11002; WIN32-NEXT: # %bb.3: # %continue1003; WIN32-NEXT: movb $1, %al1004; WIN32-NEXT: LBB18_2: # %overflow1005; WIN32-NEXT: addl $4, %esp1006; WIN32-NEXT: popl %esi1007; WIN32-NEXT: popl %edi1008; WIN32-NEXT: popl %ebx1009; WIN32-NEXT: popl %ebp1010; WIN32-NEXT: retl1011; WIN32-NEXT: LBB18_1: # %overflow1012; WIN32-NEXT: xorl %eax, %eax1013; WIN32-NEXT: jmp LBB18_21014 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)1015 %val = extractvalue {i64, i1} %t, 01016 %obit = extractvalue {i64, i1} %t, 11017 br i1 %obit, label %overflow, label %continue, !prof !01018 1019overflow:1020 ret i1 false1021 1022continue:1023 ret i1 true1024}1025 1026define zeroext i1 @umulobri8(i8 %v1, i8 %v2) {1027; SDAG-LABEL: umulobri8:1028; SDAG: # %bb.0:1029; SDAG-NEXT: movl %edi, %eax1030; SDAG-NEXT: # kill: def $al killed $al killed $eax1031; SDAG-NEXT: mulb %sil1032; SDAG-NEXT: jo .LBB19_11033; SDAG-NEXT: # %bb.2: # %continue1034; SDAG-NEXT: movb $1, %al1035; SDAG-NEXT: retq1036; SDAG-NEXT: .LBB19_1: # %overflow1037; SDAG-NEXT: xorl %eax, %eax1038; SDAG-NEXT: retq1039;1040; FAST-LABEL: umulobri8:1041; FAST: # %bb.0:1042; FAST-NEXT: movl %edi, %eax1043; FAST-NEXT: # kill: def $al killed $al killed $eax1044; FAST-NEXT: mulb %sil1045; FAST-NEXT: seto %al1046; FAST-NEXT: testb $1, %al1047; FAST-NEXT: jne .LBB19_11048; FAST-NEXT: # %bb.2: # %continue1049; FAST-NEXT: movb $1, %al1050; FAST-NEXT: andb $1, %al1051; FAST-NEXT: retq1052; FAST-NEXT: .LBB19_1: # %overflow1053; FAST-NEXT: xorl %eax, %eax1054; FAST-NEXT: andb $1, %al1055; FAST-NEXT: # kill: def $al killed $al killed $eax1056; FAST-NEXT: retq1057;1058; WIN64-LABEL: umulobri8:1059; WIN64: # %bb.0:1060; WIN64-NEXT: movl %ecx, %eax1061; WIN64-NEXT: mulb %dl1062; WIN64-NEXT: jo .LBB19_11063; WIN64-NEXT: # %bb.2: # %continue1064; WIN64-NEXT: movb $1, %al1065; WIN64-NEXT: retq1066; WIN64-NEXT: .LBB19_1: # %overflow1067; WIN64-NEXT: xorl %eax, %eax1068; WIN64-NEXT: retq1069;1070; WIN32-LABEL: umulobri8:1071; WIN32: # %bb.0:1072; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax1073; WIN32-NEXT: mulb {{[0-9]+}}(%esp)1074; WIN32-NEXT: jo LBB19_11075; WIN32-NEXT: # %bb.2: # %continue1076; WIN32-NEXT: movb $1, %al1077; WIN32-NEXT: retl1078; WIN32-NEXT: LBB19_1: # %overflow1079; WIN32-NEXT: xorl %eax, %eax1080; WIN32-NEXT: retl1081 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)1082 %val = extractvalue {i8, i1} %t, 01083 %obit = extractvalue {i8, i1} %t, 11084 br i1 %obit, label %overflow, label %continue, !prof !01085 1086overflow:1087 ret i1 false1088 1089continue:1090 ret i1 true1091}1092 1093define zeroext i1 @umulobri16(i16 %v1, i16 %v2) {1094; SDAG-LABEL: umulobri16:1095; SDAG: # %bb.0:1096; SDAG-NEXT: movl %edi, %eax1097; SDAG-NEXT: # kill: def $ax killed $ax killed $eax1098; SDAG-NEXT: mulw %si1099; SDAG-NEXT: jo .LBB20_11100; SDAG-NEXT: # %bb.2: # %continue1101; SDAG-NEXT: movb $1, %al1102; SDAG-NEXT: retq1103; SDAG-NEXT: .LBB20_1: # %overflow1104; SDAG-NEXT: xorl %eax, %eax1105; SDAG-NEXT: retq1106;1107; FAST-LABEL: umulobri16:1108; FAST: # %bb.0:1109; FAST-NEXT: movl %edi, %eax1110; FAST-NEXT: # kill: def $ax killed $ax killed $eax1111; FAST-NEXT: mulw %si1112; FAST-NEXT: seto %al1113; FAST-NEXT: testb $1, %al1114; FAST-NEXT: jne .LBB20_11115; FAST-NEXT: # %bb.2: # %continue1116; FAST-NEXT: movb $1, %al1117; FAST-NEXT: andb $1, %al1118; FAST-NEXT: retq1119; FAST-NEXT: .LBB20_1: # %overflow1120; FAST-NEXT: xorl %eax, %eax1121; FAST-NEXT: andb $1, %al1122; FAST-NEXT: # kill: def $al killed $al killed $eax1123; FAST-NEXT: retq1124;1125; WIN64-LABEL: umulobri16:1126; WIN64: # %bb.0:1127; WIN64-NEXT: movl %ecx, %eax1128; WIN64-NEXT: mulw %dx1129; WIN64-NEXT: jo .LBB20_11130; WIN64-NEXT: # %bb.2: # %continue1131; WIN64-NEXT: movb $1, %al1132; WIN64-NEXT: retq1133; WIN64-NEXT: .LBB20_1: # %overflow1134; WIN64-NEXT: xorl %eax, %eax1135; WIN64-NEXT: retq1136;1137; WIN32-LABEL: umulobri16:1138; WIN32: # %bb.0:1139; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax1140; WIN32-NEXT: mulw {{[0-9]+}}(%esp)1141; WIN32-NEXT: jo LBB20_11142; WIN32-NEXT: # %bb.2: # %continue1143; WIN32-NEXT: movb $1, %al1144; WIN32-NEXT: retl1145; WIN32-NEXT: LBB20_1: # %overflow1146; WIN32-NEXT: xorl %eax, %eax1147; WIN32-NEXT: retl1148 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)1149 %val = extractvalue {i16, i1} %t, 01150 %obit = extractvalue {i16, i1} %t, 11151 br i1 %obit, label %overflow, label %continue, !prof !01152 1153overflow:1154 ret i1 false1155 1156continue:1157 ret i1 true1158}1159 1160define zeroext i1 @umulobri32(i32 %v1, i32 %v2) {1161; SDAG-LABEL: umulobri32:1162; SDAG: # %bb.0:1163; SDAG-NEXT: movl %edi, %eax1164; SDAG-NEXT: mull %esi1165; SDAG-NEXT: jo .LBB21_11166; SDAG-NEXT: # %bb.2: # %continue1167; SDAG-NEXT: movb $1, %al1168; SDAG-NEXT: retq1169; SDAG-NEXT: .LBB21_1: # %overflow1170; SDAG-NEXT: xorl %eax, %eax1171; SDAG-NEXT: retq1172;1173; FAST-LABEL: umulobri32:1174; FAST: # %bb.0:1175; FAST-NEXT: movl %edi, %eax1176; FAST-NEXT: mull %esi1177; FAST-NEXT: jo .LBB21_11178; FAST-NEXT: # %bb.2: # %continue1179; FAST-NEXT: movb $1, %al1180; FAST-NEXT: andb $1, %al1181; FAST-NEXT: retq1182; FAST-NEXT: .LBB21_1: # %overflow1183; FAST-NEXT: xorl %eax, %eax1184; FAST-NEXT: andb $1, %al1185; FAST-NEXT: # kill: def $al killed $al killed $eax1186; FAST-NEXT: retq1187;1188; WIN64-LABEL: umulobri32:1189; WIN64: # %bb.0:1190; WIN64-NEXT: movl %ecx, %eax1191; WIN64-NEXT: mull %edx1192; WIN64-NEXT: jo .LBB21_11193; WIN64-NEXT: # %bb.2: # %continue1194; WIN64-NEXT: movb $1, %al1195; WIN64-NEXT: retq1196; WIN64-NEXT: .LBB21_1: # %overflow1197; WIN64-NEXT: xorl %eax, %eax1198; WIN64-NEXT: retq1199;1200; WIN32-LABEL: umulobri32:1201; WIN32: # %bb.0:1202; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1203; WIN32-NEXT: mull {{[0-9]+}}(%esp)1204; WIN32-NEXT: jo LBB21_11205; WIN32-NEXT: # %bb.2: # %continue1206; WIN32-NEXT: movb $1, %al1207; WIN32-NEXT: retl1208; WIN32-NEXT: LBB21_1: # %overflow1209; WIN32-NEXT: xorl %eax, %eax1210; WIN32-NEXT: retl1211 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)1212 %val = extractvalue {i32, i1} %t, 01213 %obit = extractvalue {i32, i1} %t, 11214 br i1 %obit, label %overflow, label %continue, !prof !01215 1216overflow:1217 ret i1 false1218 1219continue:1220 ret i1 true1221}1222 1223define zeroext i1 @umulobri64(i64 %v1, i64 %v2) {1224; SDAG-LABEL: umulobri64:1225; SDAG: # %bb.0:1226; SDAG-NEXT: movq %rdi, %rax1227; SDAG-NEXT: mulq %rsi1228; SDAG-NEXT: jo .LBB22_11229; SDAG-NEXT: # %bb.2: # %continue1230; SDAG-NEXT: movb $1, %al1231; SDAG-NEXT: retq1232; SDAG-NEXT: .LBB22_1: # %overflow1233; SDAG-NEXT: xorl %eax, %eax1234; SDAG-NEXT: retq1235;1236; FAST-LABEL: umulobri64:1237; FAST: # %bb.0:1238; FAST-NEXT: movq %rdi, %rax1239; FAST-NEXT: mulq %rsi1240; FAST-NEXT: jo .LBB22_11241; FAST-NEXT: # %bb.2: # %continue1242; FAST-NEXT: movb $1, %al1243; FAST-NEXT: andb $1, %al1244; FAST-NEXT: retq1245; FAST-NEXT: .LBB22_1: # %overflow1246; FAST-NEXT: xorl %eax, %eax1247; FAST-NEXT: andb $1, %al1248; FAST-NEXT: # kill: def $al killed $al killed $eax1249; FAST-NEXT: retq1250;1251; WIN64-LABEL: umulobri64:1252; WIN64: # %bb.0:1253; WIN64-NEXT: movq %rcx, %rax1254; WIN64-NEXT: mulq %rdx1255; WIN64-NEXT: jo .LBB22_11256; WIN64-NEXT: # %bb.2: # %continue1257; WIN64-NEXT: movb $1, %al1258; WIN64-NEXT: retq1259; WIN64-NEXT: .LBB22_1: # %overflow1260; WIN64-NEXT: xorl %eax, %eax1261; WIN64-NEXT: retq1262;1263; WIN32-LABEL: umulobri64:1264; WIN32: # %bb.0:1265; WIN32-NEXT: pushl %ebp1266; WIN32-NEXT: pushl %ebx1267; WIN32-NEXT: pushl %edi1268; WIN32-NEXT: pushl %esi1269; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp1270; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1271; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi1272; WIN32-NEXT: testl %esi, %esi1273; WIN32-NEXT: setne %dl1274; WIN32-NEXT: testl %eax, %eax1275; WIN32-NEXT: setne %cl1276; WIN32-NEXT: andb %dl, %cl1277; WIN32-NEXT: mull {{[0-9]+}}(%esp)1278; WIN32-NEXT: movl %eax, %edi1279; WIN32-NEXT: seto %bl1280; WIN32-NEXT: movl %esi, %eax1281; WIN32-NEXT: mull %ebp1282; WIN32-NEXT: seto %ch1283; WIN32-NEXT: orb %bl, %ch1284; WIN32-NEXT: orb %cl, %ch1285; WIN32-NEXT: leal (%edi,%eax), %esi1286; WIN32-NEXT: movl %ebp, %eax1287; WIN32-NEXT: mull {{[0-9]+}}(%esp)1288; WIN32-NEXT: addl %esi, %edx1289; WIN32-NEXT: setb %al1290; WIN32-NEXT: orb %ch, %al1291; WIN32-NEXT: subb $1, %al1292; WIN32-NEXT: je LBB22_11293; WIN32-NEXT: # %bb.3: # %continue1294; WIN32-NEXT: movb $1, %al1295; WIN32-NEXT: LBB22_2: # %overflow1296; WIN32-NEXT: popl %esi1297; WIN32-NEXT: popl %edi1298; WIN32-NEXT: popl %ebx1299; WIN32-NEXT: popl %ebp1300; WIN32-NEXT: retl1301; WIN32-NEXT: LBB22_1: # %overflow1302; WIN32-NEXT: xorl %eax, %eax1303; WIN32-NEXT: jmp LBB22_21304 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)1305 %val = extractvalue {i64, i1} %t, 01306 %obit = extractvalue {i64, i1} %t, 11307 br i1 %obit, label %overflow, label %continue, !prof !01308 1309overflow:1310 ret i1 false1311 1312continue:1313 ret i1 true1314}1315 1316define i1 @bug27873(i64 %c1, i1 %c2) {1317; LINUX-LABEL: bug27873:1318; LINUX: # %bb.0:1319; LINUX-NEXT: movq %rdi, %rax1320; LINUX-NEXT: movl $160, %ecx1321; LINUX-NEXT: mulq %rcx1322; LINUX-NEXT: seto %al1323; LINUX-NEXT: orb %sil, %al1324; LINUX-NEXT: retq1325;1326; WIN64-LABEL: bug27873:1327; WIN64: # %bb.0:1328; WIN64-NEXT: movl %edx, %r8d1329; WIN64-NEXT: movq %rcx, %rax1330; WIN64-NEXT: movl $160, %ecx1331; WIN64-NEXT: mulq %rcx1332; WIN64-NEXT: seto %al1333; WIN64-NEXT: orb %r8b, %al1334; WIN64-NEXT: retq1335;1336; WIN32-LABEL: bug27873:1337; WIN32: # %bb.0:1338; WIN32-NEXT: pushl %ebx1339; WIN32-NEXT: movl $160, %eax1340; WIN32-NEXT: mull {{[0-9]+}}(%esp)1341; WIN32-NEXT: movl %eax, %ecx1342; WIN32-NEXT: seto %bl1343; WIN32-NEXT: movl $160, %eax1344; WIN32-NEXT: mull {{[0-9]+}}(%esp)1345; WIN32-NEXT: addl %ecx, %edx1346; WIN32-NEXT: setb %al1347; WIN32-NEXT: orb %bl, %al1348; WIN32-NEXT: orb {{[0-9]+}}(%esp), %al1349; WIN32-NEXT: popl %ebx1350; WIN32-NEXT: retl1351 %mul = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %c1, i64 160)1352 %mul.overflow = extractvalue { i64, i1 } %mul, 11353 %x1 = or i1 %c2, %mul.overflow1354 ret i1 %x11355}1356 1357define zeroext i1 @smuloi8_load(ptr %ptr1, i8 %v2, ptr %res) {1358; SDAG-LABEL: smuloi8_load:1359; SDAG: # %bb.0:1360; SDAG-NEXT: movl %esi, %eax1361; SDAG-NEXT: # kill: def $al killed $al killed $eax1362; SDAG-NEXT: imulb (%rdi)1363; SDAG-NEXT: seto %cl1364; SDAG-NEXT: movb %al, (%rdx)1365; SDAG-NEXT: movl %ecx, %eax1366; SDAG-NEXT: retq1367;1368; FAST-LABEL: smuloi8_load:1369; FAST: # %bb.0:1370; FAST-NEXT: movzbl (%rdi), %eax1371; FAST-NEXT: imulb %sil1372; FAST-NEXT: seto %cl1373; FAST-NEXT: movb %al, (%rdx)1374; FAST-NEXT: andb $1, %cl1375; FAST-NEXT: movl %ecx, %eax1376; FAST-NEXT: retq1377;1378; WIN64-LABEL: smuloi8_load:1379; WIN64: # %bb.0:1380; WIN64-NEXT: movl %edx, %eax1381; WIN64-NEXT: imulb (%rcx)1382; WIN64-NEXT: seto %cl1383; WIN64-NEXT: movb %al, (%r8)1384; WIN64-NEXT: movl %ecx, %eax1385; WIN64-NEXT: retq1386;1387; WIN32-LABEL: smuloi8_load:1388; WIN32: # %bb.0:1389; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx1390; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1391; WIN32-NEXT: movzbl (%eax), %eax1392; WIN32-NEXT: imulb {{[0-9]+}}(%esp)1393; WIN32-NEXT: seto %cl1394; WIN32-NEXT: movb %al, (%edx)1395; WIN32-NEXT: movl %ecx, %eax1396; WIN32-NEXT: retl1397 %v1 = load i8, ptr %ptr11398 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)1399 %val = extractvalue {i8, i1} %t, 01400 %obit = extractvalue {i8, i1} %t, 11401 store i8 %val, ptr %res1402 ret i1 %obit1403}1404 1405define zeroext i1 @smuloi8_load2(i8 %v1, ptr %ptr2, ptr %res) {1406; SDAG-LABEL: smuloi8_load2:1407; SDAG: # %bb.0:1408; SDAG-NEXT: movl %edi, %eax1409; SDAG-NEXT: # kill: def $al killed $al killed $eax1410; SDAG-NEXT: imulb (%rsi)1411; SDAG-NEXT: seto %cl1412; SDAG-NEXT: movb %al, (%rdx)1413; SDAG-NEXT: movl %ecx, %eax1414; SDAG-NEXT: retq1415;1416; FAST-LABEL: smuloi8_load2:1417; FAST: # %bb.0:1418; FAST-NEXT: movl %edi, %eax1419; FAST-NEXT: # kill: def $al killed $al killed $eax1420; FAST-NEXT: imulb (%rsi)1421; FAST-NEXT: seto %cl1422; FAST-NEXT: movb %al, (%rdx)1423; FAST-NEXT: andb $1, %cl1424; FAST-NEXT: movl %ecx, %eax1425; FAST-NEXT: retq1426;1427; WIN64-LABEL: smuloi8_load2:1428; WIN64: # %bb.0:1429; WIN64-NEXT: movl %ecx, %eax1430; WIN64-NEXT: imulb (%rdx)1431; WIN64-NEXT: seto %cl1432; WIN64-NEXT: movb %al, (%r8)1433; WIN64-NEXT: movl %ecx, %eax1434; WIN64-NEXT: retq1435;1436; WIN32-LABEL: smuloi8_load2:1437; WIN32: # %bb.0:1438; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx1439; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax1440; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx1441; WIN32-NEXT: imulb (%ecx)1442; WIN32-NEXT: seto %cl1443; WIN32-NEXT: movb %al, (%edx)1444; WIN32-NEXT: movl %ecx, %eax1445; WIN32-NEXT: retl1446 %v2 = load i8, ptr %ptr21447 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2)1448 %val = extractvalue {i8, i1} %t, 01449 %obit = extractvalue {i8, i1} %t, 11450 store i8 %val, ptr %res1451 ret i1 %obit1452}1453 1454define zeroext i1 @smuloi16_load(ptr %ptr1, i16 %v2, ptr %res) {1455; SDAG-LABEL: smuloi16_load:1456; SDAG: # %bb.0:1457; SDAG-NEXT: imulw (%rdi), %si1458; SDAG-NEXT: seto %al1459; SDAG-NEXT: movw %si, (%rdx)1460; SDAG-NEXT: retq1461;1462; FAST-LABEL: smuloi16_load:1463; FAST: # %bb.0:1464; FAST-NEXT: imulw (%rdi), %si1465; FAST-NEXT: seto %al1466; FAST-NEXT: movw %si, (%rdx)1467; FAST-NEXT: andb $1, %al1468; FAST-NEXT: retq1469;1470; WIN64-LABEL: smuloi16_load:1471; WIN64: # %bb.0:1472; WIN64-NEXT: imulw (%rcx), %dx1473; WIN64-NEXT: seto %al1474; WIN64-NEXT: movw %dx, (%r8)1475; WIN64-NEXT: retq1476;1477; WIN32-LABEL: smuloi16_load:1478; WIN32: # %bb.0:1479; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx1480; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1481; WIN32-NEXT: movzwl (%eax), %edx1482; WIN32-NEXT: imulw {{[0-9]+}}(%esp), %dx1483; WIN32-NEXT: seto %al1484; WIN32-NEXT: movw %dx, (%ecx)1485; WIN32-NEXT: retl1486 %v1 = load i16, ptr %ptr11487 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)1488 %val = extractvalue {i16, i1} %t, 01489 %obit = extractvalue {i16, i1} %t, 11490 store i16 %val, ptr %res1491 ret i1 %obit1492}1493 1494define zeroext i1 @smuloi16_load2(i16 %v1, ptr %ptr2, ptr %res) {1495; SDAG-LABEL: smuloi16_load2:1496; SDAG: # %bb.0:1497; SDAG-NEXT: imulw (%rsi), %di1498; SDAG-NEXT: seto %al1499; SDAG-NEXT: movw %di, (%rdx)1500; SDAG-NEXT: retq1501;1502; FAST-LABEL: smuloi16_load2:1503; FAST: # %bb.0:1504; FAST-NEXT: imulw (%rsi), %di1505; FAST-NEXT: seto %al1506; FAST-NEXT: movw %di, (%rdx)1507; FAST-NEXT: andb $1, %al1508; FAST-NEXT: retq1509;1510; WIN64-LABEL: smuloi16_load2:1511; WIN64: # %bb.0:1512; WIN64-NEXT: imulw (%rdx), %cx1513; WIN64-NEXT: seto %al1514; WIN64-NEXT: movw %cx, (%r8)1515; WIN64-NEXT: retq1516;1517; WIN32-LABEL: smuloi16_load2:1518; WIN32: # %bb.0:1519; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx1520; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1521; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %edx1522; WIN32-NEXT: imulw (%eax), %dx1523; WIN32-NEXT: seto %al1524; WIN32-NEXT: movw %dx, (%ecx)1525; WIN32-NEXT: retl1526 %v2 = load i16, ptr %ptr21527 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)1528 %val = extractvalue {i16, i1} %t, 01529 %obit = extractvalue {i16, i1} %t, 11530 store i16 %val, ptr %res1531 ret i1 %obit1532}1533 1534define zeroext i1 @smuloi32_load(ptr %ptr1, i32 %v2, ptr %res) {1535; SDAG-LABEL: smuloi32_load:1536; SDAG: # %bb.0:1537; SDAG-NEXT: imull (%rdi), %esi1538; SDAG-NEXT: seto %al1539; SDAG-NEXT: movl %esi, (%rdx)1540; SDAG-NEXT: retq1541;1542; FAST-LABEL: smuloi32_load:1543; FAST: # %bb.0:1544; FAST-NEXT: imull (%rdi), %esi1545; FAST-NEXT: seto %al1546; FAST-NEXT: movl %esi, (%rdx)1547; FAST-NEXT: andb $1, %al1548; FAST-NEXT: retq1549;1550; WIN64-LABEL: smuloi32_load:1551; WIN64: # %bb.0:1552; WIN64-NEXT: imull (%rcx), %edx1553; WIN64-NEXT: seto %al1554; WIN64-NEXT: movl %edx, (%r8)1555; WIN64-NEXT: retq1556;1557; WIN32-LABEL: smuloi32_load:1558; WIN32: # %bb.0:1559; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx1560; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1561; WIN32-NEXT: movl (%eax), %edx1562; WIN32-NEXT: imull {{[0-9]+}}(%esp), %edx1563; WIN32-NEXT: seto %al1564; WIN32-NEXT: movl %edx, (%ecx)1565; WIN32-NEXT: retl1566 %v1 = load i32, ptr %ptr11567 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)1568 %val = extractvalue {i32, i1} %t, 01569 %obit = extractvalue {i32, i1} %t, 11570 store i32 %val, ptr %res1571 ret i1 %obit1572}1573 1574define zeroext i1 @smuloi32_load2(i32 %v1, ptr %ptr2, ptr %res) {1575; SDAG-LABEL: smuloi32_load2:1576; SDAG: # %bb.0:1577; SDAG-NEXT: imull (%rsi), %edi1578; SDAG-NEXT: seto %al1579; SDAG-NEXT: movl %edi, (%rdx)1580; SDAG-NEXT: retq1581;1582; FAST-LABEL: smuloi32_load2:1583; FAST: # %bb.0:1584; FAST-NEXT: imull (%rsi), %edi1585; FAST-NEXT: seto %al1586; FAST-NEXT: movl %edi, (%rdx)1587; FAST-NEXT: andb $1, %al1588; FAST-NEXT: retq1589;1590; WIN64-LABEL: smuloi32_load2:1591; WIN64: # %bb.0:1592; WIN64-NEXT: imull (%rdx), %ecx1593; WIN64-NEXT: seto %al1594; WIN64-NEXT: movl %ecx, (%r8)1595; WIN64-NEXT: retq1596;1597; WIN32-LABEL: smuloi32_load2:1598; WIN32: # %bb.0:1599; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx1600; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1601; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx1602; WIN32-NEXT: imull (%eax), %edx1603; WIN32-NEXT: seto %al1604; WIN32-NEXT: movl %edx, (%ecx)1605; WIN32-NEXT: retl1606 %v2 = load i32, ptr %ptr21607 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)1608 %val = extractvalue {i32, i1} %t, 01609 %obit = extractvalue {i32, i1} %t, 11610 store i32 %val, ptr %res1611 ret i1 %obit1612}1613 1614define zeroext i1 @smuloi64_load(ptr %ptr1, i64 %v2, ptr %res) {1615; SDAG-LABEL: smuloi64_load:1616; SDAG: # %bb.0:1617; SDAG-NEXT: imulq (%rdi), %rsi1618; SDAG-NEXT: seto %al1619; SDAG-NEXT: movq %rsi, (%rdx)1620; SDAG-NEXT: retq1621;1622; FAST-LABEL: smuloi64_load:1623; FAST: # %bb.0:1624; FAST-NEXT: imulq (%rdi), %rsi1625; FAST-NEXT: seto %al1626; FAST-NEXT: movq %rsi, (%rdx)1627; FAST-NEXT: andb $1, %al1628; FAST-NEXT: retq1629;1630; WIN64-LABEL: smuloi64_load:1631; WIN64: # %bb.0:1632; WIN64-NEXT: imulq (%rcx), %rdx1633; WIN64-NEXT: seto %al1634; WIN64-NEXT: movq %rdx, (%r8)1635; WIN64-NEXT: retq1636;1637; WIN32-LABEL: smuloi64_load:1638; WIN32: # %bb.0:1639; WIN32-NEXT: pushl %ebp1640; WIN32-NEXT: pushl %ebx1641; WIN32-NEXT: pushl %edi1642; WIN32-NEXT: pushl %esi1643; WIN32-NEXT: subl $12, %esp1644; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebx1645; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1646; WIN32-NEXT: movl (%eax), %ecx1647; WIN32-NEXT: movl 4(%eax), %ebp1648; WIN32-NEXT: movl %ebp, %esi1649; WIN32-NEXT: movl %ebp, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill1650; WIN32-NEXT: sarl $31, %esi1651; WIN32-NEXT: imull %ebx, %esi1652; WIN32-NEXT: movl %ecx, %eax1653; WIN32-NEXT: mull %ebx1654; WIN32-NEXT: movl %edx, %edi1655; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill1656; WIN32-NEXT: movl %ebp, %eax1657; WIN32-NEXT: mull %ebx1658; WIN32-NEXT: movl %edx, %ebx1659; WIN32-NEXT: movl %eax, %ebp1660; WIN32-NEXT: addl %edi, %ebp1661; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1662; WIN32-NEXT: adcl %esi, %ebx1663; WIN32-NEXT: movl %ebx, %edi1664; WIN32-NEXT: sarl $31, %edi1665; WIN32-NEXT: movl %eax, %esi1666; WIN32-NEXT: sarl $31, %esi1667; WIN32-NEXT: imull %ecx, %esi1668; WIN32-NEXT: movl %ecx, %eax1669; WIN32-NEXT: mull {{[0-9]+}}(%esp)1670; WIN32-NEXT: movl %edx, %ecx1671; WIN32-NEXT: addl %ebp, %eax1672; WIN32-NEXT: movl %eax, (%esp) # 4-byte Spill1673; WIN32-NEXT: adcl %esi, %ecx1674; WIN32-NEXT: movl %ecx, %ebp1675; WIN32-NEXT: sarl $31, %ebp1676; WIN32-NEXT: addl %ebx, %ecx1677; WIN32-NEXT: adcl %edi, %ebp1678; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload1679; WIN32-NEXT: imull {{[0-9]+}}(%esp)1680; WIN32-NEXT: addl %ecx, %eax1681; WIN32-NEXT: adcl %ebp, %edx1682; WIN32-NEXT: movl (%esp), %esi # 4-byte Reload1683; WIN32-NEXT: movl %esi, %ecx1684; WIN32-NEXT: sarl $31, %ecx1685; WIN32-NEXT: xorl %ecx, %edx1686; WIN32-NEXT: xorl %eax, %ecx1687; WIN32-NEXT: orl %edx, %ecx1688; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1689; WIN32-NEXT: movl %esi, 4(%eax)1690; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload1691; WIN32-NEXT: movl %ecx, (%eax)1692; WIN32-NEXT: setne %al1693; WIN32-NEXT: addl $12, %esp1694; WIN32-NEXT: popl %esi1695; WIN32-NEXT: popl %edi1696; WIN32-NEXT: popl %ebx1697; WIN32-NEXT: popl %ebp1698; WIN32-NEXT: retl1699 %v1 = load i64, ptr %ptr11700 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)1701 %val = extractvalue {i64, i1} %t, 01702 %obit = extractvalue {i64, i1} %t, 11703 store i64 %val, ptr %res1704 ret i1 %obit1705}1706 1707define zeroext i1 @smuloi64_load2(i64 %v1, ptr %ptr2, ptr %res) {1708; SDAG-LABEL: smuloi64_load2:1709; SDAG: # %bb.0:1710; SDAG-NEXT: imulq (%rsi), %rdi1711; SDAG-NEXT: seto %al1712; SDAG-NEXT: movq %rdi, (%rdx)1713; SDAG-NEXT: retq1714;1715; FAST-LABEL: smuloi64_load2:1716; FAST: # %bb.0:1717; FAST-NEXT: imulq (%rsi), %rdi1718; FAST-NEXT: seto %al1719; FAST-NEXT: movq %rdi, (%rdx)1720; FAST-NEXT: andb $1, %al1721; FAST-NEXT: retq1722;1723; WIN64-LABEL: smuloi64_load2:1724; WIN64: # %bb.0:1725; WIN64-NEXT: imulq (%rdx), %rcx1726; WIN64-NEXT: seto %al1727; WIN64-NEXT: movq %rcx, (%r8)1728; WIN64-NEXT: retq1729;1730; WIN32-LABEL: smuloi64_load2:1731; WIN32: # %bb.0:1732; WIN32-NEXT: pushl %ebp1733; WIN32-NEXT: pushl %ebx1734; WIN32-NEXT: pushl %edi1735; WIN32-NEXT: pushl %esi1736; WIN32-NEXT: subl $12, %esp1737; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1738; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi1739; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx1740; WIN32-NEXT: movl (%ecx), %ebx1741; WIN32-NEXT: movl %edi, %esi1742; WIN32-NEXT: sarl $31, %esi1743; WIN32-NEXT: imull %ebx, %esi1744; WIN32-NEXT: mull %ebx1745; WIN32-NEXT: movl %edx, %ecx1746; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill1747; WIN32-NEXT: movl %edi, %eax1748; WIN32-NEXT: mull %ebx1749; WIN32-NEXT: movl %edx, %ebx1750; WIN32-NEXT: movl %eax, %ebp1751; WIN32-NEXT: addl %ecx, %ebp1752; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1753; WIN32-NEXT: movl 4(%eax), %ecx1754; WIN32-NEXT: movl %ecx, (%esp) # 4-byte Spill1755; WIN32-NEXT: adcl %esi, %ebx1756; WIN32-NEXT: movl %ebx, %edi1757; WIN32-NEXT: sarl $31, %edi1758; WIN32-NEXT: movl %ecx, %esi1759; WIN32-NEXT: sarl $31, %esi1760; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1761; WIN32-NEXT: imull %eax, %esi1762; WIN32-NEXT: mull %ecx1763; WIN32-NEXT: movl %edx, %ecx1764; WIN32-NEXT: addl %ebp, %eax1765; WIN32-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill1766; WIN32-NEXT: adcl %esi, %ecx1767; WIN32-NEXT: movl %ecx, %ebp1768; WIN32-NEXT: sarl $31, %ebp1769; WIN32-NEXT: addl %ebx, %ecx1770; WIN32-NEXT: adcl %edi, %ebp1771; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1772; WIN32-NEXT: imull (%esp) # 4-byte Folded Reload1773; WIN32-NEXT: addl %ecx, %eax1774; WIN32-NEXT: adcl %ebp, %edx1775; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %esi # 4-byte Reload1776; WIN32-NEXT: movl %esi, %ecx1777; WIN32-NEXT: sarl $31, %ecx1778; WIN32-NEXT: xorl %ecx, %edx1779; WIN32-NEXT: xorl %eax, %ecx1780; WIN32-NEXT: orl %edx, %ecx1781; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1782; WIN32-NEXT: movl %esi, 4(%eax)1783; WIN32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload1784; WIN32-NEXT: movl %ecx, (%eax)1785; WIN32-NEXT: setne %al1786; WIN32-NEXT: addl $12, %esp1787; WIN32-NEXT: popl %esi1788; WIN32-NEXT: popl %edi1789; WIN32-NEXT: popl %ebx1790; WIN32-NEXT: popl %ebp1791; WIN32-NEXT: retl1792 %v2 = load i64, ptr %ptr21793 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)1794 %val = extractvalue {i64, i1} %t, 01795 %obit = extractvalue {i64, i1} %t, 11796 store i64 %val, ptr %res1797 ret i1 %obit1798}1799 1800define zeroext i1 @umuloi8_load(ptr %ptr1, i8 %v2, ptr %res) {1801; SDAG-LABEL: umuloi8_load:1802; SDAG: # %bb.0:1803; SDAG-NEXT: movl %esi, %eax1804; SDAG-NEXT: # kill: def $al killed $al killed $eax1805; SDAG-NEXT: mulb (%rdi)1806; SDAG-NEXT: seto %cl1807; SDAG-NEXT: movb %al, (%rdx)1808; SDAG-NEXT: movl %ecx, %eax1809; SDAG-NEXT: retq1810;1811; FAST-LABEL: umuloi8_load:1812; FAST: # %bb.0:1813; FAST-NEXT: movzbl (%rdi), %eax1814; FAST-NEXT: mulb %sil1815; FAST-NEXT: seto %cl1816; FAST-NEXT: movb %al, (%rdx)1817; FAST-NEXT: andb $1, %cl1818; FAST-NEXT: movl %ecx, %eax1819; FAST-NEXT: retq1820;1821; WIN64-LABEL: umuloi8_load:1822; WIN64: # %bb.0:1823; WIN64-NEXT: movl %edx, %eax1824; WIN64-NEXT: mulb (%rcx)1825; WIN64-NEXT: seto %cl1826; WIN64-NEXT: movb %al, (%r8)1827; WIN64-NEXT: movl %ecx, %eax1828; WIN64-NEXT: retq1829;1830; WIN32-LABEL: umuloi8_load:1831; WIN32: # %bb.0:1832; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx1833; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1834; WIN32-NEXT: movzbl (%eax), %eax1835; WIN32-NEXT: mulb {{[0-9]+}}(%esp)1836; WIN32-NEXT: seto %cl1837; WIN32-NEXT: movb %al, (%edx)1838; WIN32-NEXT: movl %ecx, %eax1839; WIN32-NEXT: retl1840 %v1 = load i8, ptr %ptr11841 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)1842 %val = extractvalue {i8, i1} %t, 01843 %obit = extractvalue {i8, i1} %t, 11844 store i8 %val, ptr %res1845 ret i1 %obit1846}1847 1848define zeroext i1 @umuloi8_load2(i8 %v1, ptr %ptr2, ptr %res) {1849; SDAG-LABEL: umuloi8_load2:1850; SDAG: # %bb.0:1851; SDAG-NEXT: movl %edi, %eax1852; SDAG-NEXT: # kill: def $al killed $al killed $eax1853; SDAG-NEXT: mulb (%rsi)1854; SDAG-NEXT: seto %cl1855; SDAG-NEXT: movb %al, (%rdx)1856; SDAG-NEXT: movl %ecx, %eax1857; SDAG-NEXT: retq1858;1859; FAST-LABEL: umuloi8_load2:1860; FAST: # %bb.0:1861; FAST-NEXT: movl %edi, %eax1862; FAST-NEXT: # kill: def $al killed $al killed $eax1863; FAST-NEXT: mulb (%rsi)1864; FAST-NEXT: seto %cl1865; FAST-NEXT: movb %al, (%rdx)1866; FAST-NEXT: andb $1, %cl1867; FAST-NEXT: movl %ecx, %eax1868; FAST-NEXT: retq1869;1870; WIN64-LABEL: umuloi8_load2:1871; WIN64: # %bb.0:1872; WIN64-NEXT: movl %ecx, %eax1873; WIN64-NEXT: mulb (%rdx)1874; WIN64-NEXT: seto %cl1875; WIN64-NEXT: movb %al, (%r8)1876; WIN64-NEXT: movl %ecx, %eax1877; WIN64-NEXT: retq1878;1879; WIN32-LABEL: umuloi8_load2:1880; WIN32: # %bb.0:1881; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx1882; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax1883; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx1884; WIN32-NEXT: mulb (%ecx)1885; WIN32-NEXT: seto %cl1886; WIN32-NEXT: movb %al, (%edx)1887; WIN32-NEXT: movl %ecx, %eax1888; WIN32-NEXT: retl1889 %v2 = load i8, ptr %ptr21890 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2)1891 %val = extractvalue {i8, i1} %t, 01892 %obit = extractvalue {i8, i1} %t, 11893 store i8 %val, ptr %res1894 ret i1 %obit1895}1896 1897define zeroext i1 @umuloi16_load(ptr %ptr1, i16 %v2, ptr %res) {1898; SDAG-LABEL: umuloi16_load:1899; SDAG: # %bb.0:1900; SDAG-NEXT: movq %rdx, %rcx1901; SDAG-NEXT: movl %esi, %eax1902; SDAG-NEXT: # kill: def $ax killed $ax killed $eax1903; SDAG-NEXT: mulw (%rdi)1904; SDAG-NEXT: seto %dl1905; SDAG-NEXT: movw %ax, (%rcx)1906; SDAG-NEXT: movl %edx, %eax1907; SDAG-NEXT: retq1908;1909; FAST-LABEL: umuloi16_load:1910; FAST: # %bb.0:1911; FAST-NEXT: movq %rdx, %rcx1912; FAST-NEXT: movzwl (%rdi), %eax1913; FAST-NEXT: mulw %si1914; FAST-NEXT: seto %dl1915; FAST-NEXT: movw %ax, (%rcx)1916; FAST-NEXT: andb $1, %dl1917; FAST-NEXT: movl %edx, %eax1918; FAST-NEXT: retq1919;1920; WIN64-LABEL: umuloi16_load:1921; WIN64: # %bb.0:1922; WIN64-NEXT: movl %edx, %eax1923; WIN64-NEXT: mulw (%rcx)1924; WIN64-NEXT: seto %cl1925; WIN64-NEXT: movw %ax, (%r8)1926; WIN64-NEXT: movl %ecx, %eax1927; WIN64-NEXT: retq1928;1929; WIN32-LABEL: umuloi16_load:1930; WIN32: # %bb.0:1931; WIN32-NEXT: pushl %esi1932; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi1933; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax1934; WIN32-NEXT: movzwl (%eax), %eax1935; WIN32-NEXT: mulw {{[0-9]+}}(%esp)1936; WIN32-NEXT: seto %cl1937; WIN32-NEXT: movw %ax, (%esi)1938; WIN32-NEXT: movl %ecx, %eax1939; WIN32-NEXT: popl %esi1940; WIN32-NEXT: retl1941 %v1 = load i16, ptr %ptr11942 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)1943 %val = extractvalue {i16, i1} %t, 01944 %obit = extractvalue {i16, i1} %t, 11945 store i16 %val, ptr %res1946 ret i1 %obit1947}1948 1949define zeroext i1 @umuloi16_load2(i16 %v1, ptr %ptr2, ptr %res) {1950; SDAG-LABEL: umuloi16_load2:1951; SDAG: # %bb.0:1952; SDAG-NEXT: movq %rdx, %rcx1953; SDAG-NEXT: movl %edi, %eax1954; SDAG-NEXT: # kill: def $ax killed $ax killed $eax1955; SDAG-NEXT: mulw (%rsi)1956; SDAG-NEXT: seto %dl1957; SDAG-NEXT: movw %ax, (%rcx)1958; SDAG-NEXT: movl %edx, %eax1959; SDAG-NEXT: retq1960;1961; FAST-LABEL: umuloi16_load2:1962; FAST: # %bb.0:1963; FAST-NEXT: movq %rdx, %rcx1964; FAST-NEXT: movl %edi, %eax1965; FAST-NEXT: # kill: def $ax killed $ax killed $eax1966; FAST-NEXT: mulw (%rsi)1967; FAST-NEXT: seto %dl1968; FAST-NEXT: movw %ax, (%rcx)1969; FAST-NEXT: andb $1, %dl1970; FAST-NEXT: movl %edx, %eax1971; FAST-NEXT: retq1972;1973; WIN64-LABEL: umuloi16_load2:1974; WIN64: # %bb.0:1975; WIN64-NEXT: movl %ecx, %eax1976; WIN64-NEXT: mulw (%rdx)1977; WIN64-NEXT: seto %cl1978; WIN64-NEXT: movw %ax, (%r8)1979; WIN64-NEXT: movl %ecx, %eax1980; WIN64-NEXT: retq1981;1982; WIN32-LABEL: umuloi16_load2:1983; WIN32: # %bb.0:1984; WIN32-NEXT: pushl %esi1985; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi1986; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax1987; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx1988; WIN32-NEXT: mulw (%ecx)1989; WIN32-NEXT: seto %cl1990; WIN32-NEXT: movw %ax, (%esi)1991; WIN32-NEXT: movl %ecx, %eax1992; WIN32-NEXT: popl %esi1993; WIN32-NEXT: retl1994 %v2 = load i16, ptr %ptr21995 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)1996 %val = extractvalue {i16, i1} %t, 01997 %obit = extractvalue {i16, i1} %t, 11998 store i16 %val, ptr %res1999 ret i1 %obit2000}2001 2002define zeroext i1 @umuloi32_load(ptr %ptr1, i32 %v2, ptr %res) {2003; SDAG-LABEL: umuloi32_load:2004; SDAG: # %bb.0:2005; SDAG-NEXT: movq %rdx, %rcx2006; SDAG-NEXT: movl %esi, %eax2007; SDAG-NEXT: mull (%rdi)2008; SDAG-NEXT: seto %dl2009; SDAG-NEXT: movl %eax, (%rcx)2010; SDAG-NEXT: movl %edx, %eax2011; SDAG-NEXT: retq2012;2013; FAST-LABEL: umuloi32_load:2014; FAST: # %bb.0:2015; FAST-NEXT: movq %rdx, %rcx2016; FAST-NEXT: movl (%rdi), %eax2017; FAST-NEXT: mull %esi2018; FAST-NEXT: seto %dl2019; FAST-NEXT: movl %eax, (%rcx)2020; FAST-NEXT: andb $1, %dl2021; FAST-NEXT: movl %edx, %eax2022; FAST-NEXT: retq2023;2024; WIN64-LABEL: umuloi32_load:2025; WIN64: # %bb.0:2026; WIN64-NEXT: movl %edx, %eax2027; WIN64-NEXT: mull (%rcx)2028; WIN64-NEXT: seto %cl2029; WIN64-NEXT: movl %eax, (%r8)2030; WIN64-NEXT: movl %ecx, %eax2031; WIN64-NEXT: retq2032;2033; WIN32-LABEL: umuloi32_load:2034; WIN32: # %bb.0:2035; WIN32-NEXT: pushl %esi2036; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi2037; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax2038; WIN32-NEXT: movl (%eax), %eax2039; WIN32-NEXT: mull {{[0-9]+}}(%esp)2040; WIN32-NEXT: seto %cl2041; WIN32-NEXT: movl %eax, (%esi)2042; WIN32-NEXT: movl %ecx, %eax2043; WIN32-NEXT: popl %esi2044; WIN32-NEXT: retl2045 %v1 = load i32, ptr %ptr12046 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)2047 %val = extractvalue {i32, i1} %t, 02048 %obit = extractvalue {i32, i1} %t, 12049 store i32 %val, ptr %res2050 ret i1 %obit2051}2052 2053define zeroext i1 @umuloi32_load2(i32 %v1, ptr %ptr2, ptr %res) {2054; SDAG-LABEL: umuloi32_load2:2055; SDAG: # %bb.0:2056; SDAG-NEXT: movq %rdx, %rcx2057; SDAG-NEXT: movl %edi, %eax2058; SDAG-NEXT: mull (%rsi)2059; SDAG-NEXT: seto %dl2060; SDAG-NEXT: movl %eax, (%rcx)2061; SDAG-NEXT: movl %edx, %eax2062; SDAG-NEXT: retq2063;2064; FAST-LABEL: umuloi32_load2:2065; FAST: # %bb.0:2066; FAST-NEXT: movq %rdx, %rcx2067; FAST-NEXT: movl %edi, %eax2068; FAST-NEXT: mull (%rsi)2069; FAST-NEXT: seto %dl2070; FAST-NEXT: movl %eax, (%rcx)2071; FAST-NEXT: andb $1, %dl2072; FAST-NEXT: movl %edx, %eax2073; FAST-NEXT: retq2074;2075; WIN64-LABEL: umuloi32_load2:2076; WIN64: # %bb.0:2077; WIN64-NEXT: movl %ecx, %eax2078; WIN64-NEXT: mull (%rdx)2079; WIN64-NEXT: seto %cl2080; WIN64-NEXT: movl %eax, (%r8)2081; WIN64-NEXT: movl %ecx, %eax2082; WIN64-NEXT: retq2083;2084; WIN32-LABEL: umuloi32_load2:2085; WIN32: # %bb.0:2086; WIN32-NEXT: pushl %esi2087; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi2088; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax2089; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx2090; WIN32-NEXT: mull (%ecx)2091; WIN32-NEXT: seto %cl2092; WIN32-NEXT: movl %eax, (%esi)2093; WIN32-NEXT: movl %ecx, %eax2094; WIN32-NEXT: popl %esi2095; WIN32-NEXT: retl2096 %v2 = load i32, ptr %ptr22097 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)2098 %val = extractvalue {i32, i1} %t, 02099 %obit = extractvalue {i32, i1} %t, 12100 store i32 %val, ptr %res2101 ret i1 %obit2102}2103 2104define zeroext i1 @umuloi64_load(ptr %ptr1, i64 %v2, ptr %res) {2105; SDAG-LABEL: umuloi64_load:2106; SDAG: # %bb.0:2107; SDAG-NEXT: movq %rdx, %rcx2108; SDAG-NEXT: movq %rsi, %rax2109; SDAG-NEXT: mulq (%rdi)2110; SDAG-NEXT: seto %dl2111; SDAG-NEXT: movq %rax, (%rcx)2112; SDAG-NEXT: movl %edx, %eax2113; SDAG-NEXT: retq2114;2115; FAST-LABEL: umuloi64_load:2116; FAST: # %bb.0:2117; FAST-NEXT: movq %rdx, %rcx2118; FAST-NEXT: movq (%rdi), %rax2119; FAST-NEXT: mulq %rsi2120; FAST-NEXT: seto %dl2121; FAST-NEXT: movq %rax, (%rcx)2122; FAST-NEXT: andb $1, %dl2123; FAST-NEXT: movl %edx, %eax2124; FAST-NEXT: retq2125;2126; WIN64-LABEL: umuloi64_load:2127; WIN64: # %bb.0:2128; WIN64-NEXT: movq %rdx, %rax2129; WIN64-NEXT: mulq (%rcx)2130; WIN64-NEXT: seto %cl2131; WIN64-NEXT: movq %rax, (%r8)2132; WIN64-NEXT: movl %ecx, %eax2133; WIN64-NEXT: retq2134;2135; WIN32-LABEL: umuloi64_load:2136; WIN32: # %bb.0:2137; WIN32-NEXT: pushl %ebp2138; WIN32-NEXT: pushl %ebx2139; WIN32-NEXT: pushl %edi2140; WIN32-NEXT: pushl %esi2141; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi2142; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax2143; WIN32-NEXT: movl (%eax), %ebp2144; WIN32-NEXT: movl 4(%eax), %eax2145; WIN32-NEXT: testl %esi, %esi2146; WIN32-NEXT: setne %dl2147; WIN32-NEXT: testl %eax, %eax2148; WIN32-NEXT: setne %cl2149; WIN32-NEXT: andb %dl, %cl2150; WIN32-NEXT: mull {{[0-9]+}}(%esp)2151; WIN32-NEXT: movl %eax, %edi2152; WIN32-NEXT: seto %bl2153; WIN32-NEXT: movl %esi, %eax2154; WIN32-NEXT: mull %ebp2155; WIN32-NEXT: seto %ch2156; WIN32-NEXT: orb %bl, %ch2157; WIN32-NEXT: orb %cl, %ch2158; WIN32-NEXT: leal (%edi,%eax), %esi2159; WIN32-NEXT: movl %ebp, %eax2160; WIN32-NEXT: mull {{[0-9]+}}(%esp)2161; WIN32-NEXT: addl %esi, %edx2162; WIN32-NEXT: setb %cl2163; WIN32-NEXT: orb %ch, %cl2164; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi2165; WIN32-NEXT: movl %eax, (%esi)2166; WIN32-NEXT: movl %edx, 4(%esi)2167; WIN32-NEXT: movl %ecx, %eax2168; WIN32-NEXT: popl %esi2169; WIN32-NEXT: popl %edi2170; WIN32-NEXT: popl %ebx2171; WIN32-NEXT: popl %ebp2172; WIN32-NEXT: retl2173 %v1 = load i64, ptr %ptr12174 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)2175 %val = extractvalue {i64, i1} %t, 02176 %obit = extractvalue {i64, i1} %t, 12177 store i64 %val, ptr %res2178 ret i1 %obit2179}2180 2181define zeroext i1 @umuloi64_load2(i64 %v1, ptr %ptr2, ptr %res) {2182; SDAG-LABEL: umuloi64_load2:2183; SDAG: # %bb.0:2184; SDAG-NEXT: movq %rdx, %rcx2185; SDAG-NEXT: movq %rdi, %rax2186; SDAG-NEXT: mulq (%rsi)2187; SDAG-NEXT: seto %dl2188; SDAG-NEXT: movq %rax, (%rcx)2189; SDAG-NEXT: movl %edx, %eax2190; SDAG-NEXT: retq2191;2192; FAST-LABEL: umuloi64_load2:2193; FAST: # %bb.0:2194; FAST-NEXT: movq %rdx, %rcx2195; FAST-NEXT: movq %rdi, %rax2196; FAST-NEXT: mulq (%rsi)2197; FAST-NEXT: seto %dl2198; FAST-NEXT: movq %rax, (%rcx)2199; FAST-NEXT: andb $1, %dl2200; FAST-NEXT: movl %edx, %eax2201; FAST-NEXT: retq2202;2203; WIN64-LABEL: umuloi64_load2:2204; WIN64: # %bb.0:2205; WIN64-NEXT: movq %rcx, %rax2206; WIN64-NEXT: mulq (%rdx)2207; WIN64-NEXT: seto %cl2208; WIN64-NEXT: movq %rax, (%r8)2209; WIN64-NEXT: movl %ecx, %eax2210; WIN64-NEXT: retq2211;2212; WIN32-LABEL: umuloi64_load2:2213; WIN32: # %bb.0:2214; WIN32-NEXT: pushl %ebp2215; WIN32-NEXT: pushl %ebx2216; WIN32-NEXT: pushl %edi2217; WIN32-NEXT: pushl %esi2218; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax2219; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx2220; WIN32-NEXT: movl (%ecx), %ebp2221; WIN32-NEXT: movl 4(%ecx), %esi2222; WIN32-NEXT: testl %eax, %eax2223; WIN32-NEXT: setne %dl2224; WIN32-NEXT: testl %esi, %esi2225; WIN32-NEXT: setne %cl2226; WIN32-NEXT: andb %dl, %cl2227; WIN32-NEXT: mull %ebp2228; WIN32-NEXT: movl %eax, %edi2229; WIN32-NEXT: seto %bl2230; WIN32-NEXT: movl %esi, %eax2231; WIN32-NEXT: mull {{[0-9]+}}(%esp)2232; WIN32-NEXT: seto %ch2233; WIN32-NEXT: orb %bl, %ch2234; WIN32-NEXT: orb %cl, %ch2235; WIN32-NEXT: leal (%edi,%eax), %esi2236; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax2237; WIN32-NEXT: mull %ebp2238; WIN32-NEXT: addl %esi, %edx2239; WIN32-NEXT: setb %cl2240; WIN32-NEXT: orb %ch, %cl2241; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi2242; WIN32-NEXT: movl %eax, (%esi)2243; WIN32-NEXT: movl %edx, 4(%esi)2244; WIN32-NEXT: movl %ecx, %eax2245; WIN32-NEXT: popl %esi2246; WIN32-NEXT: popl %edi2247; WIN32-NEXT: popl %ebx2248; WIN32-NEXT: popl %ebp2249; WIN32-NEXT: retl2250 %v2 = load i64, ptr %ptr22251 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)2252 %val = extractvalue {i64, i1} %t, 02253 %obit = extractvalue {i64, i1} %t, 12254 store i64 %val, ptr %res2255 ret i1 %obit2256}2257 2258declare {i8, i1} @llvm.smul.with.overflow.i8 (i8, i8 ) nounwind readnone2259declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone2260declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone2261declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone2262declare {i8, i1} @llvm.umul.with.overflow.i8 (i8, i8 ) nounwind readnone2263declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone2264declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone2265declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone2266 2267!0 = !{!"branch_weights", i32 0, i32 2147483647}2268