1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse,+sse2 | FileCheck %s --check-prefix=X86 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse,+sse2 | FileCheck %s --check-prefix=X64 4 5; If the target does not have a single div/rem operation, 6; -div-rem-pairs pass will decompose the remainder calculation as: 7; X % Y --> X - ((X / Y) * Y) 8; But if the target does have a single div/rem operation, 9; the opposite transform is likely beneficial. 10 11define i8 @scalar_i8(i8 %x, i8 %y, ptr %divdst) nounwind { 12; X86-LABEL: scalar_i8: 13; X86: # %bb.0: 14; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 15; X86-NEXT: movb {{[0-9]+}}(%esp), %ch 16; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 17; X86-NEXT: movzbl %cl, %eax 18; X86-NEXT: divb %ch 19; X86-NEXT: movb %al, (%edx) 20; X86-NEXT: mulb %ch 21; X86-NEXT: subb %al, %cl 22; X86-NEXT: movl %ecx, %eax 23; X86-NEXT: retl 24; 25; X64-LABEL: scalar_i8: 26; X64: # %bb.0: 27; X64-NEXT: movzbl %dil, %ecx 28; X64-NEXT: movl %ecx, %eax 29; X64-NEXT: divb %sil 30; X64-NEXT: movb %al, (%rdx) 31; X64-NEXT: mulb %sil 32; X64-NEXT: subb %al, %cl 33; X64-NEXT: movl %ecx, %eax 34; X64-NEXT: retq 35 %div = udiv i8 %x, %y 36 store i8 %div, ptr %divdst, align 4 37 %t1 = mul i8 %div, %y 38 %t2 = sub i8 %x, %t1 39 ret i8 %t2 40} 41 42define i16 @scalar_i16(i16 %x, i16 %y, ptr %divdst) nounwind { 43; X86-LABEL: scalar_i16: 44; X86: # %bb.0: 45; X86-NEXT: pushl %edi 46; X86-NEXT: pushl %esi 47; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 48; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 49; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 50; X86-NEXT: movl %ecx, %eax 51; X86-NEXT: xorl %edx, %edx 52; X86-NEXT: divw %si 53; X86-NEXT: # kill: def $ax killed $ax def $eax 54; X86-NEXT: movw %ax, (%edi) 55; X86-NEXT: imull %eax, %esi 56; X86-NEXT: subl %esi, %ecx 57; X86-NEXT: movl %ecx, %eax 58; X86-NEXT: popl %esi 59; X86-NEXT: popl %edi 60; X86-NEXT: retl 61; 62; X64-LABEL: scalar_i16: 63; X64: # %bb.0: 64; X64-NEXT: movq %rdx, %rcx 65; X64-NEXT: movl %edi, %eax 66; X64-NEXT: xorl %edx, %edx 67; X64-NEXT: divw %si 68; X64-NEXT: # kill: def $ax killed $ax def $eax 69; X64-NEXT: movw %ax, (%rcx) 70; X64-NEXT: imull %eax, %esi 71; X64-NEXT: subl %esi, %edi 72; X64-NEXT: movl %edi, %eax 73; X64-NEXT: retq 74 %div = udiv i16 %x, %y 75 store i16 %div, ptr %divdst, align 4 76 %t1 = mul i16 %div, %y 77 %t2 = sub i16 %x, %t1 78 ret i16 %t2 79} 80 81define i32 @scalar_i32(i32 %x, i32 %y, ptr %divdst) nounwind { 82; X86-LABEL: scalar_i32: 83; X86: # %bb.0: 84; X86-NEXT: pushl %edi 85; X86-NEXT: pushl %esi 86; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 87; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 88; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 89; X86-NEXT: movl %ecx, %eax 90; X86-NEXT: xorl %edx, %edx 91; X86-NEXT: divl %edi 92; X86-NEXT: movl %eax, (%esi) 93; X86-NEXT: imull %edi, %eax 94; X86-NEXT: subl %eax, %ecx 95; X86-NEXT: movl %ecx, %eax 96; X86-NEXT: popl %esi 97; X86-NEXT: popl %edi 98; X86-NEXT: retl 99; 100; X64-LABEL: scalar_i32: 101; X64: # %bb.0: 102; X64-NEXT: movq %rdx, %rcx 103; X64-NEXT: movl %edi, %eax 104; X64-NEXT: xorl %edx, %edx 105; X64-NEXT: divl %esi 106; X64-NEXT: movl %eax, (%rcx) 107; X64-NEXT: imull %esi, %eax 108; X64-NEXT: subl %eax, %edi 109; X64-NEXT: movl %edi, %eax 110; X64-NEXT: retq 111 %div = udiv i32 %x, %y 112 store i32 %div, ptr %divdst, align 4 113 %t1 = mul i32 %div, %y 114 %t2 = sub i32 %x, %t1 115 ret i32 %t2 116} 117 118define i64 @scalar_i64(i64 %x, i64 %y, ptr %divdst) nounwind { 119; X86-LABEL: scalar_i64: 120; X86: # %bb.0: 121; X86-NEXT: pushl %ebp 122; X86-NEXT: pushl %ebx 123; X86-NEXT: pushl %edi 124; X86-NEXT: pushl %esi 125; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 126; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 127; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 128; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp 129; X86-NEXT: pushl %ebp 130; X86-NEXT: pushl %ebx 131; X86-NEXT: pushl %edi 132; X86-NEXT: pushl %esi 133; X86-NEXT: calll __udivdi3 134; X86-NEXT: addl $16, %esp 135; X86-NEXT: movl %edx, %ecx 136; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 137; X86-NEXT: movl %ecx, 4(%edx) 138; X86-NEXT: movl %eax, (%edx) 139; X86-NEXT: imull %eax, %ebp 140; X86-NEXT: mull %ebx 141; X86-NEXT: addl %ebp, %edx 142; X86-NEXT: imull %ebx, %ecx 143; X86-NEXT: addl %edx, %ecx 144; X86-NEXT: subl %eax, %esi 145; X86-NEXT: sbbl %ecx, %edi 146; X86-NEXT: movl %esi, %eax 147; X86-NEXT: movl %edi, %edx 148; X86-NEXT: popl %esi 149; X86-NEXT: popl %edi 150; X86-NEXT: popl %ebx 151; X86-NEXT: popl %ebp 152; X86-NEXT: retl 153; 154; X64-LABEL: scalar_i64: 155; X64: # %bb.0: 156; X64-NEXT: movq %rdx, %rcx 157; X64-NEXT: movq %rdi, %rax 158; X64-NEXT: xorl %edx, %edx 159; X64-NEXT: divq %rsi 160; X64-NEXT: movq %rax, (%rcx) 161; X64-NEXT: imulq %rsi, %rax 162; X64-NEXT: subq %rax, %rdi 163; X64-NEXT: movq %rdi, %rax 164; X64-NEXT: retq 165 %div = udiv i64 %x, %y 166 store i64 %div, ptr %divdst, align 4 167 %t1 = mul i64 %div, %y 168 %t2 = sub i64 %x, %t1 169 ret i64 %t2 170} 171 172define i128 @scalar_i128(i128 %x, i128 %y, ptr %divdst) nounwind { 173; X86-LABEL: scalar_i128: 174; X86: # %bb.0: 175; X86-NEXT: pushl %ebp 176; X86-NEXT: movl %esp, %ebp 177; X86-NEXT: pushl %ebx 178; X86-NEXT: pushl %edi 179; X86-NEXT: pushl %esi 180; X86-NEXT: andl $-8, %esp 181; X86-NEXT: subl $40, %esp 182; X86-NEXT: movl 44(%ebp), %edi 183; X86-NEXT: leal {{[0-9]+}}(%esp), %eax 184; X86-NEXT: pushl 40(%ebp) 185; X86-NEXT: pushl 36(%ebp) 186; X86-NEXT: pushl 32(%ebp) 187; X86-NEXT: pushl 28(%ebp) 188; X86-NEXT: pushl 24(%ebp) 189; X86-NEXT: pushl 20(%ebp) 190; X86-NEXT: pushl 16(%ebp) 191; X86-NEXT: pushl 12(%ebp) 192; X86-NEXT: pushl %eax 193; X86-NEXT: calll __udivti3 194; X86-NEXT: addl $32, %esp 195; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 196; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 197; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 198; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 199; X86-NEXT: movl %edi, %edx 200; X86-NEXT: movl %ecx, 12(%edi) 201; X86-NEXT: movl %esi, 8(%edi) 202; X86-NEXT: movl %eax, 4(%edi) 203; X86-NEXT: movl %eax, %edi 204; X86-NEXT: movl %ebx, (%edx) 205; X86-NEXT: movl 28(%ebp), %eax 206; X86-NEXT: imull %eax, %ecx 207; X86-NEXT: mull %esi 208; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill 209; X86-NEXT: addl %ecx, %edx 210; X86-NEXT: imull 32(%ebp), %esi 211; X86-NEXT: addl %edx, %esi 212; X86-NEXT: movl 36(%ebp), %eax 213; X86-NEXT: movl %eax, %ecx 214; X86-NEXT: imull %edi, %ecx 215; X86-NEXT: mull %ebx 216; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill 217; X86-NEXT: addl %ecx, %edx 218; X86-NEXT: movl 40(%ebp), %eax 219; X86-NEXT: imull %ebx, %eax 220; X86-NEXT: addl %edx, %eax 221; X86-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload 222; X86-NEXT: addl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill 223; X86-NEXT: adcl %esi, %eax 224; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill 225; X86-NEXT: movl %ebx, %eax 226; X86-NEXT: movl 28(%ebp), %ecx 227; X86-NEXT: mull %ecx 228; X86-NEXT: movl %edx, (%esp) # 4-byte Spill 229; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill 230; X86-NEXT: movl %edi, %eax 231; X86-NEXT: mull %ecx 232; X86-NEXT: movl %edx, %ecx 233; X86-NEXT: movl %eax, %esi 234; X86-NEXT: addl (%esp), %esi # 4-byte Folded Reload 235; X86-NEXT: adcl $0, %ecx 236; X86-NEXT: movl %ebx, %eax 237; X86-NEXT: mull 32(%ebp) 238; X86-NEXT: movl %edx, %ebx 239; X86-NEXT: addl %esi, %eax 240; X86-NEXT: movl %eax, (%esp) # 4-byte Spill 241; X86-NEXT: adcl %ecx, %ebx 242; X86-NEXT: setb %cl 243; X86-NEXT: movl %edi, %eax 244; X86-NEXT: mull 32(%ebp) 245; X86-NEXT: addl %ebx, %eax 246; X86-NEXT: movzbl %cl, %ecx 247; X86-NEXT: adcl %ecx, %edx 248; X86-NEXT: addl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Folded Reload 249; X86-NEXT: adcl {{[-0-9]+}}(%e{{[sb]}}p), %edx # 4-byte Folded Reload 250; X86-NEXT: movl 12(%ebp), %ecx 251; X86-NEXT: subl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Folded Reload 252; X86-NEXT: movl 16(%ebp), %esi 253; X86-NEXT: sbbl (%esp), %esi # 4-byte Folded Reload 254; X86-NEXT: movl 20(%ebp), %edi 255; X86-NEXT: sbbl %eax, %edi 256; X86-NEXT: movl 24(%ebp), %ebx 257; X86-NEXT: sbbl %edx, %ebx 258; X86-NEXT: movl 8(%ebp), %eax 259; X86-NEXT: movl %ecx, (%eax) 260; X86-NEXT: movl %esi, 4(%eax) 261; X86-NEXT: movl %edi, 8(%eax) 262; X86-NEXT: movl %ebx, 12(%eax) 263; X86-NEXT: leal -12(%ebp), %esp 264; X86-NEXT: popl %esi 265; X86-NEXT: popl %edi 266; X86-NEXT: popl %ebx 267; X86-NEXT: popl %ebp 268; X86-NEXT: retl $4 269; 270; X64-LABEL: scalar_i128: 271; X64: # %bb.0: 272; X64-NEXT: pushq %r15 273; X64-NEXT: pushq %r14 274; X64-NEXT: pushq %r13 275; X64-NEXT: pushq %r12 276; X64-NEXT: pushq %rbx 277; X64-NEXT: movq %r8, %r14 278; X64-NEXT: movq %rcx, %rbx 279; X64-NEXT: movq %rdx, %r15 280; X64-NEXT: movq %rsi, %r12 281; X64-NEXT: movq %rdi, %r13 282; X64-NEXT: callq __udivti3@PLT 283; X64-NEXT: movq %rdx, %rcx 284; X64-NEXT: movq %rdx, 8(%r14) 285; X64-NEXT: movq %rax, (%r14) 286; X64-NEXT: imulq %rax, %rbx 287; X64-NEXT: mulq %r15 288; X64-NEXT: addq %rbx, %rdx 289; X64-NEXT: imulq %r15, %rcx 290; X64-NEXT: addq %rdx, %rcx 291; X64-NEXT: subq %rax, %r13 292; X64-NEXT: sbbq %rcx, %r12 293; X64-NEXT: movq %r13, %rax 294; X64-NEXT: movq %r12, %rdx 295; X64-NEXT: popq %rbx 296; X64-NEXT: popq %r12 297; X64-NEXT: popq %r13 298; X64-NEXT: popq %r14 299; X64-NEXT: popq %r15 300; X64-NEXT: retq 301 %div = udiv i128 %x, %y 302 store i128 %div, ptr %divdst, align 4 303 %t1 = mul i128 %div, %y 304 %t2 = sub i128 %x, %t1 305 ret i128 %t2 306} 307 308define <16 x i8> @vector_i128_i8(<16 x i8> %x, <16 x i8> %y, ptr %divdst) nounwind { 309; X86-LABEL: vector_i128_i8: 310; X86: # %bb.0: 311; X86-NEXT: pushl %ebp 312; X86-NEXT: movl %esp, %ebp 313; X86-NEXT: pushl %ebx 314; X86-NEXT: pushl %edi 315; X86-NEXT: pushl %esi 316; X86-NEXT: andl $-16, %esp 317; X86-NEXT: subl $48, %esp 318; X86-NEXT: movdqa %xmm0, (%esp) 319; X86-NEXT: movdqa %xmm1, {{[0-9]+}}(%esp) 320; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 321; X86-NEXT: divb {{[0-9]+}}(%esp) 322; X86-NEXT: movzbl %al, %eax 323; X86-NEXT: movd %eax, %xmm2 324; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 325; X86-NEXT: divb {{[0-9]+}}(%esp) 326; X86-NEXT: movzbl %al, %eax 327; X86-NEXT: movd %eax, %xmm3 328; X86-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3],xmm3[4],xmm2[4],xmm3[5],xmm2[5],xmm3[6],xmm2[6],xmm3[7],xmm2[7] 329; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 330; X86-NEXT: divb {{[0-9]+}}(%esp) 331; X86-NEXT: movzbl %al, %eax 332; X86-NEXT: movd %eax, %xmm4 333; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 334; X86-NEXT: divb {{[0-9]+}}(%esp) 335; X86-NEXT: movzbl %al, %eax 336; X86-NEXT: movd %eax, %xmm2 337; X86-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3],xmm2[4],xmm4[4],xmm2[5],xmm4[5],xmm2[6],xmm4[6],xmm2[7],xmm4[7] 338; X86-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1],xmm2[2],xmm3[2],xmm2[3],xmm3[3] 339; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 340; X86-NEXT: divb {{[0-9]+}}(%esp) 341; X86-NEXT: movzbl %al, %eax 342; X86-NEXT: movd %eax, %xmm3 343; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 344; X86-NEXT: divb {{[0-9]+}}(%esp) 345; X86-NEXT: movzbl %al, %eax 346; X86-NEXT: movd %eax, %xmm4 347; X86-NEXT: punpcklbw {{.*#+}} xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[1],xmm4[2],xmm3[2],xmm4[3],xmm3[3],xmm4[4],xmm3[4],xmm4[5],xmm3[5],xmm4[6],xmm3[6],xmm4[7],xmm3[7] 348; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 349; X86-NEXT: divb {{[0-9]+}}(%esp) 350; X86-NEXT: movzbl %al, %eax 351; X86-NEXT: movd %eax, %xmm5 352; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 353; X86-NEXT: divb {{[0-9]+}}(%esp) 354; X86-NEXT: movzbl %al, %eax 355; X86-NEXT: movd %eax, %xmm3 356; X86-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm5[0],xmm3[1],xmm5[1],xmm3[2],xmm5[2],xmm3[3],xmm5[3],xmm3[4],xmm5[4],xmm3[5],xmm5[5],xmm3[6],xmm5[6],xmm3[7],xmm5[7] 357; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 358; X86-NEXT: divb {{[0-9]+}}(%esp) 359; X86-NEXT: movzbl %al, %eax 360; X86-NEXT: movd %eax, %xmm5 361; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 362; X86-NEXT: divb {{[0-9]+}}(%esp) 363; X86-NEXT: movzbl %al, %eax 364; X86-NEXT: movd %eax, %xmm6 365; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 366; X86-NEXT: divb {{[0-9]+}}(%esp) 367; X86-NEXT: movzbl %al, %edx 368; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 369; X86-NEXT: divb {{[0-9]+}}(%esp) 370; X86-NEXT: movzbl %al, %esi 371; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 372; X86-NEXT: divb {{[0-9]+}}(%esp) 373; X86-NEXT: movzbl %al, %edi 374; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 375; X86-NEXT: divb {{[0-9]+}}(%esp) 376; X86-NEXT: movzbl %al, %ebx 377; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 378; X86-NEXT: divb {{[0-9]+}}(%esp) 379; X86-NEXT: movl %eax, %ecx 380; X86-NEXT: movzbl (%esp), %eax 381; X86-NEXT: divb {{[0-9]+}}(%esp) 382; X86-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1],xmm3[2],xmm4[2],xmm3[3],xmm4[3] 383; X86-NEXT: movd %edx, %xmm4 384; X86-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1] 385; X86-NEXT: movd %esi, %xmm7 386; X86-NEXT: punpcklbw {{.*#+}} xmm6 = xmm6[0],xmm5[0],xmm6[1],xmm5[1],xmm6[2],xmm5[2],xmm6[3],xmm5[3],xmm6[4],xmm5[4],xmm6[5],xmm5[5],xmm6[6],xmm5[6],xmm6[7],xmm5[7] 387; X86-NEXT: movd %edi, %xmm2 388; X86-NEXT: punpcklbw {{.*#+}} xmm7 = xmm7[0],xmm4[0],xmm7[1],xmm4[1],xmm7[2],xmm4[2],xmm7[3],xmm4[3],xmm7[4],xmm4[4],xmm7[5],xmm4[5],xmm7[6],xmm4[6],xmm7[7],xmm4[7] 389; X86-NEXT: punpcklwd {{.*#+}} xmm7 = xmm7[0],xmm6[0],xmm7[1],xmm6[1],xmm7[2],xmm6[2],xmm7[3],xmm6[3] 390; X86-NEXT: movd %ebx, %xmm4 391; X86-NEXT: movzbl %cl, %ecx 392; X86-NEXT: movd %ecx, %xmm5 393; X86-NEXT: movl 8(%ebp), %ecx 394; X86-NEXT: punpcklbw {{.*#+}} xmm4 = xmm4[0],xmm2[0],xmm4[1],xmm2[1],xmm4[2],xmm2[2],xmm4[3],xmm2[3],xmm4[4],xmm2[4],xmm4[5],xmm2[5],xmm4[6],xmm2[6],xmm4[7],xmm2[7] 395; X86-NEXT: movzbl %al, %eax 396; X86-NEXT: movd %eax, %xmm2 397; X86-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm5[0],xmm2[1],xmm5[1],xmm2[2],xmm5[2],xmm2[3],xmm5[3],xmm2[4],xmm5[4],xmm2[5],xmm5[5],xmm2[6],xmm5[6],xmm2[7],xmm5[7] 398; X86-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3] 399; X86-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm7[0],xmm2[1],xmm7[1] 400; X86-NEXT: movdqa %xmm2, %xmm4 401; X86-NEXT: punpcklqdq {{.*#+}} xmm4 = xmm4[0],xmm3[0] 402; X86-NEXT: movdqa %xmm4, (%ecx) 403; X86-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 404; X86-NEXT: movdqa %xmm1, %xmm4 405; X86-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] 406; X86-NEXT: pmullw %xmm3, %xmm4 407; X86-NEXT: movdqa {{.*#+}} xmm3 = [255,255,255,255,255,255,255,255] 408; X86-NEXT: pand %xmm3, %xmm4 409; X86-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 410; X86-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 411; X86-NEXT: pmullw %xmm2, %xmm1 412; X86-NEXT: pand %xmm3, %xmm1 413; X86-NEXT: packuswb %xmm4, %xmm1 414; X86-NEXT: psubb %xmm1, %xmm0 415; X86-NEXT: leal -12(%ebp), %esp 416; X86-NEXT: popl %esi 417; X86-NEXT: popl %edi 418; X86-NEXT: popl %ebx 419; X86-NEXT: popl %ebp 420; X86-NEXT: retl 421; 422; X64-LABEL: vector_i128_i8: 423; X64: # %bb.0: 424; X64-NEXT: pushq %rbp 425; X64-NEXT: pushq %r15 426; X64-NEXT: pushq %r14 427; X64-NEXT: pushq %r13 428; X64-NEXT: pushq %r12 429; X64-NEXT: pushq %rbx 430; X64-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill 431; X64-NEXT: movdqa %xmm0, -{{[0-9]+}}(%rsp) 432; X64-NEXT: movdqa %xmm1, -{{[0-9]+}}(%rsp) 433; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 434; X64-NEXT: divb -{{[0-9]+}}(%rsp) 435; X64-NEXT: movzbl %al, %eax 436; X64-NEXT: movd %eax, %xmm2 437; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 438; X64-NEXT: divb -{{[0-9]+}}(%rsp) 439; X64-NEXT: movzbl %al, %r8d 440; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 441; X64-NEXT: divb -{{[0-9]+}}(%rsp) 442; X64-NEXT: movzbl %al, %r9d 443; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 444; X64-NEXT: divb -{{[0-9]+}}(%rsp) 445; X64-NEXT: movzbl %al, %r10d 446; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 447; X64-NEXT: divb -{{[0-9]+}}(%rsp) 448; X64-NEXT: movzbl %al, %r11d 449; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 450; X64-NEXT: divb -{{[0-9]+}}(%rsp) 451; X64-NEXT: movzbl %al, %r14d 452; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 453; X64-NEXT: divb -{{[0-9]+}}(%rsp) 454; X64-NEXT: movzbl %al, %r15d 455; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 456; X64-NEXT: divb -{{[0-9]+}}(%rsp) 457; X64-NEXT: movzbl %al, %r12d 458; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 459; X64-NEXT: divb -{{[0-9]+}}(%rsp) 460; X64-NEXT: movzbl %al, %r13d 461; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 462; X64-NEXT: divb -{{[0-9]+}}(%rsp) 463; X64-NEXT: movzbl %al, %edi 464; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 465; X64-NEXT: divb -{{[0-9]+}}(%rsp) 466; X64-NEXT: movzbl %al, %esi 467; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 468; X64-NEXT: divb -{{[0-9]+}}(%rsp) 469; X64-NEXT: movzbl %al, %ebx 470; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 471; X64-NEXT: divb -{{[0-9]+}}(%rsp) 472; X64-NEXT: movzbl %al, %ebp 473; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 474; X64-NEXT: divb -{{[0-9]+}}(%rsp) 475; X64-NEXT: movzbl %al, %edx 476; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 477; X64-NEXT: divb -{{[0-9]+}}(%rsp) 478; X64-NEXT: movl %eax, %ecx 479; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax 480; X64-NEXT: divb -{{[0-9]+}}(%rsp) 481; X64-NEXT: movd %r8d, %xmm3 482; X64-NEXT: movd %r9d, %xmm4 483; X64-NEXT: movd %r10d, %xmm5 484; X64-NEXT: movd %r11d, %xmm6 485; X64-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3],xmm3[4],xmm2[4],xmm3[5],xmm2[5],xmm3[6],xmm2[6],xmm3[7],xmm2[7] 486; X64-NEXT: movd %r14d, %xmm2 487; X64-NEXT: punpcklbw {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1],xmm5[2],xmm4[2],xmm5[3],xmm4[3],xmm5[4],xmm4[4],xmm5[5],xmm4[5],xmm5[6],xmm4[6],xmm5[7],xmm4[7] 488; X64-NEXT: movd %r15d, %xmm4 489; X64-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm3[0],xmm5[1],xmm3[1],xmm5[2],xmm3[2],xmm5[3],xmm3[3] 490; X64-NEXT: movd %r12d, %xmm3 491; X64-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm6[0],xmm2[1],xmm6[1],xmm2[2],xmm6[2],xmm2[3],xmm6[3],xmm2[4],xmm6[4],xmm2[5],xmm6[5],xmm2[6],xmm6[6],xmm2[7],xmm6[7] 492; X64-NEXT: movd %r13d, %xmm6 493; X64-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1],xmm3[2],xmm4[2],xmm3[3],xmm4[3],xmm3[4],xmm4[4],xmm3[5],xmm4[5],xmm3[6],xmm4[6],xmm3[7],xmm4[7] 494; X64-NEXT: movd %edi, %xmm4 495; X64-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3] 496; X64-NEXT: movd %esi, %xmm2 497; X64-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm5[0],xmm3[1],xmm5[1] 498; X64-NEXT: movd %ebx, %xmm5 499; X64-NEXT: punpcklbw {{.*#+}} xmm4 = xmm4[0],xmm6[0],xmm4[1],xmm6[1],xmm4[2],xmm6[2],xmm4[3],xmm6[3],xmm4[4],xmm6[4],xmm4[5],xmm6[5],xmm4[6],xmm6[6],xmm4[7],xmm6[7] 500; X64-NEXT: movd %ebp, %xmm6 501; X64-NEXT: punpcklbw {{.*#+}} xmm5 = xmm5[0],xmm2[0],xmm5[1],xmm2[1],xmm5[2],xmm2[2],xmm5[3],xmm2[3],xmm5[4],xmm2[4],xmm5[5],xmm2[5],xmm5[6],xmm2[6],xmm5[7],xmm2[7] 502; X64-NEXT: movd %edx, %xmm2 503; X64-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1],xmm5[2],xmm4[2],xmm5[3],xmm4[3] 504; X64-NEXT: movzbl %cl, %ecx 505; X64-NEXT: movd %ecx, %xmm4 506; X64-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm6[0],xmm2[1],xmm6[1],xmm2[2],xmm6[2],xmm2[3],xmm6[3],xmm2[4],xmm6[4],xmm2[5],xmm6[5],xmm2[6],xmm6[6],xmm2[7],xmm6[7] 507; X64-NEXT: movzbl %al, %eax 508; X64-NEXT: movd %eax, %xmm6 509; X64-NEXT: punpcklbw {{.*#+}} xmm6 = xmm6[0],xmm4[0],xmm6[1],xmm4[1],xmm6[2],xmm4[2],xmm6[3],xmm4[3],xmm6[4],xmm4[4],xmm6[5],xmm4[5],xmm6[6],xmm4[6],xmm6[7],xmm4[7] 510; X64-NEXT: punpcklwd {{.*#+}} xmm6 = xmm6[0],xmm2[0],xmm6[1],xmm2[1],xmm6[2],xmm2[2],xmm6[3],xmm2[3] 511; X64-NEXT: punpckldq {{.*#+}} xmm6 = xmm6[0],xmm5[0],xmm6[1],xmm5[1] 512; X64-NEXT: movdqa %xmm6, %xmm2 513; X64-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0] 514; X64-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload 515; X64-NEXT: movdqa %xmm2, (%rax) 516; X64-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 517; X64-NEXT: movdqa %xmm1, %xmm2 518; X64-NEXT: punpckhbw {{.*#+}} xmm2 = xmm2[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15] 519; X64-NEXT: pmullw %xmm3, %xmm2 520; X64-NEXT: movdqa {{.*#+}} xmm3 = [255,255,255,255,255,255,255,255] 521; X64-NEXT: pand %xmm3, %xmm2 522; X64-NEXT: punpcklbw {{.*#+}} xmm6 = xmm6[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 523; X64-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] 524; X64-NEXT: pmullw %xmm6, %xmm1 525; X64-NEXT: pand %xmm3, %xmm1 526; X64-NEXT: packuswb %xmm2, %xmm1 527; X64-NEXT: psubb %xmm1, %xmm0 528; X64-NEXT: popq %rbx 529; X64-NEXT: popq %r12 530; X64-NEXT: popq %r13 531; X64-NEXT: popq %r14 532; X64-NEXT: popq %r15 533; X64-NEXT: popq %rbp 534; X64-NEXT: retq 535 %div = udiv <16 x i8> %x, %y 536 store <16 x i8> %div, ptr %divdst, align 16 537 %t1 = mul <16 x i8> %div, %y 538 %t2 = sub <16 x i8> %x, %t1 539 ret <16 x i8> %t2 540} 541 542define <8 x i16> @vector_i128_i16(<8 x i16> %x, <8 x i16> %y, ptr %divdst) nounwind { 543; X86-LABEL: vector_i128_i16: 544; X86: # %bb.0: 545; X86-NEXT: pushl %esi 546; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 547; X86-NEXT: pextrw $7, %xmm0, %eax 548; X86-NEXT: pextrw $7, %xmm1, %esi 549; X86-NEXT: # kill: def $ax killed $ax killed $eax 550; X86-NEXT: xorl %edx, %edx 551; X86-NEXT: divw %si 552; X86-NEXT: # kill: def $ax killed $ax def $eax 553; X86-NEXT: movd %eax, %xmm2 554; X86-NEXT: pextrw $6, %xmm0, %eax 555; X86-NEXT: pextrw $6, %xmm1, %esi 556; X86-NEXT: # kill: def $ax killed $ax killed $eax 557; X86-NEXT: xorl %edx, %edx 558; X86-NEXT: divw %si 559; X86-NEXT: # kill: def $ax killed $ax def $eax 560; X86-NEXT: movd %eax, %xmm3 561; X86-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3] 562; X86-NEXT: pextrw $5, %xmm0, %eax 563; X86-NEXT: pextrw $5, %xmm1, %esi 564; X86-NEXT: # kill: def $ax killed $ax killed $eax 565; X86-NEXT: xorl %edx, %edx 566; X86-NEXT: divw %si 567; X86-NEXT: # kill: def $ax killed $ax def $eax 568; X86-NEXT: movd %eax, %xmm4 569; X86-NEXT: pextrw $4, %xmm0, %eax 570; X86-NEXT: pextrw $4, %xmm1, %esi 571; X86-NEXT: # kill: def $ax killed $ax killed $eax 572; X86-NEXT: xorl %edx, %edx 573; X86-NEXT: divw %si 574; X86-NEXT: # kill: def $ax killed $ax def $eax 575; X86-NEXT: movd %eax, %xmm2 576; X86-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3] 577; X86-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1] 578; X86-NEXT: pextrw $3, %xmm0, %eax 579; X86-NEXT: pextrw $3, %xmm1, %esi 580; X86-NEXT: # kill: def $ax killed $ax killed $eax 581; X86-NEXT: xorl %edx, %edx 582; X86-NEXT: divw %si 583; X86-NEXT: # kill: def $ax killed $ax def $eax 584; X86-NEXT: movd %eax, %xmm4 585; X86-NEXT: pextrw $2, %xmm0, %eax 586; X86-NEXT: pextrw $2, %xmm1, %esi 587; X86-NEXT: # kill: def $ax killed $ax killed $eax 588; X86-NEXT: xorl %edx, %edx 589; X86-NEXT: divw %si 590; X86-NEXT: # kill: def $ax killed $ax def $eax 591; X86-NEXT: movd %eax, %xmm3 592; X86-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1],xmm3[2],xmm4[2],xmm3[3],xmm4[3] 593; X86-NEXT: pextrw $1, %xmm0, %eax 594; X86-NEXT: pextrw $1, %xmm1, %esi 595; X86-NEXT: # kill: def $ax killed $ax killed $eax 596; X86-NEXT: xorl %edx, %edx 597; X86-NEXT: divw %si 598; X86-NEXT: # kill: def $ax killed $ax def $eax 599; X86-NEXT: movd %eax, %xmm4 600; X86-NEXT: movd %xmm0, %eax 601; X86-NEXT: movd %xmm1, %esi 602; X86-NEXT: # kill: def $ax killed $ax killed $eax 603; X86-NEXT: xorl %edx, %edx 604; X86-NEXT: divw %si 605; X86-NEXT: # kill: def $ax killed $ax def $eax 606; X86-NEXT: movd %eax, %xmm5 607; X86-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1],xmm5[2],xmm4[2],xmm5[3],xmm4[3] 608; X86-NEXT: punpckldq {{.*#+}} xmm5 = xmm5[0],xmm3[0],xmm5[1],xmm3[1] 609; X86-NEXT: punpcklqdq {{.*#+}} xmm5 = xmm5[0],xmm2[0] 610; X86-NEXT: movdqa %xmm5, (%ecx) 611; X86-NEXT: pmullw %xmm1, %xmm5 612; X86-NEXT: psubw %xmm5, %xmm0 613; X86-NEXT: popl %esi 614; X86-NEXT: retl 615; 616; X64-LABEL: vector_i128_i16: 617; X64: # %bb.0: 618; X64-NEXT: pextrw $7, %xmm0, %eax 619; X64-NEXT: pextrw $7, %xmm1, %ecx 620; X64-NEXT: # kill: def $ax killed $ax killed $eax 621; X64-NEXT: xorl %edx, %edx 622; X64-NEXT: divw %cx 623; X64-NEXT: # kill: def $ax killed $ax def $eax 624; X64-NEXT: movd %eax, %xmm2 625; X64-NEXT: pextrw $6, %xmm0, %eax 626; X64-NEXT: pextrw $6, %xmm1, %ecx 627; X64-NEXT: # kill: def $ax killed $ax killed $eax 628; X64-NEXT: xorl %edx, %edx 629; X64-NEXT: divw %cx 630; X64-NEXT: # kill: def $ax killed $ax def $eax 631; X64-NEXT: movd %eax, %xmm3 632; X64-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3] 633; X64-NEXT: pextrw $5, %xmm0, %eax 634; X64-NEXT: pextrw $5, %xmm1, %ecx 635; X64-NEXT: # kill: def $ax killed $ax killed $eax 636; X64-NEXT: xorl %edx, %edx 637; X64-NEXT: divw %cx 638; X64-NEXT: # kill: def $ax killed $ax def $eax 639; X64-NEXT: movd %eax, %xmm4 640; X64-NEXT: pextrw $4, %xmm0, %eax 641; X64-NEXT: pextrw $4, %xmm1, %ecx 642; X64-NEXT: # kill: def $ax killed $ax killed $eax 643; X64-NEXT: xorl %edx, %edx 644; X64-NEXT: divw %cx 645; X64-NEXT: # kill: def $ax killed $ax def $eax 646; X64-NEXT: movd %eax, %xmm2 647; X64-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3] 648; X64-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1] 649; X64-NEXT: pextrw $3, %xmm0, %eax 650; X64-NEXT: pextrw $3, %xmm1, %ecx 651; X64-NEXT: # kill: def $ax killed $ax killed $eax 652; X64-NEXT: xorl %edx, %edx 653; X64-NEXT: divw %cx 654; X64-NEXT: # kill: def $ax killed $ax def $eax 655; X64-NEXT: movd %eax, %xmm3 656; X64-NEXT: pextrw $2, %xmm0, %eax 657; X64-NEXT: pextrw $2, %xmm1, %ecx 658; X64-NEXT: # kill: def $ax killed $ax killed $eax 659; X64-NEXT: xorl %edx, %edx 660; X64-NEXT: divw %cx 661; X64-NEXT: # kill: def $ax killed $ax def $eax 662; X64-NEXT: movd %eax, %xmm4 663; X64-NEXT: punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[1],xmm4[2],xmm3[2],xmm4[3],xmm3[3] 664; X64-NEXT: pextrw $1, %xmm0, %eax 665; X64-NEXT: pextrw $1, %xmm1, %ecx 666; X64-NEXT: # kill: def $ax killed $ax killed $eax 667; X64-NEXT: xorl %edx, %edx 668; X64-NEXT: divw %cx 669; X64-NEXT: # kill: def $ax killed $ax def $eax 670; X64-NEXT: movd %eax, %xmm3 671; X64-NEXT: movd %xmm0, %eax 672; X64-NEXT: movd %xmm1, %ecx 673; X64-NEXT: # kill: def $ax killed $ax killed $eax 674; X64-NEXT: xorl %edx, %edx 675; X64-NEXT: divw %cx 676; X64-NEXT: # kill: def $ax killed $ax def $eax 677; X64-NEXT: movd %eax, %xmm5 678; X64-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm3[0],xmm5[1],xmm3[1],xmm5[2],xmm3[2],xmm5[3],xmm3[3] 679; X64-NEXT: punpckldq {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1] 680; X64-NEXT: punpcklqdq {{.*#+}} xmm5 = xmm5[0],xmm2[0] 681; X64-NEXT: movdqa %xmm5, (%rdi) 682; X64-NEXT: pmullw %xmm1, %xmm5 683; X64-NEXT: psubw %xmm5, %xmm0 684; X64-NEXT: retq 685 %div = udiv <8 x i16> %x, %y 686 store <8 x i16> %div, ptr %divdst, align 16 687 %t1 = mul <8 x i16> %div, %y 688 %t2 = sub <8 x i16> %x, %t1 689 ret <8 x i16> %t2 690} 691 692define <4 x i32> @vector_i128_i32(<4 x i32> %x, <4 x i32> %y, ptr %divdst) nounwind { 693; X86-LABEL: vector_i128_i32: 694; X86: # %bb.0: 695; X86-NEXT: pushl %esi 696; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 697; X86-NEXT: pshufd {{.*#+}} xmm2 = xmm0[3,3,3,3] 698; X86-NEXT: movd %xmm2, %eax 699; X86-NEXT: pshufd {{.*#+}} xmm2 = xmm1[3,3,3,3] 700; X86-NEXT: movd %xmm2, %esi 701; X86-NEXT: xorl %edx, %edx 702; X86-NEXT: divl %esi 703; X86-NEXT: movd %eax, %xmm3 704; X86-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3] 705; X86-NEXT: movd %xmm2, %eax 706; X86-NEXT: pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3] 707; X86-NEXT: movd %xmm2, %esi 708; X86-NEXT: xorl %edx, %edx 709; X86-NEXT: divl %esi 710; X86-NEXT: movd %eax, %xmm2 711; X86-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1] 712; X86-NEXT: movd %xmm0, %eax 713; X86-NEXT: movd %xmm1, %esi 714; X86-NEXT: xorl %edx, %edx 715; X86-NEXT: divl %esi 716; X86-NEXT: movd %eax, %xmm3 717; X86-NEXT: pshufd {{.*#+}} xmm4 = xmm0[1,1,1,1] 718; X86-NEXT: movd %xmm4, %eax 719; X86-NEXT: pshufd {{.*#+}} xmm4 = xmm1[1,1,1,1] 720; X86-NEXT: movd %xmm4, %esi 721; X86-NEXT: xorl %edx, %edx 722; X86-NEXT: divl %esi 723; X86-NEXT: movd %eax, %xmm4 724; X86-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1] 725; X86-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm2[0] 726; X86-NEXT: movdqa %xmm3, (%ecx) 727; X86-NEXT: pshufd {{.*#+}} xmm2 = xmm3[1,1,3,3] 728; X86-NEXT: pmuludq %xmm1, %xmm3 729; X86-NEXT: pshufd {{.*#+}} xmm3 = xmm3[0,2,2,3] 730; X86-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] 731; X86-NEXT: pmuludq %xmm2, %xmm1 732; X86-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] 733; X86-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1] 734; X86-NEXT: psubd %xmm3, %xmm0 735; X86-NEXT: popl %esi 736; X86-NEXT: retl 737; 738; X64-LABEL: vector_i128_i32: 739; X64: # %bb.0: 740; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm0[3,3,3,3] 741; X64-NEXT: movd %xmm2, %eax 742; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm1[3,3,3,3] 743; X64-NEXT: movd %xmm2, %ecx 744; X64-NEXT: xorl %edx, %edx 745; X64-NEXT: divl %ecx 746; X64-NEXT: movd %eax, %xmm2 747; X64-NEXT: pshufd {{.*#+}} xmm3 = xmm0[2,3,2,3] 748; X64-NEXT: movd %xmm3, %eax 749; X64-NEXT: pshufd {{.*#+}} xmm3 = xmm1[2,3,2,3] 750; X64-NEXT: movd %xmm3, %ecx 751; X64-NEXT: xorl %edx, %edx 752; X64-NEXT: divl %ecx 753; X64-NEXT: movd %eax, %xmm3 754; X64-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1] 755; X64-NEXT: movd %xmm0, %eax 756; X64-NEXT: movd %xmm1, %ecx 757; X64-NEXT: xorl %edx, %edx 758; X64-NEXT: divl %ecx 759; X64-NEXT: movd %eax, %xmm2 760; X64-NEXT: pshufd {{.*#+}} xmm4 = xmm0[1,1,1,1] 761; X64-NEXT: movd %xmm4, %eax 762; X64-NEXT: pshufd {{.*#+}} xmm4 = xmm1[1,1,1,1] 763; X64-NEXT: movd %xmm4, %ecx 764; X64-NEXT: xorl %edx, %edx 765; X64-NEXT: divl %ecx 766; X64-NEXT: movd %eax, %xmm4 767; X64-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1] 768; X64-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0] 769; X64-NEXT: movdqa %xmm2, (%rdi) 770; X64-NEXT: pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3] 771; X64-NEXT: pmuludq %xmm1, %xmm2 772; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3] 773; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] 774; X64-NEXT: pmuludq %xmm3, %xmm1 775; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] 776; X64-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1] 777; X64-NEXT: psubd %xmm2, %xmm0 778; X64-NEXT: retq 779 %div = udiv <4 x i32> %x, %y 780 store <4 x i32> %div, ptr %divdst, align 16 781 %t1 = mul <4 x i32> %div, %y 782 %t2 = sub <4 x i32> %x, %t1 783 ret <4 x i32> %t2 784} 785 786define <2 x i64> @vector_i128_i64(<2 x i64> %x, <2 x i64> %y, ptr %divdst) nounwind { 787; X86-LABEL: vector_i128_i64: 788; X86: # %bb.0: 789; X86-NEXT: pushl %esi 790; X86-NEXT: subl $64, %esp 791; X86-NEXT: movdqu %xmm1, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill 792; X86-NEXT: movdqu %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill 793; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 794; X86-NEXT: pshufd {{.*#+}} xmm2 = xmm1[3,3,3,3] 795; X86-NEXT: movd %xmm2, {{[0-9]+}}(%esp) 796; X86-NEXT: pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3] 797; X86-NEXT: movd %xmm2, {{[0-9]+}}(%esp) 798; X86-NEXT: pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3] 799; X86-NEXT: movd %xmm1, {{[0-9]+}}(%esp) 800; X86-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3] 801; X86-NEXT: movd %xmm1, (%esp) 802; X86-NEXT: calll __udivdi3 803; X86-NEXT: movdqu {{[-0-9]+}}(%e{{[sb]}}p), %xmm1 # 16-byte Reload 804; X86-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1] 805; X86-NEXT: movd %xmm0, {{[0-9]+}}(%esp) 806; X86-NEXT: movd %xmm1, {{[0-9]+}}(%esp) 807; X86-NEXT: movdqu {{[-0-9]+}}(%e{{[sb]}}p), %xmm1 # 16-byte Reload 808; X86-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1] 809; X86-NEXT: movd %xmm0, {{[0-9]+}}(%esp) 810; X86-NEXT: movd %xmm1, (%esp) 811; X86-NEXT: movd %edx, %xmm0 812; X86-NEXT: movd %eax, %xmm1 813; X86-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 814; X86-NEXT: movdqu %xmm1, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill 815; X86-NEXT: calll __udivdi3 816; X86-NEXT: movd %edx, %xmm1 817; X86-NEXT: movd %eax, %xmm3 818; X86-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1] 819; X86-NEXT: movdqu {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload 820; X86-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm0[0] 821; X86-NEXT: movdqa %xmm3, (%esi) 822; X86-NEXT: movdqu {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload 823; X86-NEXT: movdqa %xmm0, %xmm1 824; X86-NEXT: psrlq $32, %xmm1 825; X86-NEXT: pmuludq %xmm3, %xmm1 826; X86-NEXT: movdqa %xmm3, %xmm2 827; X86-NEXT: psrlq $32, %xmm2 828; X86-NEXT: pmuludq %xmm0, %xmm2 829; X86-NEXT: paddq %xmm1, %xmm2 830; X86-NEXT: psllq $32, %xmm2 831; X86-NEXT: pmuludq %xmm0, %xmm3 832; X86-NEXT: paddq %xmm2, %xmm3 833; X86-NEXT: movdqu {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload 834; X86-NEXT: psubq %xmm3, %xmm0 835; X86-NEXT: addl $64, %esp 836; X86-NEXT: popl %esi 837; X86-NEXT: retl 838; 839; X64-LABEL: vector_i128_i64: 840; X64: # %bb.0: 841; X64-NEXT: movq %xmm0, %rax 842; X64-NEXT: movq %xmm1, %rcx 843; X64-NEXT: xorl %edx, %edx 844; X64-NEXT: divq %rcx 845; X64-NEXT: movq %rax, %xmm2 846; X64-NEXT: pshufd {{.*#+}} xmm3 = xmm0[2,3,2,3] 847; X64-NEXT: movq %xmm3, %rax 848; X64-NEXT: pshufd {{.*#+}} xmm3 = xmm1[2,3,2,3] 849; X64-NEXT: movq %xmm3, %rcx 850; X64-NEXT: xorl %edx, %edx 851; X64-NEXT: divq %rcx 852; X64-NEXT: movq %rax, %xmm3 853; X64-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0] 854; X64-NEXT: movdqa %xmm2, (%rdi) 855; X64-NEXT: movdqa %xmm1, %xmm3 856; X64-NEXT: psrlq $32, %xmm3 857; X64-NEXT: pmuludq %xmm2, %xmm3 858; X64-NEXT: movdqa %xmm2, %xmm4 859; X64-NEXT: psrlq $32, %xmm4 860; X64-NEXT: pmuludq %xmm1, %xmm4 861; X64-NEXT: paddq %xmm3, %xmm4 862; X64-NEXT: psllq $32, %xmm4 863; X64-NEXT: pmuludq %xmm1, %xmm2 864; X64-NEXT: paddq %xmm4, %xmm2 865; X64-NEXT: psubq %xmm2, %xmm0 866; X64-NEXT: retq 867 %div = udiv <2 x i64> %x, %y 868 store <2 x i64> %div, ptr %divdst, align 16 869 %t1 = mul <2 x i64> %div, %y 870 %t2 = sub <2 x i64> %x, %t1 871 ret <2 x i64> %t2 872} 873 874; Special tests. 875 876define i32 @scalar_i32_commutative(i32 %x, ptr %ysrc, ptr %divdst) nounwind { 877; X86-LABEL: scalar_i32_commutative: 878; X86: # %bb.0: 879; X86-NEXT: pushl %edi 880; X86-NEXT: pushl %esi 881; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 882; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 883; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 884; X86-NEXT: movl (%eax), %edi 885; X86-NEXT: movl %ecx, %eax 886; X86-NEXT: xorl %edx, %edx 887; X86-NEXT: divl %edi 888; X86-NEXT: movl %eax, (%esi) 889; X86-NEXT: imull %eax, %edi 890; X86-NEXT: subl %edi, %ecx 891; X86-NEXT: movl %ecx, %eax 892; X86-NEXT: popl %esi 893; X86-NEXT: popl %edi 894; X86-NEXT: retl 895; 896; X64-LABEL: scalar_i32_commutative: 897; X64: # %bb.0: 898; X64-NEXT: movq %rdx, %rcx 899; X64-NEXT: movl (%rsi), %esi 900; X64-NEXT: movl %edi, %eax 901; X64-NEXT: xorl %edx, %edx 902; X64-NEXT: divl %esi 903; X64-NEXT: movl %eax, (%rcx) 904; X64-NEXT: imull %eax, %esi 905; X64-NEXT: subl %esi, %edi 906; X64-NEXT: movl %edi, %eax 907; X64-NEXT: retq 908 %y = load i32, ptr %ysrc, align 4 909 %div = udiv i32 %x, %y 910 store i32 %div, ptr %divdst, align 4 911 %t1 = mul i32 %y, %div ; commutative 912 %t2 = sub i32 %x, %t1 913 ret i32 %t2 914} 915 916; We do not care about extra uses. 917define i32 @extrause(i32 %x, i32 %y, ptr %divdst, ptr %t1dst) nounwind { 918; X86-LABEL: extrause: 919; X86: # %bb.0: 920; X86-NEXT: pushl %ebx 921; X86-NEXT: pushl %edi 922; X86-NEXT: pushl %esi 923; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 924; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 925; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 926; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 927; X86-NEXT: movl %ecx, %eax 928; X86-NEXT: xorl %edx, %edx 929; X86-NEXT: divl %ebx 930; X86-NEXT: movl %eax, (%edi) 931; X86-NEXT: imull %ebx, %eax 932; X86-NEXT: movl %eax, (%esi) 933; X86-NEXT: subl %eax, %ecx 934; X86-NEXT: movl %ecx, %eax 935; X86-NEXT: popl %esi 936; X86-NEXT: popl %edi 937; X86-NEXT: popl %ebx 938; X86-NEXT: retl 939; 940; X64-LABEL: extrause: 941; X64: # %bb.0: 942; X64-NEXT: movq %rdx, %r8 943; X64-NEXT: movl %edi, %eax 944; X64-NEXT: xorl %edx, %edx 945; X64-NEXT: divl %esi 946; X64-NEXT: movl %eax, (%r8) 947; X64-NEXT: imull %esi, %eax 948; X64-NEXT: movl %eax, (%rcx) 949; X64-NEXT: subl %eax, %edi 950; X64-NEXT: movl %edi, %eax 951; X64-NEXT: retq 952 %div = udiv i32 %x, %y 953 store i32 %div, ptr %divdst, align 4 954 %t1 = mul i32 %div, %y 955 store i32 %t1, ptr %t1dst, align 4 956 %t2 = sub i32 %x, %t1 957 ret i32 %t2 958} 959 960; 'rem' should appear next to 'div'. 961define i32 @multiple_bb(i32 %x, i32 %y, ptr %divdst, i1 zeroext %store_urem, ptr %uremdst) nounwind { 962; X86-LABEL: multiple_bb: 963; X86: # %bb.0: 964; X86-NEXT: pushl %ebx 965; X86-NEXT: pushl %edi 966; X86-NEXT: pushl %esi 967; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 968; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 969; X86-NEXT: movb {{[0-9]+}}(%esp), %bl 970; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 971; X86-NEXT: movl %ecx, %eax 972; X86-NEXT: xorl %edx, %edx 973; X86-NEXT: divl %esi 974; X86-NEXT: movl %eax, (%edi) 975; X86-NEXT: testb %bl, %bl 976; X86-NEXT: je .LBB11_2 977; X86-NEXT: # %bb.1: # %do_urem 978; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 979; X86-NEXT: movl %eax, %edi 980; X86-NEXT: imull %esi, %edi 981; X86-NEXT: subl %edi, %ecx 982; X86-NEXT: movl %ecx, (%edx) 983; X86-NEXT: .LBB11_2: # %end 984; X86-NEXT: popl %esi 985; X86-NEXT: popl %edi 986; X86-NEXT: popl %ebx 987; X86-NEXT: retl 988; 989; X64-LABEL: multiple_bb: 990; X64: # %bb.0: 991; X64-NEXT: movq %rdx, %r9 992; X64-NEXT: movl %edi, %eax 993; X64-NEXT: xorl %edx, %edx 994; X64-NEXT: divl %esi 995; X64-NEXT: movl %eax, (%r9) 996; X64-NEXT: testl %ecx, %ecx 997; X64-NEXT: je .LBB11_2 998; X64-NEXT: # %bb.1: # %do_urem 999; X64-NEXT: movl %eax, %ecx 1000; X64-NEXT: imull %esi, %ecx 1001; X64-NEXT: subl %ecx, %edi 1002; X64-NEXT: movl %edi, (%r8) 1003; X64-NEXT: .LBB11_2: # %end 1004; X64-NEXT: retq 1005 %div = udiv i32 %x, %y 1006 store i32 %div, ptr %divdst, align 4 1007 br i1 %store_urem, label %do_urem, label %end 1008do_urem: 1009 %t1 = mul i32 %div, %y 1010 %t2 = sub i32 %x, %t1 1011 store i32 %t2, ptr %uremdst, align 4 1012 br label %end 1013end: 1014 ret i32 %div 1015} 1016 1017define i32 @negative_different_x(i32 %x0, i32 %x1, i32 %y, ptr %divdst) nounwind { 1018; X86-LABEL: negative_different_x: 1019; X86: # %bb.0: 1020; X86-NEXT: pushl %edi 1021; X86-NEXT: pushl %esi 1022; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1023; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1024; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1025; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 1026; X86-NEXT: xorl %edx, %edx 1027; X86-NEXT: divl %edi 1028; X86-NEXT: movl %eax, (%esi) 1029; X86-NEXT: imull %edi, %eax 1030; X86-NEXT: subl %eax, %ecx 1031; X86-NEXT: movl %ecx, %eax 1032; X86-NEXT: popl %esi 1033; X86-NEXT: popl %edi 1034; X86-NEXT: retl 1035; 1036; X64-LABEL: negative_different_x: 1037; X64: # %bb.0: 1038; X64-NEXT: movl %edx, %r8d 1039; X64-NEXT: movl %edi, %eax 1040; X64-NEXT: xorl %edx, %edx 1041; X64-NEXT: divl %r8d 1042; X64-NEXT: movl %eax, (%rcx) 1043; X64-NEXT: imull %r8d, %eax 1044; X64-NEXT: subl %eax, %esi 1045; X64-NEXT: movl %esi, %eax 1046; X64-NEXT: retq 1047 %div = udiv i32 %x0, %y ; not %x1 1048 store i32 %div, ptr %divdst, align 4 1049 %t1 = mul i32 %div, %y 1050 %t2 = sub i32 %x1, %t1 ; not %x0 1051 ret i32 %t2 1052} 1053 1054define i32 @negative_different_y(i32 %x0, i32 %x1, i32 %y, i32 %z, ptr %divdst) nounwind { 1055; X86-LABEL: negative_different_y: 1056; X86: # %bb.0: 1057; X86-NEXT: pushl %esi 1058; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1059; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1060; X86-NEXT: movl %ecx, %eax 1061; X86-NEXT: xorl %edx, %edx 1062; X86-NEXT: divl {{[0-9]+}}(%esp) 1063; X86-NEXT: movl %eax, (%esi) 1064; X86-NEXT: imull {{[0-9]+}}(%esp), %eax 1065; X86-NEXT: subl %eax, %ecx 1066; X86-NEXT: movl %ecx, %eax 1067; X86-NEXT: popl %esi 1068; X86-NEXT: retl 1069; 1070; X64-LABEL: negative_different_y: 1071; X64: # %bb.0: 1072; X64-NEXT: movl %edx, %edi 1073; X64-NEXT: movl %esi, %eax 1074; X64-NEXT: xorl %edx, %edx 1075; X64-NEXT: divl %ecx 1076; X64-NEXT: movl %eax, (%r8) 1077; X64-NEXT: imull %eax, %edi 1078; X64-NEXT: subl %edi, %esi 1079; X64-NEXT: movl %esi, %eax 1080; X64-NEXT: retq 1081 %div = udiv i32 %x1, %z ; not %x0 1082 store i32 %div, ptr %divdst, align 4 1083 %t1 = mul i32 %div, %y 1084 %t2 = sub i32 %x1, %t1 1085 ret i32 %t2 1086} 1087 1088define i32 @negative_inverted_division(i32 %x0, i32 %x1, i32 %y, ptr %divdst) nounwind { 1089; X86-LABEL: negative_inverted_division: 1090; X86: # %bb.0: 1091; X86-NEXT: pushl %esi 1092; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1093; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1094; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1095; X86-NEXT: xorl %edx, %edx 1096; X86-NEXT: divl %ecx 1097; X86-NEXT: movl %eax, (%esi) 1098; X86-NEXT: imull %ecx, %eax 1099; X86-NEXT: subl %eax, %ecx 1100; X86-NEXT: movl %ecx, %eax 1101; X86-NEXT: popl %esi 1102; X86-NEXT: retl 1103; 1104; X64-LABEL: negative_inverted_division: 1105; X64: # %bb.0: 1106; X64-NEXT: movl %edi, %eax 1107; X64-NEXT: xorl %edx, %edx 1108; X64-NEXT: divl %esi 1109; X64-NEXT: movl %eax, (%rcx) 1110; X64-NEXT: imull %esi, %eax 1111; X64-NEXT: subl %eax, %esi 1112; X64-NEXT: movl %esi, %eax 1113; X64-NEXT: retq 1114 %div = udiv i32 %x0, %x1 ; inverted division 1115 store i32 %div, ptr %divdst, align 4 1116 %t1 = mul i32 %div, %x1 1117 %t2 = sub i32 %x1, %t1 1118 ret i32 %t2 1119} 1120