442 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.2 | FileCheck %s3 4; Verify when widening a divide/remainder operation, we only generate a5; divide/rem per element since divide/remainder can trap.6 7define void @vectorDiv (ptr addrspace(1) %nsource, ptr addrspace(1) %dsource, ptr addrspace(1) %qdest) nounwind {8; CHECK-LABEL: vectorDiv:9; CHECK: # %bb.0: # %entry10; CHECK-NEXT: movq %rdx, %rcx11; CHECK-NEXT: movq %rdi, -{{[0-9]+}}(%rsp)12; CHECK-NEXT: movq %rsi, -{{[0-9]+}}(%rsp)13; CHECK-NEXT: movq %rdx, -{{[0-9]+}}(%rsp)14; CHECK-NEXT: movslq -{{[0-9]+}}(%rsp), %r815; CHECK-NEXT: movq (%rdi,%r8,8), %rdi16; CHECK-NEXT: movq (%rsi,%r8,8), %r917; CHECK-NEXT: movq %rdi, %rax18; CHECK-NEXT: shrq $32, %rax19; CHECK-NEXT: movq %r9, %rsi20; CHECK-NEXT: shrq $32, %rsi21; CHECK-NEXT: # kill: def $eax killed $eax killed $rax22; CHECK-NEXT: cltd23; CHECK-NEXT: idivl %esi24; CHECK-NEXT: movl %eax, %esi25; CHECK-NEXT: movl %edi, %eax26; CHECK-NEXT: cltd27; CHECK-NEXT: idivl %r9d28; CHECK-NEXT: movd %eax, %xmm029; CHECK-NEXT: pinsrd $1, %esi, %xmm030; CHECK-NEXT: movq %xmm0, (%rcx,%r8,8)31; CHECK-NEXT: retq32entry:33 %nsource.addr = alloca ptr addrspace(1), align 434 %dsource.addr = alloca ptr addrspace(1), align 435 %qdest.addr = alloca ptr addrspace(1), align 436 %index = alloca i32, align 437 store ptr addrspace(1) %nsource, ptr %nsource.addr38 store ptr addrspace(1) %dsource, ptr %dsource.addr39 store ptr addrspace(1) %qdest, ptr %qdest.addr40 %tmp = load ptr addrspace(1), ptr %qdest.addr41 %tmp1 = load i32, ptr %index42 %arrayidx = getelementptr <2 x i32>, ptr addrspace(1) %tmp, i32 %tmp143 %tmp2 = load ptr addrspace(1), ptr %nsource.addr44 %tmp3 = load i32, ptr %index45 %arrayidx4 = getelementptr <2 x i32>, ptr addrspace(1) %tmp2, i32 %tmp346 %tmp5 = load <2 x i32>, ptr addrspace(1) %arrayidx447 %tmp6 = load ptr addrspace(1), ptr %dsource.addr48 %tmp7 = load i32, ptr %index49 %arrayidx8 = getelementptr <2 x i32>, ptr addrspace(1) %tmp6, i32 %tmp750 %tmp9 = load <2 x i32>, ptr addrspace(1) %arrayidx851 %tmp10 = sdiv <2 x i32> %tmp5, %tmp952 store <2 x i32> %tmp10, ptr addrspace(1) %arrayidx53 ret void54}55 56define <3 x i8> @test_char_div(<3 x i8> %num, <3 x i8> %div) {57; CHECK-LABEL: test_char_div:58; CHECK: # %bb.0:59; CHECK-NEXT: movsbl %dil, %eax60; CHECK-NEXT: idivb %cl61; CHECK-NEXT: movl %eax, %ecx62; CHECK-NEXT: movsbl %sil, %eax63; CHECK-NEXT: idivb %r8b64; CHECK-NEXT: movl %eax, %esi65; CHECK-NEXT: movsbl %dl, %eax66; CHECK-NEXT: idivb %r9b67; CHECK-NEXT: movl %eax, %edi68; CHECK-NEXT: movl %ecx, %eax69; CHECK-NEXT: movl %esi, %edx70; CHECK-NEXT: movl %edi, %ecx71; CHECK-NEXT: retq72 %div.r = sdiv <3 x i8> %num, %div73 ret <3 x i8> %div.r74}75 76define <3 x i8> @test_uchar_div(<3 x i8> %num, <3 x i8> %div) {77; CHECK-LABEL: test_uchar_div:78; CHECK: # %bb.0:79; CHECK-NEXT: movzbl %dil, %eax80; CHECK-NEXT: divb %cl81; CHECK-NEXT: movl %eax, %ecx82; CHECK-NEXT: movzbl %sil, %eax83; CHECK-NEXT: divb %r8b84; CHECK-NEXT: movl %eax, %esi85; CHECK-NEXT: movzbl %dl, %eax86; CHECK-NEXT: divb %r9b87; CHECK-NEXT: movl %eax, %edi88; CHECK-NEXT: movl %ecx, %eax89; CHECK-NEXT: movl %esi, %edx90; CHECK-NEXT: movl %edi, %ecx91; CHECK-NEXT: retq92 %div.r = udiv <3 x i8> %num, %div93 ret <3 x i8> %div.r94}95 96define <5 x i16> @test_short_div(<5 x i16> %num, <5 x i16> %div) {97; CHECK-LABEL: test_short_div:98; CHECK: # %bb.0:99; CHECK-NEXT: pextrw $4, %xmm0, %eax100; CHECK-NEXT: pextrw $4, %xmm1, %ecx101; CHECK-NEXT: # kill: def $ax killed $ax killed $eax102; CHECK-NEXT: cwtd103; CHECK-NEXT: idivw %cx104; CHECK-NEXT: movl %eax, %ecx105; CHECK-NEXT: pextrw $3, %xmm0, %eax106; CHECK-NEXT: pextrw $3, %xmm1, %esi107; CHECK-NEXT: # kill: def $ax killed $ax killed $eax108; CHECK-NEXT: cwtd109; CHECK-NEXT: idivw %si110; CHECK-NEXT: movl %eax, %esi111; CHECK-NEXT: pextrw $2, %xmm0, %eax112; CHECK-NEXT: pextrw $2, %xmm1, %edi113; CHECK-NEXT: # kill: def $ax killed $ax killed $eax114; CHECK-NEXT: cwtd115; CHECK-NEXT: idivw %di116; CHECK-NEXT: movl %eax, %edi117; CHECK-NEXT: movd %xmm0, %eax118; CHECK-NEXT: movd %xmm1, %r8d119; CHECK-NEXT: # kill: def $ax killed $ax killed $eax120; CHECK-NEXT: cwtd121; CHECK-NEXT: idivw %r8w122; CHECK-NEXT: movl %eax, %r8d123; CHECK-NEXT: pextrw $1, %xmm0, %eax124; CHECK-NEXT: pextrw $1, %xmm1, %r9d125; CHECK-NEXT: # kill: def $ax killed $ax killed $eax126; CHECK-NEXT: cwtd127; CHECK-NEXT: idivw %r9w128; CHECK-NEXT: # kill: def $ax killed $ax def $eax129; CHECK-NEXT: movd %r8d, %xmm0130; CHECK-NEXT: pinsrw $1, %eax, %xmm0131; CHECK-NEXT: pinsrw $2, %edi, %xmm0132; CHECK-NEXT: pinsrw $3, %esi, %xmm0133; CHECK-NEXT: pinsrw $4, %ecx, %xmm0134; CHECK-NEXT: retq135 %div.r = sdiv <5 x i16> %num, %div136 ret <5 x i16> %div.r137}138 139define <4 x i16> @test_ushort_div(<4 x i16> %num, <4 x i16> %div) {140; CHECK-LABEL: test_ushort_div:141; CHECK: # %bb.0:142; CHECK-NEXT: pextrw $1, %xmm0, %eax143; CHECK-NEXT: pextrw $1, %xmm1, %ecx144; CHECK-NEXT: # kill: def $ax killed $ax killed $eax145; CHECK-NEXT: xorl %edx, %edx146; CHECK-NEXT: divw %cx147; CHECK-NEXT: movl %eax, %ecx148; CHECK-NEXT: movd %xmm0, %eax149; CHECK-NEXT: movd %xmm1, %esi150; CHECK-NEXT: # kill: def $ax killed $ax killed $eax151; CHECK-NEXT: xorl %edx, %edx152; CHECK-NEXT: divw %si153; CHECK-NEXT: # kill: def $ax killed $ax def $eax154; CHECK-NEXT: movd %eax, %xmm2155; CHECK-NEXT: pinsrw $1, %ecx, %xmm2156; CHECK-NEXT: pextrw $2, %xmm0, %eax157; CHECK-NEXT: pextrw $2, %xmm1, %ecx158; CHECK-NEXT: # kill: def $ax killed $ax killed $eax159; CHECK-NEXT: xorl %edx, %edx160; CHECK-NEXT: divw %cx161; CHECK-NEXT: # kill: def $ax killed $ax def $eax162; CHECK-NEXT: pinsrw $2, %eax, %xmm2163; CHECK-NEXT: pextrw $3, %xmm0, %eax164; CHECK-NEXT: pextrw $3, %xmm1, %ecx165; CHECK-NEXT: # kill: def $ax killed $ax killed $eax166; CHECK-NEXT: xorl %edx, %edx167; CHECK-NEXT: divw %cx168; CHECK-NEXT: # kill: def $ax killed $ax def $eax169; CHECK-NEXT: pinsrw $3, %eax, %xmm2170; CHECK-NEXT: movdqa %xmm2, %xmm0171; CHECK-NEXT: retq172 %div.r = udiv <4 x i16> %num, %div173 ret <4 x i16> %div.r174}175 176define <3 x i32> @test_uint_div(<3 x i32> %num, <3 x i32> %div) {177; CHECK-LABEL: test_uint_div:178; CHECK: # %bb.0:179; CHECK-NEXT: pextrd $2, %xmm0, %eax180; CHECK-NEXT: pextrd $2, %xmm1, %ecx181; CHECK-NEXT: xorl %edx, %edx182; CHECK-NEXT: divl %ecx183; CHECK-NEXT: movl %eax, %ecx184; CHECK-NEXT: pextrd $1, %xmm0, %eax185; CHECK-NEXT: pextrd $1, %xmm1, %esi186; CHECK-NEXT: xorl %edx, %edx187; CHECK-NEXT: divl %esi188; CHECK-NEXT: movl %eax, %esi189; CHECK-NEXT: movd %xmm0, %eax190; CHECK-NEXT: movd %xmm1, %edi191; CHECK-NEXT: xorl %edx, %edx192; CHECK-NEXT: divl %edi193; CHECK-NEXT: movd %eax, %xmm0194; CHECK-NEXT: pinsrd $1, %esi, %xmm0195; CHECK-NEXT: pinsrd $2, %ecx, %xmm0196; CHECK-NEXT: retq197 %div.r = udiv <3 x i32> %num, %div198 ret <3 x i32> %div.r199}200 201define <3 x i64> @test_long_div(<3 x i64> %num, <3 x i64> %div) {202; CHECK-LABEL: test_long_div:203; CHECK: # %bb.0:204; CHECK-NEXT: movq %rdx, %r10205; CHECK-NEXT: movq %rdi, %rax206; CHECK-NEXT: cqto207; CHECK-NEXT: idivq %rcx208; CHECK-NEXT: movq %rax, %rcx209; CHECK-NEXT: movq %rsi, %rax210; CHECK-NEXT: cqto211; CHECK-NEXT: idivq %r8212; CHECK-NEXT: movq %rax, %rsi213; CHECK-NEXT: movq %r10, %rax214; CHECK-NEXT: cqto215; CHECK-NEXT: idivq %r9216; CHECK-NEXT: movq %rax, %rdi217; CHECK-NEXT: movq %rcx, %rax218; CHECK-NEXT: movq %rsi, %rdx219; CHECK-NEXT: movq %rdi, %rcx220; CHECK-NEXT: retq221 %div.r = sdiv <3 x i64> %num, %div222 ret <3 x i64> %div.r223}224 225define <3 x i64> @test_ulong_div(<3 x i64> %num, <3 x i64> %div) {226; CHECK-LABEL: test_ulong_div:227; CHECK: # %bb.0:228; CHECK-NEXT: movq %rdx, %r10229; CHECK-NEXT: movq %rdi, %rax230; CHECK-NEXT: xorl %edx, %edx231; CHECK-NEXT: divq %rcx232; CHECK-NEXT: movq %rax, %rcx233; CHECK-NEXT: movq %rsi, %rax234; CHECK-NEXT: xorl %edx, %edx235; CHECK-NEXT: divq %r8236; CHECK-NEXT: movq %rax, %rsi237; CHECK-NEXT: movq %r10, %rax238; CHECK-NEXT: xorl %edx, %edx239; CHECK-NEXT: divq %r9240; CHECK-NEXT: movq %rax, %rdi241; CHECK-NEXT: movq %rcx, %rax242; CHECK-NEXT: movq %rsi, %rdx243; CHECK-NEXT: movq %rdi, %rcx244; CHECK-NEXT: retq245 %div.r = udiv <3 x i64> %num, %div246 ret <3 x i64> %div.r247}248 249define <4 x i8> @test_char_rem(<4 x i8> %num, <4 x i8> %rem) {250; CHECK-LABEL: test_char_rem:251; CHECK: # %bb.0:252; CHECK-NEXT: pextrb $1, %xmm1, %ecx253; CHECK-NEXT: pextrb $1, %xmm0, %eax254; CHECK-NEXT: cbtw255; CHECK-NEXT: idivb %cl256; CHECK-NEXT: movsbl %ah, %ecx257; CHECK-NEXT: movd %xmm1, %edx258; CHECK-NEXT: movd %xmm0, %eax259; CHECK-NEXT: cbtw260; CHECK-NEXT: idivb %dl261; CHECK-NEXT: movsbl %ah, %eax262; CHECK-NEXT: movd %eax, %xmm2263; CHECK-NEXT: pinsrb $1, %ecx, %xmm2264; CHECK-NEXT: pextrb $2, %xmm1, %ecx265; CHECK-NEXT: pextrb $2, %xmm0, %eax266; CHECK-NEXT: cbtw267; CHECK-NEXT: idivb %cl268; CHECK-NEXT: movsbl %ah, %eax269; CHECK-NEXT: pinsrb $2, %eax, %xmm2270; CHECK-NEXT: pextrb $3, %xmm1, %ecx271; CHECK-NEXT: pextrb $3, %xmm0, %eax272; CHECK-NEXT: cbtw273; CHECK-NEXT: idivb %cl274; CHECK-NEXT: movsbl %ah, %eax275; CHECK-NEXT: pinsrb $3, %eax, %xmm2276; CHECK-NEXT: movdqa %xmm2, %xmm0277; CHECK-NEXT: retq278 %rem.r = srem <4 x i8> %num, %rem279 ret <4 x i8> %rem.r280}281 282define <5 x i16> @test_short_rem(<5 x i16> %num, <5 x i16> %rem) {283; CHECK-LABEL: test_short_rem:284; CHECK: # %bb.0:285; CHECK-NEXT: pextrw $4, %xmm0, %eax286; CHECK-NEXT: pextrw $4, %xmm1, %ecx287; CHECK-NEXT: # kill: def $ax killed $ax killed $eax288; CHECK-NEXT: cwtd289; CHECK-NEXT: idivw %cx290; CHECK-NEXT: movl %edx, %ecx291; CHECK-NEXT: pextrw $3, %xmm0, %eax292; CHECK-NEXT: pextrw $3, %xmm1, %esi293; CHECK-NEXT: # kill: def $ax killed $ax killed $eax294; CHECK-NEXT: cwtd295; CHECK-NEXT: idivw %si296; CHECK-NEXT: movl %edx, %esi297; CHECK-NEXT: pextrw $2, %xmm0, %eax298; CHECK-NEXT: pextrw $2, %xmm1, %edi299; CHECK-NEXT: # kill: def $ax killed $ax killed $eax300; CHECK-NEXT: cwtd301; CHECK-NEXT: idivw %di302; CHECK-NEXT: movl %edx, %edi303; CHECK-NEXT: movd %xmm0, %eax304; CHECK-NEXT: movd %xmm1, %r8d305; CHECK-NEXT: # kill: def $ax killed $ax killed $eax306; CHECK-NEXT: cwtd307; CHECK-NEXT: idivw %r8w308; CHECK-NEXT: movl %edx, %r8d309; CHECK-NEXT: pextrw $1, %xmm0, %eax310; CHECK-NEXT: pextrw $1, %xmm1, %r9d311; CHECK-NEXT: # kill: def $ax killed $ax killed $eax312; CHECK-NEXT: cwtd313; CHECK-NEXT: idivw %r9w314; CHECK-NEXT: # kill: def $dx killed $dx def $edx315; CHECK-NEXT: movd %r8d, %xmm0316; CHECK-NEXT: pinsrw $1, %edx, %xmm0317; CHECK-NEXT: pinsrw $2, %edi, %xmm0318; CHECK-NEXT: pinsrw $3, %esi, %xmm0319; CHECK-NEXT: pinsrw $4, %ecx, %xmm0320; CHECK-NEXT: retq321 %rem.r = srem <5 x i16> %num, %rem322 ret <5 x i16> %rem.r323}324 325define <4 x i32> @test_uint_rem(<4 x i32> %num, <4 x i32> %rem) {326; CHECK-LABEL: test_uint_rem:327; CHECK: # %bb.0:328; CHECK-NEXT: pextrd $1, %xmm0, %eax329; CHECK-NEXT: pextrd $1, %xmm1, %ecx330; CHECK-NEXT: cltd331; CHECK-NEXT: idivl %ecx332; CHECK-NEXT: movl %edx, %ecx333; CHECK-NEXT: movd %xmm0, %eax334; CHECK-NEXT: movd %xmm1, %esi335; CHECK-NEXT: cltd336; CHECK-NEXT: idivl %esi337; CHECK-NEXT: movd %edx, %xmm2338; CHECK-NEXT: pinsrd $1, %ecx, %xmm2339; CHECK-NEXT: pextrd $2, %xmm0, %eax340; CHECK-NEXT: pextrd $2, %xmm1, %ecx341; CHECK-NEXT: cltd342; CHECK-NEXT: idivl %ecx343; CHECK-NEXT: pinsrd $2, %edx, %xmm2344; CHECK-NEXT: pextrd $3, %xmm0, %eax345; CHECK-NEXT: pextrd $3, %xmm1, %ecx346; CHECK-NEXT: cltd347; CHECK-NEXT: idivl %ecx348; CHECK-NEXT: pinsrd $3, %edx, %xmm2349; CHECK-NEXT: movdqa %xmm2, %xmm0350; CHECK-NEXT: retq351 %rem.r = srem <4 x i32> %num, %rem352 ret <4 x i32> %rem.r353}354 355 356define <5 x i64> @test_ulong_rem(<5 x i64> %num, <5 x i64> %rem) {357; CHECK-LABEL: test_ulong_rem:358; CHECK: # %bb.0:359; CHECK-NEXT: movq %rdx, %rax360; CHECK-NEXT: xorl %edx, %edx361; CHECK-NEXT: divq {{[0-9]+}}(%rsp)362; CHECK-NEXT: movq %rdx, %xmm0363; CHECK-NEXT: movq %rsi, %rax364; CHECK-NEXT: xorl %edx, %edx365; CHECK-NEXT: divq {{[0-9]+}}(%rsp)366; CHECK-NEXT: movq %rdx, %xmm1367; CHECK-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]368; CHECK-NEXT: movq %r8, %rax369; CHECK-NEXT: xorl %edx, %edx370; CHECK-NEXT: divq {{[0-9]+}}(%rsp)371; CHECK-NEXT: movq %rdx, %xmm0372; CHECK-NEXT: movq %rcx, %rax373; CHECK-NEXT: xorl %edx, %edx374; CHECK-NEXT: divq {{[0-9]+}}(%rsp)375; CHECK-NEXT: movq %rdx, %xmm2376; CHECK-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0]377; CHECK-NEXT: movq %r9, %rax378; CHECK-NEXT: xorl %edx, %edx379; CHECK-NEXT: divq {{[0-9]+}}(%rsp)380; CHECK-NEXT: movq %rdx, 32(%rdi)381; CHECK-NEXT: movdqa %xmm2, 16(%rdi)382; CHECK-NEXT: movdqa %xmm1, (%rdi)383; CHECK-NEXT: movq %rdi, %rax384; CHECK-NEXT: retq385 %rem.r = urem <5 x i64> %num, %rem386 ret <5 x i64> %rem.r387}388 389define void @test_int_div(ptr %dest, ptr %old, i32 %n) {390; CHECK-LABEL: test_int_div:391; CHECK: # %bb.0: # %entry392; CHECK-NEXT: testl %edx, %edx393; CHECK-NEXT: jle .LBB12_3394; CHECK-NEXT: # %bb.1: # %bb.nph395; CHECK-NEXT: movl %edx, %ecx396; CHECK-NEXT: xorl %r10d, %r10d397; CHECK-NEXT: .p2align 4398; CHECK-NEXT: .LBB12_2: # %for.body399; CHECK-NEXT: # =>This Inner Loop Header: Depth=1400; CHECK-NEXT: movl (%rdi,%r10), %r8d401; CHECK-NEXT: movl 4(%rdi,%r10), %eax402; CHECK-NEXT: cltd403; CHECK-NEXT: idivl 4(%rsi,%r10)404; CHECK-NEXT: movl %eax, %r9d405; CHECK-NEXT: movl %r8d, %eax406; CHECK-NEXT: cltd407; CHECK-NEXT: idivl (%rsi,%r10)408; CHECK-NEXT: movd %eax, %xmm0409; CHECK-NEXT: pinsrd $1, %r9d, %xmm0410; CHECK-NEXT: movl 8(%rdi,%r10), %eax411; CHECK-NEXT: cltd412; CHECK-NEXT: idivl 8(%rsi,%r10)413; CHECK-NEXT: movl %eax, 8(%rdi,%r10)414; CHECK-NEXT: movq %xmm0, (%rdi,%r10)415; CHECK-NEXT: addq $16, %r10416; CHECK-NEXT: decl %ecx417; CHECK-NEXT: jne .LBB12_2418; CHECK-NEXT: .LBB12_3: # %for.end419; CHECK-NEXT: retq420entry:421 %cmp13 = icmp sgt i32 %n, 0422 br i1 %cmp13, label %bb.nph, label %for.end423 424bb.nph:425 br label %for.body426 427for.body:428 %i.014 = phi i32 [ 0, %bb.nph ], [ %inc, %for.body ]429 %arrayidx11 = getelementptr <3 x i32>, ptr %dest, i32 %i.014430 %tmp4 = load <3 x i32>, ptr %arrayidx11 ; <<3 x i32>> [#uses=1]431 %arrayidx7 = getelementptr inbounds <3 x i32>, ptr %old, i32 %i.014432 %tmp8 = load <3 x i32>, ptr %arrayidx7 ; <<3 x i32>> [#uses=1]433 %div = sdiv <3 x i32> %tmp4, %tmp8434 store <3 x i32> %div, ptr %arrayidx11435 %inc = add nsw i32 %i.014, 1436 %exitcond = icmp eq i32 %inc, %n437 br i1 %exitcond, label %for.end, label %for.body438 439for.end: ; preds = %for.body, %entry440 ret void441}442