415 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=X643; RUN: llc < %s -mtriple=i686 -mattr=cmov | FileCheck %s --check-prefix=X864 5declare i4 @llvm.smul.fix.i4 (i4, i4, i32)6declare i32 @llvm.smul.fix.i32 (i32, i32, i32)7declare i64 @llvm.smul.fix.i64 (i64, i64, i32)8declare <4 x i32> @llvm.smul.fix.v4i32(<4 x i32>, <4 x i32>, i32)9 10define i32 @func(i32 %x, i32 %y) nounwind {11; X64-LABEL: func:12; X64: # %bb.0:13; X64-NEXT: movslq %esi, %rcx14; X64-NEXT: movslq %edi, %rax15; X64-NEXT: imulq %rcx, %rax16; X64-NEXT: movl %eax, %ecx17; X64-NEXT: shrq $32, %rax18; X64-NEXT: shldl $30, %ecx, %eax19; X64-NEXT: # kill: def $eax killed $eax killed $rax20; X64-NEXT: retq21;22; X86-LABEL: func:23; X86: # %bb.0:24; X86-NEXT: movl {{[0-9]+}}(%esp), %eax25; X86-NEXT: imull {{[0-9]+}}(%esp)26; X86-NEXT: shrdl $2, %edx, %eax27; X86-NEXT: retl28 %tmp = call i32 @llvm.smul.fix.i32(i32 %x, i32 %y, i32 2)29 ret i32 %tmp30}31 32define i64 @func2(i64 %x, i64 %y) {33; X64-LABEL: func2:34; X64: # %bb.0:35; X64-NEXT: movq %rdi, %rax36; X64-NEXT: imulq %rsi37; X64-NEXT: shrdq $2, %rdx, %rax38; X64-NEXT: retq39;40; X86-LABEL: func2:41; X86: # %bb.0:42; X86-NEXT: pushl %ebp43; X86-NEXT: .cfi_def_cfa_offset 844; X86-NEXT: pushl %ebx45; X86-NEXT: .cfi_def_cfa_offset 1246; X86-NEXT: pushl %edi47; X86-NEXT: .cfi_def_cfa_offset 1648; X86-NEXT: pushl %esi49; X86-NEXT: .cfi_def_cfa_offset 2050; X86-NEXT: .cfi_offset %esi, -2051; X86-NEXT: .cfi_offset %edi, -1652; X86-NEXT: .cfi_offset %ebx, -1253; X86-NEXT: .cfi_offset %ebp, -854; X86-NEXT: movl {{[0-9]+}}(%esp), %esi55; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx56; X86-NEXT: movl %esi, %eax57; X86-NEXT: mull {{[0-9]+}}(%esp)58; X86-NEXT: movl %edx, %edi59; X86-NEXT: movl %eax, %ebx60; X86-NEXT: movl %esi, %eax61; X86-NEXT: mull %ecx62; X86-NEXT: movl %eax, %esi63; X86-NEXT: addl %edx, %ebx64; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp65; X86-NEXT: adcl $0, %edi66; X86-NEXT: movl %ebp, %eax67; X86-NEXT: mull %ecx68; X86-NEXT: addl %ebx, %eax69; X86-NEXT: adcl %edi, %edx70; X86-NEXT: movl %ebp, %edi71; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx72; X86-NEXT: imull %ebx, %edi73; X86-NEXT: addl %edi, %edx74; X86-NEXT: movl %edx, %edi75; X86-NEXT: subl %ecx, %edi76; X86-NEXT: testl %ebp, %ebp77; X86-NEXT: cmovsl %edi, %edx78; X86-NEXT: movl %edx, %ecx79; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx80; X86-NEXT: testl %ebx, %ebx81; X86-NEXT: cmovsl %ecx, %edx82; X86-NEXT: shldl $30, %eax, %edx83; X86-NEXT: shldl $30, %esi, %eax84; X86-NEXT: popl %esi85; X86-NEXT: .cfi_def_cfa_offset 1686; X86-NEXT: popl %edi87; X86-NEXT: .cfi_def_cfa_offset 1288; X86-NEXT: popl %ebx89; X86-NEXT: .cfi_def_cfa_offset 890; X86-NEXT: popl %ebp91; X86-NEXT: .cfi_def_cfa_offset 492; X86-NEXT: retl93 %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 2)94 ret i64 %tmp95}96 97define i4 @func3(i4 %x, i4 %y) nounwind {98; X64-LABEL: func3:99; X64: # %bb.0:100; X64-NEXT: shlb $4, %dil101; X64-NEXT: sarb $4, %dil102; X64-NEXT: shlb $4, %sil103; X64-NEXT: sarb $4, %sil104; X64-NEXT: movsbl %sil, %ecx105; X64-NEXT: movsbl %dil, %eax106; X64-NEXT: imull %ecx, %eax107; X64-NEXT: movl %eax, %ecx108; X64-NEXT: shrb $2, %cl109; X64-NEXT: shrl $8, %eax110; X64-NEXT: shlb $6, %al111; X64-NEXT: orb %cl, %al112; X64-NEXT: # kill: def $al killed $al killed $eax113; X64-NEXT: retq114;115; X86-LABEL: func3:116; X86: # %bb.0:117; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax118; X86-NEXT: shlb $4, %al119; X86-NEXT: sarb $4, %al120; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx121; X86-NEXT: shlb $4, %cl122; X86-NEXT: sarb $4, %cl123; X86-NEXT: movsbl %cl, %ecx124; X86-NEXT: movsbl %al, %eax125; X86-NEXT: imull %ecx, %eax126; X86-NEXT: shlb $6, %ah127; X86-NEXT: shrb $2, %al128; X86-NEXT: orb %ah, %al129; X86-NEXT: # kill: def $al killed $al killed $eax130; X86-NEXT: retl131 %tmp = call i4 @llvm.smul.fix.i4(i4 %x, i4 %y, i32 2)132 ret i4 %tmp133}134 135define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {136; X64-LABEL: vec:137; X64: # %bb.0:138; X64-NEXT: pxor %xmm2, %xmm2139; X64-NEXT: pxor %xmm3, %xmm3140; X64-NEXT: pcmpgtd %xmm1, %xmm3141; X64-NEXT: pand %xmm0, %xmm3142; X64-NEXT: pcmpgtd %xmm0, %xmm2143; X64-NEXT: pand %xmm1, %xmm2144; X64-NEXT: paddd %xmm3, %xmm2145; X64-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3]146; X64-NEXT: pmuludq %xmm1, %xmm0147; X64-NEXT: pshufd {{.*#+}} xmm4 = xmm0[1,3,2,3]148; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]149; X64-NEXT: pmuludq %xmm3, %xmm1150; X64-NEXT: pshufd {{.*#+}} xmm3 = xmm1[1,3,2,3]151; X64-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[1]152; X64-NEXT: psubd %xmm2, %xmm4153; X64-NEXT: pslld $30, %xmm4154; X64-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]155; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]156; X64-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]157; X64-NEXT: psrld $2, %xmm0158; X64-NEXT: por %xmm4, %xmm0159; X64-NEXT: retq160;161; X86-LABEL: vec:162; X86: # %bb.0:163; X86-NEXT: pushl %ebp164; X86-NEXT: pushl %ebx165; X86-NEXT: pushl %edi166; X86-NEXT: pushl %esi167; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx168; X86-NEXT: movl {{[0-9]+}}(%esp), %edi169; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp170; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx171; X86-NEXT: movl {{[0-9]+}}(%esp), %eax172; X86-NEXT: imull {{[0-9]+}}(%esp)173; X86-NEXT: movl %edx, %esi174; X86-NEXT: shldl $30, %eax, %esi175; X86-NEXT: movl %ebx, %eax176; X86-NEXT: imull {{[0-9]+}}(%esp)177; X86-NEXT: movl %edx, %ebx178; X86-NEXT: shldl $30, %eax, %ebx179; X86-NEXT: movl %ebp, %eax180; X86-NEXT: imull {{[0-9]+}}(%esp)181; X86-NEXT: movl %edx, %ebp182; X86-NEXT: shldl $30, %eax, %ebp183; X86-NEXT: movl %edi, %eax184; X86-NEXT: imull {{[0-9]+}}(%esp)185; X86-NEXT: shldl $30, %eax, %edx186; X86-NEXT: movl %edx, 12(%ecx)187; X86-NEXT: movl %ebp, 8(%ecx)188; X86-NEXT: movl %ebx, 4(%ecx)189; X86-NEXT: movl %esi, (%ecx)190; X86-NEXT: movl %ecx, %eax191; X86-NEXT: popl %esi192; X86-NEXT: popl %edi193; X86-NEXT: popl %ebx194; X86-NEXT: popl %ebp195; X86-NEXT: retl $4196 %tmp = call <4 x i32> @llvm.smul.fix.v4i32(<4 x i32> %x, <4 x i32> %y, i32 2)197 ret <4 x i32> %tmp198}199 200; These result in regular integer multiplication201define i32 @func4(i32 %x, i32 %y) nounwind {202; X64-LABEL: func4:203; X64: # %bb.0:204; X64-NEXT: movl %edi, %eax205; X64-NEXT: imull %esi, %eax206; X64-NEXT: retq207;208; X86-LABEL: func4:209; X86: # %bb.0:210; X86-NEXT: movl {{[0-9]+}}(%esp), %eax211; X86-NEXT: imull {{[0-9]+}}(%esp), %eax212; X86-NEXT: retl213 %tmp = call i32 @llvm.smul.fix.i32(i32 %x, i32 %y, i32 0)214 ret i32 %tmp215}216 217define i64 @func5(i64 %x, i64 %y) {218; X64-LABEL: func5:219; X64: # %bb.0:220; X64-NEXT: movq %rdi, %rax221; X64-NEXT: imulq %rsi, %rax222; X64-NEXT: retq223;224; X86-LABEL: func5:225; X86: # %bb.0:226; X86-NEXT: pushl %esi227; X86-NEXT: .cfi_def_cfa_offset 8228; X86-NEXT: .cfi_offset %esi, -8229; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx230; X86-NEXT: movl {{[0-9]+}}(%esp), %esi231; X86-NEXT: movl %ecx, %eax232; X86-NEXT: mull %esi233; X86-NEXT: imull {{[0-9]+}}(%esp), %ecx234; X86-NEXT: addl %ecx, %edx235; X86-NEXT: imull {{[0-9]+}}(%esp), %esi236; X86-NEXT: addl %esi, %edx237; X86-NEXT: popl %esi238; X86-NEXT: .cfi_def_cfa_offset 4239; X86-NEXT: retl240 %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 0)241 ret i64 %tmp242}243 244define i4 @func6(i4 %x, i4 %y) nounwind {245; X64-LABEL: func6:246; X64: # %bb.0:247; X64-NEXT: movl %edi, %eax248; X64-NEXT: shlb $4, %al249; X64-NEXT: sarb $4, %al250; X64-NEXT: shlb $4, %sil251; X64-NEXT: sarb $4, %sil252; X64-NEXT: # kill: def $al killed $al killed $eax253; X64-NEXT: mulb %sil254; X64-NEXT: retq255;256; X86-LABEL: func6:257; X86: # %bb.0:258; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax259; X86-NEXT: shlb $4, %al260; X86-NEXT: sarb $4, %al261; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx262; X86-NEXT: shlb $4, %cl263; X86-NEXT: sarb $4, %cl264; X86-NEXT: mulb %cl265; X86-NEXT: retl266 %tmp = call i4 @llvm.smul.fix.i4(i4 %x, i4 %y, i32 0)267 ret i4 %tmp268}269 270define <4 x i32> @vec2(<4 x i32> %x, <4 x i32> %y) nounwind {271; X64-LABEL: vec2:272; X64: # %bb.0:273; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3]274; X64-NEXT: pmuludq %xmm1, %xmm0275; X64-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]276; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]277; X64-NEXT: pmuludq %xmm2, %xmm1278; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]279; X64-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]280; X64-NEXT: retq281;282; X86-LABEL: vec2:283; X86: # %bb.0:284; X86-NEXT: pushl %edi285; X86-NEXT: pushl %esi286; X86-NEXT: movl {{[0-9]+}}(%esp), %eax287; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx288; X86-NEXT: movl {{[0-9]+}}(%esp), %edx289; X86-NEXT: movl {{[0-9]+}}(%esp), %esi290; X86-NEXT: movl {{[0-9]+}}(%esp), %edi291; X86-NEXT: imull {{[0-9]+}}(%esp), %edi292; X86-NEXT: imull {{[0-9]+}}(%esp), %esi293; X86-NEXT: imull {{[0-9]+}}(%esp), %edx294; X86-NEXT: imull {{[0-9]+}}(%esp), %ecx295; X86-NEXT: movl %ecx, 12(%eax)296; X86-NEXT: movl %edx, 8(%eax)297; X86-NEXT: movl %esi, 4(%eax)298; X86-NEXT: movl %edi, (%eax)299; X86-NEXT: popl %esi300; X86-NEXT: popl %edi301; X86-NEXT: retl $4302 %tmp = call <4 x i32> @llvm.smul.fix.v4i32(<4 x i32> %x, <4 x i32> %y, i32 0)303 ret <4 x i32> %tmp304}305 306define i64 @func7(i64 %x, i64 %y) nounwind {307; X64-LABEL: func7:308; X64: # %bb.0:309; X64-NEXT: movq %rdi, %rax310; X64-NEXT: imulq %rsi311; X64-NEXT: shrdq $32, %rdx, %rax312; X64-NEXT: retq313;314; X86-LABEL: func7:315; X86: # %bb.0:316; X86-NEXT: pushl %ebp317; X86-NEXT: pushl %ebx318; X86-NEXT: pushl %edi319; X86-NEXT: pushl %esi320; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx321; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp322; X86-NEXT: movl {{[0-9]+}}(%esp), %esi323; X86-NEXT: movl %ecx, %eax324; X86-NEXT: mull {{[0-9]+}}(%esp)325; X86-NEXT: movl %edx, %edi326; X86-NEXT: movl %eax, %ebx327; X86-NEXT: movl %ecx, %eax328; X86-NEXT: mull %esi329; X86-NEXT: addl %edx, %ebx330; X86-NEXT: adcl $0, %edi331; X86-NEXT: movl %ebp, %eax332; X86-NEXT: mull %esi333; X86-NEXT: addl %ebx, %eax334; X86-NEXT: adcl %edi, %edx335; X86-NEXT: movl %ebp, %edi336; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx337; X86-NEXT: imull %ebx, %edi338; X86-NEXT: addl %edi, %edx339; X86-NEXT: movl %edx, %edi340; X86-NEXT: subl %esi, %edi341; X86-NEXT: testl %ebp, %ebp342; X86-NEXT: cmovsl %edi, %edx343; X86-NEXT: movl %edx, %ecx344; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx345; X86-NEXT: testl %ebx, %ebx346; X86-NEXT: cmovsl %ecx, %edx347; X86-NEXT: popl %esi348; X86-NEXT: popl %edi349; X86-NEXT: popl %ebx350; X86-NEXT: popl %ebp351; X86-NEXT: retl352 %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 32)353 ret i64 %tmp354}355 356define i64 @func8(i64 %x, i64 %y) nounwind {357; X64-LABEL: func8:358; X64: # %bb.0:359; X64-NEXT: movq %rdi, %rax360; X64-NEXT: imulq %rsi361; X64-NEXT: shrdq $63, %rdx, %rax362; X64-NEXT: retq363;364; X86-LABEL: func8:365; X86: # %bb.0:366; X86-NEXT: pushl %ebp367; X86-NEXT: pushl %ebx368; X86-NEXT: pushl %edi369; X86-NEXT: pushl %esi370; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx371; X86-NEXT: movl {{[0-9]+}}(%esp), %esi372; X86-NEXT: movl %ecx, %eax373; X86-NEXT: mull {{[0-9]+}}(%esp)374; X86-NEXT: movl %edx, %edi375; X86-NEXT: movl %eax, %ebp376; X86-NEXT: movl %ecx, %eax377; X86-NEXT: mull {{[0-9]+}}(%esp)378; X86-NEXT: addl %edx, %ebp379; X86-NEXT: adcl $0, %edi380; X86-NEXT: movl %esi, %eax381; X86-NEXT: imull {{[0-9]+}}(%esp)382; X86-NEXT: movl %edx, %ebx383; X86-NEXT: movl %eax, %ecx384; X86-NEXT: movl %esi, %eax385; X86-NEXT: mull {{[0-9]+}}(%esp)386; X86-NEXT: addl %ebp, %eax387; X86-NEXT: adcl %edx, %edi388; X86-NEXT: adcl $0, %ebx389; X86-NEXT: addl %ecx, %edi390; X86-NEXT: adcl $0, %ebx391; X86-NEXT: movl %edi, %ecx392; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx393; X86-NEXT: movl %ebx, %esi394; X86-NEXT: sbbl $0, %esi395; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp)396; X86-NEXT: cmovnsl %ebx, %esi397; X86-NEXT: cmovnsl %edi, %ecx398; X86-NEXT: movl %ecx, %edi399; X86-NEXT: subl {{[0-9]+}}(%esp), %edi400; X86-NEXT: movl %esi, %edx401; X86-NEXT: sbbl $0, %edx402; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp)403; X86-NEXT: cmovnsl %esi, %edx404; X86-NEXT: cmovnsl %ecx, %edi405; X86-NEXT: shldl $1, %edi, %edx406; X86-NEXT: shrdl $31, %edi, %eax407; X86-NEXT: popl %esi408; X86-NEXT: popl %edi409; X86-NEXT: popl %ebx410; X86-NEXT: popl %ebp411; X86-NEXT: retl412 %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 63)413 ret i64 %tmp414}415