331 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X86-NOBMI3; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi2 | FileCheck %s --check-prefix=X86-BMI4; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64-NOBMI5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi2 | FileCheck %s --check-prefix=X64-BMI6 7; PR11988 9define i64 @foo(i64 %x, i64 %y) nounwind {10; X86-NOBMI-LABEL: foo:11; X86-NOBMI: # %bb.0:12; X86-NOBMI-NEXT: pushl %ebp13; X86-NOBMI-NEXT: pushl %ebx14; X86-NOBMI-NEXT: pushl %edi15; X86-NOBMI-NEXT: pushl %esi16; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi17; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ebx18; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi19; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx20; X86-NOBMI-NEXT: movl %edi, %eax21; X86-NOBMI-NEXT: mull %esi22; X86-NOBMI-NEXT: movl %edx, %ebp23; X86-NOBMI-NEXT: movl %ebx, %eax24; X86-NOBMI-NEXT: mull %esi25; X86-NOBMI-NEXT: movl %edx, %esi26; X86-NOBMI-NEXT: movl %eax, %ebx27; X86-NOBMI-NEXT: addl %ebp, %ebx28; X86-NOBMI-NEXT: adcl $0, %esi29; X86-NOBMI-NEXT: movl %edi, %eax30; X86-NOBMI-NEXT: mull %ecx31; X86-NOBMI-NEXT: addl %ebx, %eax32; X86-NOBMI-NEXT: adcl %edx, %esi33; X86-NOBMI-NEXT: setb %al34; X86-NOBMI-NEXT: movzbl %al, %edi35; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax36; X86-NOBMI-NEXT: mull %ecx37; X86-NOBMI-NEXT: addl %esi, %eax38; X86-NOBMI-NEXT: adcl %edi, %edx39; X86-NOBMI-NEXT: popl %esi40; X86-NOBMI-NEXT: popl %edi41; X86-NOBMI-NEXT: popl %ebx42; X86-NOBMI-NEXT: popl %ebp43; X86-NOBMI-NEXT: retl44;45; X86-BMI-LABEL: foo:46; X86-BMI: # %bb.0:47; X86-BMI-NEXT: pushl %ebp48; X86-BMI-NEXT: pushl %ebx49; X86-BMI-NEXT: pushl %edi50; X86-BMI-NEXT: pushl %esi51; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %ecx52; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %eax53; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %edi54; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %esi55; X86-BMI-NEXT: movl %ecx, %edx56; X86-BMI-NEXT: mulxl %edi, %ebx, %ebx57; X86-BMI-NEXT: movl %eax, %edx58; X86-BMI-NEXT: mulxl %edi, %edi, %ebp59; X86-BMI-NEXT: addl %ebx, %edi60; X86-BMI-NEXT: adcl $0, %ebp61; X86-BMI-NEXT: movl %ecx, %edx62; X86-BMI-NEXT: mulxl %esi, %ecx, %ebx63; X86-BMI-NEXT: addl %edi, %ecx64; X86-BMI-NEXT: adcl %ebp, %ebx65; X86-BMI-NEXT: setb %cl66; X86-BMI-NEXT: movzbl %cl, %ecx67; X86-BMI-NEXT: movl %eax, %edx68; X86-BMI-NEXT: mulxl %esi, %eax, %edx69; X86-BMI-NEXT: addl %ebx, %eax70; X86-BMI-NEXT: adcl %ecx, %edx71; X86-BMI-NEXT: popl %esi72; X86-BMI-NEXT: popl %edi73; X86-BMI-NEXT: popl %ebx74; X86-BMI-NEXT: popl %ebp75; X86-BMI-NEXT: retl76;77; X64-NOBMI-LABEL: foo:78; X64-NOBMI: # %bb.0:79; X64-NOBMI-NEXT: movq %rdi, %rax80; X64-NOBMI-NEXT: mulq %rsi81; X64-NOBMI-NEXT: movq %rdx, %rax82; X64-NOBMI-NEXT: retq83;84; X64-BMI-LABEL: foo:85; X64-BMI: # %bb.0:86; X64-BMI-NEXT: movq %rdi, %rdx87; X64-BMI-NEXT: mulxq %rsi, %rax, %rax88; X64-BMI-NEXT: retq89 %tmp0 = zext i64 %x to i12890 %tmp1 = zext i64 %y to i12891 %tmp2 = mul i128 %tmp0, %tmp192 %tmp7 = zext i32 64 to i12893 %tmp3 = lshr i128 %tmp2, %tmp794 %tmp4 = trunc i128 %tmp3 to i6495 ret i64 %tmp496}97 98; <rdar://problem/14096009> superfluous multiply by high part of99; zero-extended value.100 101define i64 @mul1(i64 %n, ptr nocapture %z, ptr nocapture %x, i64 %y) nounwind {102; X86-NOBMI-LABEL: mul1:103; X86-NOBMI: # %bb.0: # %entry104; X86-NOBMI-NEXT: pushl %ebp105; X86-NOBMI-NEXT: pushl %ebx106; X86-NOBMI-NEXT: pushl %edi107; X86-NOBMI-NEXT: pushl %esi108; X86-NOBMI-NEXT: subl $20, %esp109; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx110; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax111; X86-NOBMI-NEXT: orl %ecx, %eax112; X86-NOBMI-NEXT: je .LBB1_3113; X86-NOBMI-NEXT: # %bb.1: # %for.body.preheader114; X86-NOBMI-NEXT: xorl %eax, %eax115; X86-NOBMI-NEXT: xorl %edx, %edx116; X86-NOBMI-NEXT: xorl %ecx, %ecx117; X86-NOBMI-NEXT: movl $0, (%esp) # 4-byte Folded Spill118; X86-NOBMI-NEXT: .p2align 4119; X86-NOBMI-NEXT: .LBB1_2: # %for.body120; X86-NOBMI-NEXT: # =>This Inner Loop Header: Depth=1121; X86-NOBMI-NEXT: movl %edx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill122; X86-NOBMI-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill123; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax124; X86-NOBMI-NEXT: movl (%eax,%ecx,8), %edi125; X86-NOBMI-NEXT: movl 4(%eax,%ecx,8), %ebx126; X86-NOBMI-NEXT: movl %ebx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill127; X86-NOBMI-NEXT: movl %edi, %eax128; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi129; X86-NOBMI-NEXT: mull %esi130; X86-NOBMI-NEXT: movl %edx, %ebp131; X86-NOBMI-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill132; X86-NOBMI-NEXT: movl %ebx, %eax133; X86-NOBMI-NEXT: mull %esi134; X86-NOBMI-NEXT: movl %edx, %ebx135; X86-NOBMI-NEXT: movl %eax, %esi136; X86-NOBMI-NEXT: addl %ebp, %esi137; X86-NOBMI-NEXT: adcl $0, %ebx138; X86-NOBMI-NEXT: movl %edi, %eax139; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx140; X86-NOBMI-NEXT: mull %edx141; X86-NOBMI-NEXT: movl %edx, %ebp142; X86-NOBMI-NEXT: movl %eax, %edi143; X86-NOBMI-NEXT: addl %esi, %edi144; X86-NOBMI-NEXT: adcl %ebx, %ebp145; X86-NOBMI-NEXT: setb %bl146; X86-NOBMI-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload147; X86-NOBMI-NEXT: mull {{[0-9]+}}(%esp)148; X86-NOBMI-NEXT: addl %ebp, %eax149; X86-NOBMI-NEXT: movzbl %bl, %esi150; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ebp151; X86-NOBMI-NEXT: adcl %esi, %edx152; X86-NOBMI-NEXT: movl %ecx, %ebx153; X86-NOBMI-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload154; X86-NOBMI-NEXT: addl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Folded Reload155; X86-NOBMI-NEXT: adcl {{[-0-9]+}}(%e{{[sb]}}p), %edi # 4-byte Folded Reload156; X86-NOBMI-NEXT: adcl $0, %eax157; X86-NOBMI-NEXT: adcl $0, %edx158; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi159; X86-NOBMI-NEXT: movl %ecx, (%esi,%ebx,8)160; X86-NOBMI-NEXT: movl %ebx, %ecx161; X86-NOBMI-NEXT: movl %edi, 4(%esi,%ebx,8)162; X86-NOBMI-NEXT: addl $1, %ecx163; X86-NOBMI-NEXT: movl (%esp), %edi # 4-byte Reload164; X86-NOBMI-NEXT: adcl $0, %edi165; X86-NOBMI-NEXT: movl %ecx, %esi166; X86-NOBMI-NEXT: xorl {{[0-9]+}}(%esp), %esi167; X86-NOBMI-NEXT: movl %edi, (%esp) # 4-byte Spill168; X86-NOBMI-NEXT: xorl %ebp, %edi169; X86-NOBMI-NEXT: orl %esi, %edi170; X86-NOBMI-NEXT: jne .LBB1_2171; X86-NOBMI-NEXT: .LBB1_3: # %for.end172; X86-NOBMI-NEXT: xorl %eax, %eax173; X86-NOBMI-NEXT: xorl %edx, %edx174; X86-NOBMI-NEXT: addl $20, %esp175; X86-NOBMI-NEXT: popl %esi176; X86-NOBMI-NEXT: popl %edi177; X86-NOBMI-NEXT: popl %ebx178; X86-NOBMI-NEXT: popl %ebp179; X86-NOBMI-NEXT: retl180;181; X86-BMI-LABEL: mul1:182; X86-BMI: # %bb.0: # %entry183; X86-BMI-NEXT: pushl %ebp184; X86-BMI-NEXT: pushl %ebx185; X86-BMI-NEXT: pushl %edi186; X86-BMI-NEXT: pushl %esi187; X86-BMI-NEXT: subl $20, %esp188; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %ecx189; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %eax190; X86-BMI-NEXT: orl %ecx, %eax191; X86-BMI-NEXT: je .LBB1_3192; X86-BMI-NEXT: # %bb.1: # %for.body.preheader193; X86-BMI-NEXT: xorl %ecx, %ecx194; X86-BMI-NEXT: xorl %eax, %eax195; X86-BMI-NEXT: xorl %ebx, %ebx196; X86-BMI-NEXT: xorl %ebp, %ebp197; X86-BMI-NEXT: .p2align 4198; X86-BMI-NEXT: .LBB1_2: # %for.body199; X86-BMI-NEXT: # =>This Inner Loop Header: Depth=1200; X86-BMI-NEXT: movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill201; X86-BMI-NEXT: movl %eax, (%esp) # 4-byte Spill202; X86-BMI-NEXT: movl %ebp, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill203; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %eax204; X86-BMI-NEXT: movl (%eax,%ebx,8), %ecx205; X86-BMI-NEXT: movl 4(%eax,%ebx,8), %esi206; X86-BMI-NEXT: movl %esi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill207; X86-BMI-NEXT: movl %ecx, %edx208; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %eax209; X86-BMI-NEXT: mulxl %eax, %edx, %edi210; X86-BMI-NEXT: movl %edx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill211; X86-BMI-NEXT: movl %esi, %edx212; X86-BMI-NEXT: mulxl %eax, %esi, %eax213; X86-BMI-NEXT: addl %edi, %esi214; X86-BMI-NEXT: adcl $0, %eax215; X86-BMI-NEXT: movl %ecx, %edx216; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %ecx217; X86-BMI-NEXT: mulxl %ecx, %edi, %ebp218; X86-BMI-NEXT: addl %esi, %edi219; X86-BMI-NEXT: adcl %eax, %ebp220; X86-BMI-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %edx # 4-byte Reload221; X86-BMI-NEXT: mulxl %ecx, %ecx, %eax222; X86-BMI-NEXT: setb %dl223; X86-BMI-NEXT: addl %ebp, %ecx224; X86-BMI-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ebp # 4-byte Reload225; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %esi226; X86-BMI-NEXT: movzbl %dl, %edx227; X86-BMI-NEXT: adcl %edx, %eax228; X86-BMI-NEXT: movl %eax, %edx229; X86-BMI-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload230; X86-BMI-NEXT: addl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Folded Reload231; X86-BMI-NEXT: adcl (%esp), %edi # 4-byte Folded Reload232; X86-BMI-NEXT: adcl $0, %ecx233; X86-BMI-NEXT: adcl $0, %edx234; X86-BMI-NEXT: movl %edx, (%esp) # 4-byte Spill235; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %edx236; X86-BMI-NEXT: movl %eax, (%edx,%ebx,8)237; X86-BMI-NEXT: movl %edi, 4(%edx,%ebx,8)238; X86-BMI-NEXT: movl {{[0-9]+}}(%esp), %edi239; X86-BMI-NEXT: addl $1, %ebx240; X86-BMI-NEXT: adcl $0, %ebp241; X86-BMI-NEXT: movl %ebx, %edx242; X86-BMI-NEXT: xorl %esi, %edx243; X86-BMI-NEXT: movl %ebp, %esi244; X86-BMI-NEXT: xorl %edi, %esi245; X86-BMI-NEXT: orl %edx, %esi246; X86-BMI-NEXT: movl (%esp), %eax # 4-byte Reload247; X86-BMI-NEXT: jne .LBB1_2248; X86-BMI-NEXT: .LBB1_3: # %for.end249; X86-BMI-NEXT: xorl %eax, %eax250; X86-BMI-NEXT: xorl %edx, %edx251; X86-BMI-NEXT: addl $20, %esp252; X86-BMI-NEXT: popl %esi253; X86-BMI-NEXT: popl %edi254; X86-BMI-NEXT: popl %ebx255; X86-BMI-NEXT: popl %ebp256; X86-BMI-NEXT: retl257;258; X64-NOBMI-LABEL: mul1:259; X64-NOBMI: # %bb.0: # %entry260; X64-NOBMI-NEXT: testq %rdi, %rdi261; X64-NOBMI-NEXT: je .LBB1_3262; X64-NOBMI-NEXT: # %bb.1: # %for.body.preheader263; X64-NOBMI-NEXT: movq %rdx, %r8264; X64-NOBMI-NEXT: xorl %r10d, %r10d265; X64-NOBMI-NEXT: xorl %r9d, %r9d266; X64-NOBMI-NEXT: .p2align 4267; X64-NOBMI-NEXT: .LBB1_2: # %for.body268; X64-NOBMI-NEXT: # =>This Inner Loop Header: Depth=1269; X64-NOBMI-NEXT: movq %rcx, %rax270; X64-NOBMI-NEXT: mulq (%r8,%r9,8)271; X64-NOBMI-NEXT: addq %r10, %rax272; X64-NOBMI-NEXT: adcq $0, %rdx273; X64-NOBMI-NEXT: movq %rax, (%rsi,%r9,8)274; X64-NOBMI-NEXT: incq %r9275; X64-NOBMI-NEXT: cmpq %r9, %rdi276; X64-NOBMI-NEXT: movq %rdx, %r10277; X64-NOBMI-NEXT: jne .LBB1_2278; X64-NOBMI-NEXT: .LBB1_3: # %for.end279; X64-NOBMI-NEXT: xorl %eax, %eax280; X64-NOBMI-NEXT: retq281;282; X64-BMI-LABEL: mul1:283; X64-BMI: # %bb.0: # %entry284; X64-BMI-NEXT: testq %rdi, %rdi285; X64-BMI-NEXT: je .LBB1_3286; X64-BMI-NEXT: # %bb.1: # %for.body.preheader287; X64-BMI-NEXT: movq %rdx, %rax288; X64-BMI-NEXT: xorl %r9d, %r9d289; X64-BMI-NEXT: xorl %r8d, %r8d290; X64-BMI-NEXT: .p2align 4291; X64-BMI-NEXT: .LBB1_2: # %for.body292; X64-BMI-NEXT: # =>This Inner Loop Header: Depth=1293; X64-BMI-NEXT: movq %rcx, %rdx294; X64-BMI-NEXT: mulxq (%rax,%r8,8), %r10, %rdx295; X64-BMI-NEXT: addq %r9, %r10296; X64-BMI-NEXT: adcq $0, %rdx297; X64-BMI-NEXT: movq %r10, (%rsi,%r8,8)298; X64-BMI-NEXT: incq %r8299; X64-BMI-NEXT: cmpq %r8, %rdi300; X64-BMI-NEXT: movq %rdx, %r9301; X64-BMI-NEXT: jne .LBB1_2302; X64-BMI-NEXT: .LBB1_3: # %for.end303; X64-BMI-NEXT: xorl %eax, %eax304; X64-BMI-NEXT: retq305entry:306 %conv = zext i64 %y to i128307 %cmp11 = icmp eq i64 %n, 0308 br i1 %cmp11, label %for.end, label %for.body309 310for.body: ; preds = %entry, %for.body311 %carry.013 = phi i64 [ %conv6, %for.body ], [ 0, %entry ]312 %i.012 = phi i64 [ %inc, %for.body ], [ 0, %entry ]313 %arrayidx = getelementptr inbounds i64, ptr %x, i64 %i.012314 %0 = load i64, ptr %arrayidx, align 8315 %conv2 = zext i64 %0 to i128316 %mul = mul i128 %conv2, %conv317 %conv3 = zext i64 %carry.013 to i128318 %add = add i128 %mul, %conv3319 %conv4 = trunc i128 %add to i64320 %arrayidx5 = getelementptr inbounds i64, ptr %z, i64 %i.012321 store i64 %conv4, ptr %arrayidx5, align 8322 %shr = lshr i128 %add, 64323 %conv6 = trunc i128 %shr to i64324 %inc = add i64 %i.012, 1325 %exitcond = icmp eq i64 %inc, %n326 br i1 %exitcond, label %for.end, label %for.body327 328for.end: ; preds = %for.body, %entry329 ret i64 0330}331