389 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.umul.fix.i4 (i4, i4, i32)6declare i32 @llvm.umul.fix.i32 (i32, i32, i32)7declare i64 @llvm.umul.fix.i64 (i64, i64, i32)8declare <4 x i32> @llvm.umul.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: movl %esi, %ecx14; X64-NEXT: movl %edi, %eax15; 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: mull {{[0-9]+}}(%esp)26; X86-NEXT: shrdl $2, %edx, %eax27; X86-NEXT: retl28 %tmp = call i32 @llvm.umul.fix.i32(i32 %x, i32 %y, i32 2)29 ret i32 %tmp30}31 32define i64 @func2(i64 %x, i64 %y) nounwind {33; X64-LABEL: func2:34; X64: # %bb.0:35; X64-NEXT: movq %rdi, %rax36; X64-NEXT: mulq %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: pushl %ebx44; X86-NEXT: pushl %edi45; X86-NEXT: pushl %esi46; X86-NEXT: movl {{[0-9]+}}(%esp), %esi47; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx48; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp49; X86-NEXT: movl %esi, %eax50; X86-NEXT: mull {{[0-9]+}}(%esp)51; X86-NEXT: movl %edx, %edi52; X86-NEXT: movl %eax, %ebx53; X86-NEXT: movl %esi, %eax54; X86-NEXT: mull %ebp55; X86-NEXT: movl %eax, %esi56; X86-NEXT: addl %edx, %ebx57; X86-NEXT: adcl $0, %edi58; X86-NEXT: movl %ecx, %eax59; X86-NEXT: mull %ebp60; X86-NEXT: addl %ebx, %eax61; X86-NEXT: adcl %edi, %edx62; X86-NEXT: imull {{[0-9]+}}(%esp), %ecx63; X86-NEXT: addl %ecx, %edx64; X86-NEXT: shldl $30, %eax, %edx65; X86-NEXT: shldl $30, %esi, %eax66; X86-NEXT: popl %esi67; X86-NEXT: popl %edi68; X86-NEXT: popl %ebx69; X86-NEXT: popl %ebp70; X86-NEXT: retl71 %tmp = call i64 @llvm.umul.fix.i64(i64 %x, i64 %y, i32 2)72 ret i64 %tmp73}74 75define i4 @func3(i4 %x, i4 %y) nounwind {76; X64-LABEL: func3:77; X64: # %bb.0:78; X64-NEXT: movl %edi, %eax79; X64-NEXT: andb $15, %al80; X64-NEXT: andb $15, %sil81; X64-NEXT: # kill: def $al killed $al killed $eax82; X64-NEXT: mulb %sil83; X64-NEXT: shrb $2, %al84; X64-NEXT: retq85;86; X86-LABEL: func3:87; X86: # %bb.0:88; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax89; X86-NEXT: andb $15, %al90; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx91; X86-NEXT: andb $15, %cl92; X86-NEXT: mulb %cl93; X86-NEXT: shrb $2, %al94; X86-NEXT: retl95 %tmp = call i4 @llvm.umul.fix.i4(i4 %x, i4 %y, i32 2)96 ret i4 %tmp97}98 99define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {100; X64-LABEL: vec:101; X64: # %bb.0:102; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3]103; X64-NEXT: pmuludq %xmm1, %xmm0104; X64-NEXT: pshufd {{.*#+}} xmm3 = xmm0[0,2,2,3]105; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]106; X64-NEXT: pmuludq %xmm2, %xmm1107; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm1[0,2,2,3]108; X64-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]109; X64-NEXT: psrld $2, %xmm3110; X64-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,3]111; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]112; X64-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]113; X64-NEXT: pslld $30, %xmm0114; X64-NEXT: por %xmm3, %xmm0115; X64-NEXT: retq116;117; X86-LABEL: vec:118; X86: # %bb.0:119; X86-NEXT: pushl %ebp120; X86-NEXT: pushl %ebx121; X86-NEXT: pushl %edi122; X86-NEXT: pushl %esi123; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx124; X86-NEXT: movl {{[0-9]+}}(%esp), %edi125; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp126; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx127; X86-NEXT: movl {{[0-9]+}}(%esp), %eax128; X86-NEXT: mull {{[0-9]+}}(%esp)129; X86-NEXT: movl %edx, %esi130; X86-NEXT: shldl $30, %eax, %esi131; X86-NEXT: movl %ebx, %eax132; X86-NEXT: mull {{[0-9]+}}(%esp)133; X86-NEXT: movl %edx, %ebx134; X86-NEXT: shldl $30, %eax, %ebx135; X86-NEXT: movl %ebp, %eax136; X86-NEXT: mull {{[0-9]+}}(%esp)137; X86-NEXT: movl %edx, %ebp138; X86-NEXT: shldl $30, %eax, %ebp139; X86-NEXT: movl %edi, %eax140; X86-NEXT: mull {{[0-9]+}}(%esp)141; X86-NEXT: shldl $30, %eax, %edx142; X86-NEXT: movl %edx, 12(%ecx)143; X86-NEXT: movl %ebp, 8(%ecx)144; X86-NEXT: movl %ebx, 4(%ecx)145; X86-NEXT: movl %esi, (%ecx)146; X86-NEXT: movl %ecx, %eax147; X86-NEXT: popl %esi148; X86-NEXT: popl %edi149; X86-NEXT: popl %ebx150; X86-NEXT: popl %ebp151; X86-NEXT: retl $4152 %tmp = call <4 x i32> @llvm.umul.fix.v4i32(<4 x i32> %x, <4 x i32> %y, i32 2)153 ret <4 x i32> %tmp154}155 156; These result in regular integer multiplication157define i32 @func4(i32 %x, i32 %y) nounwind {158; X64-LABEL: func4:159; X64: # %bb.0:160; X64-NEXT: movl %edi, %eax161; X64-NEXT: imull %esi, %eax162; X64-NEXT: retq163;164; X86-LABEL: func4:165; X86: # %bb.0:166; X86-NEXT: movl {{[0-9]+}}(%esp), %eax167; X86-NEXT: imull {{[0-9]+}}(%esp), %eax168; X86-NEXT: retl169 %tmp = call i32 @llvm.umul.fix.i32(i32 %x, i32 %y, i32 0)170 ret i32 %tmp171}172 173define i64 @func5(i64 %x, i64 %y) nounwind {174; X64-LABEL: func5:175; X64: # %bb.0:176; X64-NEXT: movq %rdi, %rax177; X64-NEXT: imulq %rsi, %rax178; X64-NEXT: retq179;180; X86-LABEL: func5:181; X86: # %bb.0:182; X86-NEXT: pushl %esi183; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx184; X86-NEXT: movl {{[0-9]+}}(%esp), %esi185; X86-NEXT: movl %ecx, %eax186; X86-NEXT: mull %esi187; X86-NEXT: imull {{[0-9]+}}(%esp), %ecx188; X86-NEXT: addl %ecx, %edx189; X86-NEXT: imull {{[0-9]+}}(%esp), %esi190; X86-NEXT: addl %esi, %edx191; X86-NEXT: popl %esi192; X86-NEXT: retl193 %tmp = call i64 @llvm.umul.fix.i64(i64 %x, i64 %y, i32 0)194 ret i64 %tmp195}196 197define i4 @func6(i4 %x, i4 %y) nounwind {198; X64-LABEL: func6:199; X64: # %bb.0:200; X64-NEXT: movl %edi, %eax201; X64-NEXT: andb $15, %al202; X64-NEXT: andb $15, %sil203; X64-NEXT: # kill: def $al killed $al killed $eax204; X64-NEXT: mulb %sil205; X64-NEXT: retq206;207; X86-LABEL: func6:208; X86: # %bb.0:209; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax210; X86-NEXT: andb $15, %al211; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx212; X86-NEXT: andb $15, %cl213; X86-NEXT: mulb %cl214; X86-NEXT: retl215 %tmp = call i4 @llvm.umul.fix.i4(i4 %x, i4 %y, i32 0)216 ret i4 %tmp217}218 219define <4 x i32> @vec2(<4 x i32> %x, <4 x i32> %y) nounwind {220; X64-LABEL: vec2:221; X64: # %bb.0:222; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3]223; X64-NEXT: pmuludq %xmm1, %xmm0224; X64-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]225; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]226; X64-NEXT: pmuludq %xmm2, %xmm1227; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]228; X64-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]229; X64-NEXT: retq230;231; X86-LABEL: vec2:232; X86: # %bb.0:233; X86-NEXT: pushl %edi234; X86-NEXT: pushl %esi235; X86-NEXT: movl {{[0-9]+}}(%esp), %eax236; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx237; X86-NEXT: movl {{[0-9]+}}(%esp), %edx238; X86-NEXT: movl {{[0-9]+}}(%esp), %esi239; X86-NEXT: movl {{[0-9]+}}(%esp), %edi240; X86-NEXT: imull {{[0-9]+}}(%esp), %edi241; X86-NEXT: imull {{[0-9]+}}(%esp), %esi242; X86-NEXT: imull {{[0-9]+}}(%esp), %edx243; X86-NEXT: imull {{[0-9]+}}(%esp), %ecx244; X86-NEXT: movl %ecx, 12(%eax)245; X86-NEXT: movl %edx, 8(%eax)246; X86-NEXT: movl %esi, 4(%eax)247; X86-NEXT: movl %edi, (%eax)248; X86-NEXT: popl %esi249; X86-NEXT: popl %edi250; X86-NEXT: retl $4251 %tmp = call <4 x i32> @llvm.umul.fix.v4i32(<4 x i32> %x, <4 x i32> %y, i32 0)252 ret <4 x i32> %tmp253}254 255define i64 @func7(i64 %x, i64 %y) nounwind {256; X64-LABEL: func7:257; X64: # %bb.0:258; X64-NEXT: movq %rdi, %rax259; X64-NEXT: mulq %rsi260; X64-NEXT: shrdq $32, %rdx, %rax261; X64-NEXT: retq262;263; X86-LABEL: func7:264; X86: # %bb.0:265; X86-NEXT: pushl %ebp266; X86-NEXT: pushl %ebx267; X86-NEXT: pushl %edi268; X86-NEXT: pushl %esi269; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx270; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx271; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp272; X86-NEXT: movl %ebx, %eax273; X86-NEXT: mull {{[0-9]+}}(%esp)274; X86-NEXT: movl %edx, %esi275; X86-NEXT: movl %eax, %edi276; X86-NEXT: movl %ebx, %eax277; X86-NEXT: mull %ebp278; X86-NEXT: addl %edx, %edi279; X86-NEXT: adcl $0, %esi280; X86-NEXT: movl %ecx, %eax281; X86-NEXT: mull %ebp282; X86-NEXT: addl %edi, %eax283; X86-NEXT: adcl %esi, %edx284; X86-NEXT: imull {{[0-9]+}}(%esp), %ecx285; X86-NEXT: addl %ecx, %edx286; X86-NEXT: popl %esi287; X86-NEXT: popl %edi288; X86-NEXT: popl %ebx289; X86-NEXT: popl %ebp290; X86-NEXT: retl291 %tmp = call i64 @llvm.umul.fix.i64(i64 %x, i64 %y, i32 32)292 ret i64 %tmp293}294 295define i64 @func8(i64 %x, i64 %y) nounwind {296; X64-LABEL: func8:297; X64: # %bb.0:298; X64-NEXT: movq %rdi, %rax299; X64-NEXT: mulq %rsi300; X64-NEXT: shrdq $63, %rdx, %rax301; X64-NEXT: retq302;303; X86-LABEL: func8:304; X86: # %bb.0:305; X86-NEXT: pushl %ebp306; X86-NEXT: pushl %ebx307; X86-NEXT: pushl %edi308; X86-NEXT: pushl %esi309; X86-NEXT: movl {{[0-9]+}}(%esp), %esi310; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx311; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp312; X86-NEXT: movl %esi, %eax313; X86-NEXT: mull %ebp314; X86-NEXT: movl %edx, %ecx315; X86-NEXT: movl %eax, %edi316; X86-NEXT: movl %esi, %eax317; X86-NEXT: mull %ebx318; X86-NEXT: addl %edx, %edi319; X86-NEXT: adcl $0, %ecx320; X86-NEXT: movl {{[0-9]+}}(%esp), %eax321; X86-NEXT: mull %ebp322; X86-NEXT: movl %edx, %esi323; X86-NEXT: movl %eax, %ebp324; X86-NEXT: movl {{[0-9]+}}(%esp), %eax325; X86-NEXT: mull %ebx326; X86-NEXT: addl %edi, %eax327; X86-NEXT: adcl %edx, %ecx328; X86-NEXT: adcl $0, %esi329; X86-NEXT: addl %ebp, %ecx330; X86-NEXT: adcl $0, %esi331; X86-NEXT: shldl $1, %ecx, %esi332; X86-NEXT: shrdl $31, %ecx, %eax333; X86-NEXT: movl %esi, %edx334; X86-NEXT: popl %esi335; X86-NEXT: popl %edi336; X86-NEXT: popl %ebx337; X86-NEXT: popl %ebp338; X86-NEXT: retl339 %tmp = call i64 @llvm.umul.fix.i64(i64 %x, i64 %y, i32 63)340 ret i64 %tmp341}342 343define i64 @func9(i64 %x, i64 %y) nounwind {344; X64-LABEL: func9:345; X64: # %bb.0:346; X64-NEXT: movq %rdi, %rax347; X64-NEXT: mulq %rsi348; X64-NEXT: movq %rdx, %rax349; X64-NEXT: retq350;351; X86-LABEL: func9:352; X86: # %bb.0:353; X86-NEXT: pushl %ebp354; X86-NEXT: pushl %ebx355; X86-NEXT: pushl %edi356; X86-NEXT: pushl %esi357; X86-NEXT: movl {{[0-9]+}}(%esp), %edi358; X86-NEXT: movl {{[0-9]+}}(%esp), %esi359; X86-NEXT: movl %edi, %eax360; X86-NEXT: mull %esi361; X86-NEXT: movl %edx, %ecx362; X86-NEXT: movl %eax, %ebp363; X86-NEXT: movl %edi, %eax364; X86-NEXT: mull {{[0-9]+}}(%esp)365; X86-NEXT: movl %edx, %ebx366; X86-NEXT: addl %ebp, %ebx367; X86-NEXT: adcl $0, %ecx368; X86-NEXT: movl {{[0-9]+}}(%esp), %eax369; X86-NEXT: mull %esi370; X86-NEXT: movl %edx, %edi371; X86-NEXT: movl %eax, %ebp372; X86-NEXT: movl {{[0-9]+}}(%esp), %eax373; X86-NEXT: mull {{[0-9]+}}(%esp)374; X86-NEXT: addl %ebx, %eax375; X86-NEXT: adcl %edx, %ecx376; X86-NEXT: adcl $0, %edi377; X86-NEXT: addl %ebp, %ecx378; X86-NEXT: adcl $0, %edi379; X86-NEXT: movl %ecx, %eax380; X86-NEXT: movl %edi, %edx381; X86-NEXT: popl %esi382; X86-NEXT: popl %edi383; X86-NEXT: popl %ebx384; X86-NEXT: popl %ebp385; X86-NEXT: retl386 %tmp = call i64 @llvm.umul.fix.i64(i64 %x, i64 %y, i32 64)387 ret i64 %tmp388}389