[llvm] [X86] Vectorize non-power-of-two integer division (PR #215076)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 19 02:35:56 PDT 2026


https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/215076

>From b2550935abb875e1cfb5123fd78acdda79fcbd91 Mon Sep 17 00:00:00 2001
From: Patrick Ribbsaeter <patrickswedish at gmail.com>
Date: Thu, 13 Aug 2026 09:12:46 +0200
Subject: [PATCH] [X86] Vectorize non-power-of-two integer division

Preserve vector lowering when constant extracts collectively demand every lane, while retaining scalarization for partial and variable-index extracts.

Add generated X86 regression coverage, including the requested <2 x i8> all-lanes case.
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  22 +-
 llvm/test/CodeGen/X86/masked-sdiv.ll          |  12 +-
 llvm/test/CodeGen/X86/masked-srem.ll          |  60 +++---
 llvm/test/CodeGen/X86/masked-udiv.ll          | 185 +++++-----------
 llvm/test/CodeGen/X86/masked-urem.ll          | 198 ++++++-----------
 llvm/test/CodeGen/X86/scalar_widen_div.ll     | 204 +++++++++---------
 llvm/test/CodeGen/X86/vector-idiv-udiv-256.ll | 114 ++++++++++
 7 files changed, 401 insertions(+), 394 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index eed9416741c17..f0965cbc6aef8 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -50647,10 +50647,24 @@ static SDValue combineIntDivRem(SDNode *N, SelectionDAG &DAG,
   bool IsSigned = Opc == ISD::SDIV || Opc == ISD::SREM;
 
   // If the result is only read back as scalar extracts, scalarization computes
-  // just the demanded lanes.
-  if (all_of(N->users(), [](const SDNode *U) {
-        return U->getOpcode() == ISD::EXTRACT_VECTOR_ELT;
-      }))
+  // just the demanded lanes. Keep the vector operation when every lane is
+  // extracted, which occurs when non-power-of-two vectors are returned.
+  APInt ExtractedElts = APInt::getZero(VT.getVectorNumElements());
+  bool OnlyExtracts = true;
+  for (const SDNode *U : N->users()) {
+    if (U->getOpcode() != ISD::EXTRACT_VECTOR_ELT) {
+      OnlyExtracts = false;
+      break;
+    }
+    auto *Idx = dyn_cast<ConstantSDNode>(U->getOperand(1));
+    if (!Idx)
+      continue;
+    const APInt &IdxVal = Idx->getAPIntValue();
+    if (IdxVal.uge(VT.getVectorNumElements()))
+      continue;
+    ExtractedElts.setBit(IdxVal.getZExtValue());
+  }
+  if (OnlyExtracts && !ExtractedElts.isAllOnes())
     return SDValue();
 
   // Magic multiply lowers constant divisors cheaper than a divide.
diff --git a/llvm/test/CodeGen/X86/masked-sdiv.ll b/llvm/test/CodeGen/X86/masked-sdiv.ll
index d45a824be63ef..3dc2ffb4ef9ff 100644
--- a/llvm/test/CodeGen/X86/masked-sdiv.ll
+++ b/llvm/test/CodeGen/X86/masked-sdiv.ll
@@ -606,8 +606,6 @@ define <3 x i10> @sdiv_v3i10(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m) {
 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
 ; SSE2-NEXT:    movd %edx, %xmm0
 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; SSE2-NEXT:    pslld $22, %xmm1
-; SSE2-NEXT:    psrad $22, %xmm1
 ; SSE2-NEXT:    movd %r8d, %xmm0
 ; SSE2-NEXT:    movd %ecx, %xmm2
 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1]
@@ -616,6 +614,8 @@ define <3 x i10> @sdiv_v3i10(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m) {
 ; SSE2-NEXT:    pslld $22, %xmm2
 ; SSE2-NEXT:    psrad $22, %xmm2
 ; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm0
+; SSE2-NEXT:    pslld $22, %xmm1
+; SSE2-NEXT:    psrad $22, %xmm1
 ; SSE2-NEXT:    cvtdq2ps %xmm1, %xmm1
 ; SSE2-NEXT:    divps %xmm0, %xmm1
 ; SSE2-NEXT:    cvttps2dq %xmm1, %xmm0
@@ -632,14 +632,14 @@ define <3 x i10> @sdiv_v3i10(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m) {
 ; SSE42-NEXT:    movd %edi, %xmm0
 ; SSE42-NEXT:    pinsrd $1, %esi, %xmm0
 ; SSE42-NEXT:    pinsrd $2, %edx, %xmm0
-; SSE42-NEXT:    pslld $22, %xmm0
-; SSE42-NEXT:    psrad $22, %xmm0
 ; SSE42-NEXT:    movd %ecx, %xmm1
 ; SSE42-NEXT:    pinsrd $1, %r8d, %xmm1
 ; SSE42-NEXT:    pinsrd $2, %r9d, %xmm1
 ; SSE42-NEXT:    pslld $22, %xmm1
 ; SSE42-NEXT:    psrad $22, %xmm1
 ; SSE42-NEXT:    cvtdq2ps %xmm1, %xmm1
+; SSE42-NEXT:    pslld $22, %xmm0
+; SSE42-NEXT:    psrad $22, %xmm0
 ; SSE42-NEXT:    cvtdq2ps %xmm0, %xmm0
 ; SSE42-NEXT:    divps %xmm1, %xmm0
 ; SSE42-NEXT:    cvttps2dq %xmm0, %xmm0
@@ -656,14 +656,14 @@ define <3 x i10> @sdiv_v3i10(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m) {
 ; AVX-NEXT:    vmovd %edi, %xmm0
 ; AVX-NEXT:    vpinsrd $1, %esi, %xmm0, %xmm0
 ; AVX-NEXT:    vpinsrd $2, %edx, %xmm0, %xmm0
-; AVX-NEXT:    vpslld $22, %xmm0, %xmm0
 ; AVX-NEXT:    vmovd %ecx, %xmm1
 ; AVX-NEXT:    vpinsrd $1, %r8d, %xmm1, %xmm1
 ; AVX-NEXT:    vpinsrd $2, %r9d, %xmm1, %xmm1
-; AVX-NEXT:    vpsrad $22, %xmm0, %xmm0
 ; AVX-NEXT:    vpslld $22, %xmm1, %xmm1
 ; AVX-NEXT:    vpsrad $22, %xmm1, %xmm1
 ; AVX-NEXT:    vcvtdq2ps %xmm1, %xmm1
+; AVX-NEXT:    vpslld $22, %xmm0, %xmm0
+; AVX-NEXT:    vpsrad $22, %xmm0, %xmm0
 ; AVX-NEXT:    vcvtdq2ps %xmm0, %xmm0
 ; AVX-NEXT:    vdivps %xmm1, %xmm0, %xmm0
 ; AVX-NEXT:    vcvttps2dq %xmm0, %xmm0
diff --git a/llvm/test/CodeGen/X86/masked-srem.ll b/llvm/test/CodeGen/X86/masked-srem.ll
index 4a301c6260403..3318495303aa7 100644
--- a/llvm/test/CodeGen/X86/masked-srem.ll
+++ b/llvm/test/CodeGen/X86/masked-srem.ll
@@ -661,27 +661,29 @@ define <3 x i10> @srem_v3i10(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m) {
 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
 ; SSE2-NEXT:    movd %edx, %xmm1
 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
-; SSE2-NEXT:    pslld $22, %xmm0
-; SSE2-NEXT:    psrad $22, %xmm0
 ; SSE2-NEXT:    movd %r8d, %xmm1
 ; SSE2-NEXT:    movd %ecx, %xmm2
 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
-; SSE2-NEXT:    movd %r9d, %xmm1
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
-; SSE2-NEXT:    pslld $22, %xmm2
-; SSE2-NEXT:    psrad $22, %xmm2
-; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm1
-; SSE2-NEXT:    cvtdq2ps %xmm0, %xmm3
-; SSE2-NEXT:    divps %xmm1, %xmm3
-; SSE2-NEXT:    cvttps2dq %xmm3, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[1,1,3,3]
-; SSE2-NEXT:    pmuludq %xmm2, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,1,1]
+; SSE2-NEXT:    movd %r9d, %xmm3
+; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
+; SSE2-NEXT:    movdqa %xmm2, %xmm3
+; SSE2-NEXT:    pslld $22, %xmm3
+; SSE2-NEXT:    psrad $22, %xmm3
+; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; SSE2-NEXT:    movdqa %xmm0, %xmm4
+; SSE2-NEXT:    pslld $22, %xmm4
+; SSE2-NEXT:    psrad $22, %xmm4
+; SSE2-NEXT:    cvtdq2ps %xmm4, %xmm4
+; SSE2-NEXT:    divps %xmm3, %xmm4
+; SSE2-NEXT:    cvttps2dq %xmm4, %xmm3
 ; SSE2-NEXT:    pmuludq %xmm3, %xmm2
 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
-; SSE2-NEXT:    psubd %xmm1, %xmm0
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,0,0,0]
+; SSE2-NEXT:    pmuludq %xmm3, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
+; SSE2-NEXT:    psubd %xmm2, %xmm0
 ; SSE2-NEXT:    pextrw $2, %xmm0, %edx
 ; SSE2-NEXT:    pextrw $4, %xmm0, %ecx
 ; SSE2-NEXT:    movd %xmm0, %eax
@@ -695,15 +697,17 @@ define <3 x i10> @srem_v3i10(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m) {
 ; SSE42-NEXT:    movd %edi, %xmm0
 ; SSE42-NEXT:    pinsrd $1, %esi, %xmm0
 ; SSE42-NEXT:    pinsrd $2, %edx, %xmm0
-; SSE42-NEXT:    pslld $22, %xmm0
-; SSE42-NEXT:    psrad $22, %xmm0
 ; SSE42-NEXT:    movd %ecx, %xmm1
 ; SSE42-NEXT:    pinsrd $1, %r8d, %xmm1
 ; SSE42-NEXT:    pinsrd $2, %r9d, %xmm1
-; SSE42-NEXT:    pslld $22, %xmm1
-; SSE42-NEXT:    psrad $22, %xmm1
-; SSE42-NEXT:    cvtdq2ps %xmm1, %xmm2
-; SSE42-NEXT:    cvtdq2ps %xmm0, %xmm3
+; SSE42-NEXT:    movdqa %xmm1, %xmm2
+; SSE42-NEXT:    pslld $22, %xmm2
+; SSE42-NEXT:    psrad $22, %xmm2
+; SSE42-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE42-NEXT:    movdqa %xmm0, %xmm3
+; SSE42-NEXT:    pslld $22, %xmm3
+; SSE42-NEXT:    psrad $22, %xmm3
+; SSE42-NEXT:    cvtdq2ps %xmm3, %xmm3
 ; SSE42-NEXT:    divps %xmm2, %xmm3
 ; SSE42-NEXT:    cvttps2dq %xmm3, %xmm2
 ; SSE42-NEXT:    pmulld %xmm1, %xmm2
@@ -721,15 +725,15 @@ define <3 x i10> @srem_v3i10(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m) {
 ; AVX-NEXT:    vmovd %edi, %xmm0
 ; AVX-NEXT:    vpinsrd $1, %esi, %xmm0, %xmm0
 ; AVX-NEXT:    vpinsrd $2, %edx, %xmm0, %xmm0
-; AVX-NEXT:    vpslld $22, %xmm0, %xmm0
-; AVX-NEXT:    vpsrad $22, %xmm0, %xmm0
 ; AVX-NEXT:    vmovd %ecx, %xmm1
 ; AVX-NEXT:    vpinsrd $1, %r8d, %xmm1, %xmm1
 ; AVX-NEXT:    vpinsrd $2, %r9d, %xmm1, %xmm1
-; AVX-NEXT:    vpslld $22, %xmm1, %xmm1
-; AVX-NEXT:    vpsrad $22, %xmm1, %xmm1
-; AVX-NEXT:    vcvtdq2ps %xmm1, %xmm2
-; AVX-NEXT:    vcvtdq2ps %xmm0, %xmm3
+; AVX-NEXT:    vpslld $22, %xmm1, %xmm2
+; AVX-NEXT:    vpsrad $22, %xmm2, %xmm2
+; AVX-NEXT:    vcvtdq2ps %xmm2, %xmm2
+; AVX-NEXT:    vpslld $22, %xmm0, %xmm3
+; AVX-NEXT:    vpsrad $22, %xmm3, %xmm3
+; AVX-NEXT:    vcvtdq2ps %xmm3, %xmm3
 ; AVX-NEXT:    vdivps %xmm2, %xmm3, %xmm2
 ; AVX-NEXT:    vcvttps2dq %xmm2, %xmm2
 ; AVX-NEXT:    vpmulld %xmm1, %xmm2, %xmm1
diff --git a/llvm/test/CodeGen/X86/masked-udiv.ll b/llvm/test/CodeGen/X86/masked-udiv.ll
index c3dfe74655ed7..d18a721c71930 100644
--- a/llvm/test/CodeGen/X86/masked-udiv.ll
+++ b/llvm/test/CodeGen/X86/masked-udiv.ll
@@ -748,147 +748,76 @@ define <2 x i128> @udiv_v2i128(<2 x i128> %x, <2 x i128> %y, <2 x i1> %m) nounwi
 define <3 x i10> @udiv_v3i10(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m) {
 ; SSE2-LABEL: udiv_v3i10:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movd %r8d, %xmm1
-; SSE2-NEXT:    movd %ecx, %xmm0
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE2-NEXT:    movd %r9d, %xmm1
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
-; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
-; SSE2-NEXT:    movd {{.*#+}} xmm2 = mem[0],zero,zero,zero
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
-; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
-; SSE2-NEXT:    pslld $31, %xmm2
-; SSE2-NEXT:    psrad $31, %xmm2
-; SSE2-NEXT:    movd %esi, %xmm3
+; SSE2-NEXT:    movd %esi, %xmm0
 ; SSE2-NEXT:    movd %edi, %xmm1
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
-; SSE2-NEXT:    movd %edx, %xmm3
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0]
-; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [1023,1023,1023,1023]
-; SSE2-NEXT:    pand %xmm3, %xmm1
-; SSE2-NEXT:    pand %xmm3, %xmm0
-; SSE2-NEXT:    pand %xmm2, %xmm0
-; SSE2-NEXT:    paddd %xmm2, %xmm0
-; SSE2-NEXT:    pcmpeqd %xmm2, %xmm2
-; SSE2-NEXT:    psubd %xmm2, %xmm0
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
-; SSE2-NEXT:    movd %xmm2, %ecx
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3]
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    xorl %edx, %edx
-; SSE2-NEXT:    divl %ecx
-; SSE2-NEXT:    movl %eax, %ecx
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,1,1,1]
-; SSE2-NEXT:    movd %xmm2, %esi
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[1,1,1,1]
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    xorl %edx, %edx
-; SSE2-NEXT:    divl %esi
-; SSE2-NEXT:    movl %eax, %esi
-; SSE2-NEXT:    movd %xmm0, %edi
-; SSE2-NEXT:    movd %xmm1, %eax
-; SSE2-NEXT:    xorl %edx, %edx
-; SSE2-NEXT:    divl %edi
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
+; SSE2-NEXT:    movd %edx, %xmm0
+; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
+; SSE2-NEXT:    movd %r8d, %xmm0
+; SSE2-NEXT:    movd %ecx, %xmm2
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1]
+; SSE2-NEXT:    movd %r9d, %xmm0
+; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0]
+; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [1023,1023,1023,1023]
+; SSE2-NEXT:    pand %xmm0, %xmm2
+; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE2-NEXT:    pand %xmm0, %xmm1
+; SSE2-NEXT:    cvtdq2ps %xmm1, %xmm0
+; SSE2-NEXT:    divps %xmm2, %xmm0
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE2-NEXT:    pextrw $2, %xmm0, %edx
+; SSE2-NEXT:    pextrw $4, %xmm0, %ecx
+; SSE2-NEXT:    movd %xmm0, %eax
 ; SSE2-NEXT:    # kill: def $ax killed $ax killed $eax
-; SSE2-NEXT:    movl %esi, %edx
+; SSE2-NEXT:    # kill: def $dx killed $dx killed $edx
 ; SSE2-NEXT:    # kill: def $cx killed $cx killed $ecx
 ; SSE2-NEXT:    retq
 ;
 ; SSE42-LABEL: udiv_v3i10:
 ; SSE42:       # %bb.0:
-; SSE42-NEXT:    movd %edi, %xmm1
-; SSE42-NEXT:    pinsrd $1, %esi, %xmm1
-; SSE42-NEXT:    pinsrd $2, %edx, %xmm1
-; SSE42-NEXT:    movdqa {{.*#+}} xmm0 = [1023,1023,1023,1023]
-; SSE42-NEXT:    movd %ecx, %xmm2
-; SSE42-NEXT:    pinsrd $1, %r8d, %xmm2
-; SSE42-NEXT:    pinsrd $2, %r9d, %xmm2
-; SSE42-NEXT:    pand %xmm0, %xmm1
-; SSE42-NEXT:    pand %xmm0, %xmm2
-; SSE42-NEXT:    movd {{.*#+}} xmm3 = mem[0],zero,zero,zero
-; SSE42-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; SSE42-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
-; SSE42-NEXT:    movd {{.*#+}} xmm3 = mem[0],zero,zero,zero
-; SSE42-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm3[0]
-; SSE42-NEXT:    pslld $31, %xmm0
-; SSE42-NEXT:    movaps {{.*#+}} xmm3 = [1,1,1,1]
-; SSE42-NEXT:    blendvps %xmm0, %xmm2, %xmm3
-; SSE42-NEXT:    extractps $1, %xmm3, %ecx
-; SSE42-NEXT:    pextrd $1, %xmm1, %eax
-; SSE42-NEXT:    xorl %edx, %edx
-; SSE42-NEXT:    divl %ecx
-; SSE42-NEXT:    movl %eax, %ecx
-; SSE42-NEXT:    movd %xmm3, %esi
-; SSE42-NEXT:    movd %xmm1, %eax
-; SSE42-NEXT:    xorl %edx, %edx
-; SSE42-NEXT:    divl %esi
-; SSE42-NEXT:    movl %eax, %esi
-; SSE42-NEXT:    movd %eax, %xmm0
-; SSE42-NEXT:    pinsrd $1, %ecx, %xmm0
-; SSE42-NEXT:    pextrd $2, %xmm3, %ecx
-; SSE42-NEXT:    pextrd $2, %xmm1, %eax
-; SSE42-NEXT:    xorl %edx, %edx
-; SSE42-NEXT:    divl %ecx
+; SSE42-NEXT:    movd %edi, %xmm0
+; SSE42-NEXT:    pinsrd $1, %esi, %xmm0
+; SSE42-NEXT:    pinsrd $2, %edx, %xmm0
+; SSE42-NEXT:    movd %ecx, %xmm1
+; SSE42-NEXT:    pinsrd $1, %r8d, %xmm1
+; SSE42-NEXT:    pinsrd $2, %r9d, %xmm1
+; SSE42-NEXT:    movdqa {{.*#+}} xmm2 = [1023,1023,1023,1023]
+; SSE42-NEXT:    pand %xmm2, %xmm1
+; SSE42-NEXT:    cvtdq2ps %xmm1, %xmm1
+; SSE42-NEXT:    pand %xmm2, %xmm0
+; SSE42-NEXT:    cvtdq2ps %xmm0, %xmm0
+; SSE42-NEXT:    divps %xmm1, %xmm0
+; SSE42-NEXT:    cvttps2dq %xmm0, %xmm0
 ; SSE42-NEXT:    pextrw $2, %xmm0, %edx
-; SSE42-NEXT:    pinsrd $2, %eax, %xmm0
 ; SSE42-NEXT:    pextrw $4, %xmm0, %ecx
-; SSE42-NEXT:    movl %esi, %eax
+; SSE42-NEXT:    movd %xmm0, %eax
+; SSE42-NEXT:    # kill: def $ax killed $ax killed $eax
 ; SSE42-NEXT:    # kill: def $dx killed $dx killed $edx
 ; SSE42-NEXT:    # kill: def $cx killed $cx killed $ecx
 ; SSE42-NEXT:    retq
 ;
-; AVX2-LABEL: udiv_v3i10:
-; AVX2:       # %bb.0:
-; AVX2-NEXT:    vmovd %edi, %xmm0
-; AVX2-NEXT:    vpinsrd $1, %esi, %xmm0, %xmm0
-; AVX2-NEXT:    vpinsrd $2, %edx, %xmm0, %xmm0
-; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm1 = [1023,1023,1023,1023]
-; AVX2-NEXT:    vpand %xmm1, %xmm0, %xmm0
-; AVX2-NEXT:    vmovd %ecx, %xmm2
-; AVX2-NEXT:    vpinsrd $1, %r8d, %xmm2, %xmm2
-; AVX2-NEXT:    vpinsrd $2, %r9d, %xmm2, %xmm2
-; AVX2-NEXT:    vpand %xmm1, %xmm2, %xmm1
-; AVX2-NEXT:    vcvtdq2ps %xmm1, %xmm1
-; AVX2-NEXT:    vcvtdq2ps %xmm0, %xmm0
-; AVX2-NEXT:    vdivps %xmm1, %xmm0, %xmm0
-; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm1
-; AVX2-NEXT:    vpsrad $31, %xmm1, %xmm2
-; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
-; AVX2-NEXT:    vsubps %xmm3, %xmm0, %xmm0
-; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm0
-; AVX2-NEXT:    vpand %xmm2, %xmm0, %xmm0
-; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX2-NEXT:    vmovd %xmm0, %eax
-; AVX2-NEXT:    vpextrw $2, %xmm0, %edx
-; AVX2-NEXT:    vpextrw $4, %xmm0, %ecx
-; AVX2-NEXT:    # kill: def $ax killed $ax killed $eax
-; AVX2-NEXT:    # kill: def $dx killed $dx killed $edx
-; AVX2-NEXT:    # kill: def $cx killed $cx killed $ecx
-; AVX2-NEXT:    retq
-;
-; AVX512-LABEL: udiv_v3i10:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vmovd %edi, %xmm0
-; AVX512-NEXT:    vpinsrd $1, %esi, %xmm0, %xmm0
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm0, %xmm0
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} xmm1 = [1023,1023,1023,1023]
-; AVX512-NEXT:    vpand %xmm1, %xmm0, %xmm0
-; AVX512-NEXT:    vmovd %ecx, %xmm2
-; AVX512-NEXT:    vpinsrd $1, %r8d, %xmm2, %xmm2
-; AVX512-NEXT:    vpinsrd $2, %r9d, %xmm2, %xmm2
-; AVX512-NEXT:    vpand %xmm1, %xmm2, %xmm1
-; AVX512-NEXT:    vcvtdq2ps %xmm1, %xmm1
-; AVX512-NEXT:    vcvtdq2ps %xmm0, %xmm0
-; AVX512-NEXT:    vdivps %xmm1, %xmm0, %xmm0
-; AVX512-NEXT:    vcvttps2udq %xmm0, %xmm0
-; AVX512-NEXT:    vmovd %xmm0, %eax
-; AVX512-NEXT:    vpextrw $2, %xmm0, %edx
-; AVX512-NEXT:    vpextrw $4, %xmm0, %ecx
-; AVX512-NEXT:    # kill: def $ax killed $ax killed $eax
-; AVX512-NEXT:    # kill: def $dx killed $dx killed $edx
-; AVX512-NEXT:    # kill: def $cx killed $cx killed $ecx
-; AVX512-NEXT:    retq
+; AVX-LABEL: udiv_v3i10:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vmovd %edi, %xmm0
+; AVX-NEXT:    vpinsrd $1, %esi, %xmm0, %xmm0
+; AVX-NEXT:    vpinsrd $2, %edx, %xmm0, %xmm0
+; AVX-NEXT:    vmovd %ecx, %xmm1
+; AVX-NEXT:    vpinsrd $1, %r8d, %xmm1, %xmm1
+; AVX-NEXT:    vpinsrd $2, %r9d, %xmm1, %xmm1
+; AVX-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [1023,1023,1023,1023]
+; AVX-NEXT:    vpand %xmm2, %xmm1, %xmm1
+; AVX-NEXT:    vcvtdq2ps %xmm1, %xmm1
+; AVX-NEXT:    vpand %xmm2, %xmm0, %xmm0
+; AVX-NEXT:    vcvtdq2ps %xmm0, %xmm0
+; AVX-NEXT:    vdivps %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    vcvttps2dq %xmm0, %xmm0
+; AVX-NEXT:    vmovd %xmm0, %eax
+; AVX-NEXT:    vpextrw $2, %xmm0, %edx
+; AVX-NEXT:    vpextrw $4, %xmm0, %ecx
+; AVX-NEXT:    # kill: def $ax killed $ax killed $eax
+; AVX-NEXT:    # kill: def $dx killed $dx killed $edx
+; AVX-NEXT:    # kill: def $cx killed $cx killed $ecx
+; AVX-NEXT:    retq
   %res = call <3 x i10> @llvm.masked.udiv(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m)
   ret <3 x i10> %res
 }
diff --git a/llvm/test/CodeGen/X86/masked-urem.ll b/llvm/test/CodeGen/X86/masked-urem.ll
index 4aede8e3b0365..9944c0bf903d3 100644
--- a/llvm/test/CodeGen/X86/masked-urem.ll
+++ b/llvm/test/CodeGen/X86/masked-urem.ll
@@ -766,152 +766,90 @@ define <2 x i128> @urem_v2i128(<2 x i128> %x, <2 x i128> %y, <2 x i1> %m) nounwi
 define <3 x i10> @urem_v3i10(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m) {
 ; SSE2-LABEL: urem_v3i10:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movd %r8d, %xmm1
-; SSE2-NEXT:    movd %ecx, %xmm0
+; SSE2-NEXT:    movd %esi, %xmm1
+; SSE2-NEXT:    movd %edi, %xmm0
 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE2-NEXT:    movd %r9d, %xmm1
+; SSE2-NEXT:    movd %edx, %xmm1
 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
-; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
-; SSE2-NEXT:    movd {{.*#+}} xmm2 = mem[0],zero,zero,zero
+; SSE2-NEXT:    movd %r8d, %xmm1
+; SSE2-NEXT:    movd %ecx, %xmm2
 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
-; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
-; SSE2-NEXT:    pslld $31, %xmm2
-; SSE2-NEXT:    psrad $31, %xmm2
-; SSE2-NEXT:    movd %esi, %xmm3
-; SSE2-NEXT:    movd %edi, %xmm1
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
-; SSE2-NEXT:    movd %edx, %xmm3
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0]
+; SSE2-NEXT:    movd %r9d, %xmm3
+; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
 ; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [1023,1023,1023,1023]
-; SSE2-NEXT:    pand %xmm3, %xmm1
-; SSE2-NEXT:    pand %xmm3, %xmm0
-; SSE2-NEXT:    pand %xmm2, %xmm0
-; SSE2-NEXT:    paddd %xmm2, %xmm0
-; SSE2-NEXT:    pcmpeqd %xmm2, %xmm2
+; SSE2-NEXT:    movdqa %xmm2, %xmm4
+; SSE2-NEXT:    pand %xmm3, %xmm4
+; SSE2-NEXT:    cvtdq2ps %xmm4, %xmm4
+; SSE2-NEXT:    pand %xmm0, %xmm3
+; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; SSE2-NEXT:    divps %xmm4, %xmm3
+; SSE2-NEXT:    cvttps2dq %xmm3, %xmm3
+; SSE2-NEXT:    pmuludq %xmm3, %xmm2
+; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,0,0,0]
+; SSE2-NEXT:    pmuludq %xmm3, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
 ; SSE2-NEXT:    psubd %xmm2, %xmm0
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
-; SSE2-NEXT:    movd %xmm2, %ecx
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3]
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    xorl %edx, %edx
-; SSE2-NEXT:    divl %ecx
-; SSE2-NEXT:    movl %edx, %ecx
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,1,1,1]
-; SSE2-NEXT:    movd %xmm2, %esi
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[1,1,1,1]
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    xorl %edx, %edx
-; SSE2-NEXT:    divl %esi
-; SSE2-NEXT:    movl %edx, %esi
-; SSE2-NEXT:    movd %xmm0, %edi
-; SSE2-NEXT:    movd %xmm1, %eax
-; SSE2-NEXT:    xorl %edx, %edx
-; SSE2-NEXT:    divl %edi
-; SSE2-NEXT:    movl %edx, %eax
+; SSE2-NEXT:    pextrw $2, %xmm0, %edx
+; SSE2-NEXT:    pextrw $4, %xmm0, %ecx
+; SSE2-NEXT:    movd %xmm0, %eax
 ; SSE2-NEXT:    # kill: def $ax killed $ax killed $eax
-; SSE2-NEXT:    movl %esi, %edx
+; SSE2-NEXT:    # kill: def $dx killed $dx killed $edx
 ; SSE2-NEXT:    # kill: def $cx killed $cx killed $ecx
 ; SSE2-NEXT:    retq
 ;
 ; SSE42-LABEL: urem_v3i10:
 ; SSE42:       # %bb.0:
-; SSE42-NEXT:    movd %edi, %xmm1
-; SSE42-NEXT:    pinsrd $1, %esi, %xmm1
-; SSE42-NEXT:    pinsrd $2, %edx, %xmm1
-; SSE42-NEXT:    movdqa {{.*#+}} xmm0 = [1023,1023,1023,1023]
-; SSE42-NEXT:    movd %ecx, %xmm2
-; SSE42-NEXT:    pinsrd $1, %r8d, %xmm2
-; SSE42-NEXT:    pinsrd $2, %r9d, %xmm2
-; SSE42-NEXT:    pand %xmm0, %xmm1
-; SSE42-NEXT:    pand %xmm0, %xmm2
-; SSE42-NEXT:    movd {{.*#+}} xmm3 = mem[0],zero,zero,zero
-; SSE42-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; SSE42-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
-; SSE42-NEXT:    movd {{.*#+}} xmm3 = mem[0],zero,zero,zero
-; SSE42-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm3[0]
-; SSE42-NEXT:    pslld $31, %xmm0
-; SSE42-NEXT:    movaps {{.*#+}} xmm3 = [1,1,1,1]
-; SSE42-NEXT:    blendvps %xmm0, %xmm2, %xmm3
-; SSE42-NEXT:    extractps $1, %xmm3, %ecx
-; SSE42-NEXT:    pextrd $1, %xmm1, %eax
-; SSE42-NEXT:    xorl %edx, %edx
-; SSE42-NEXT:    divl %ecx
-; SSE42-NEXT:    movl %edx, %ecx
-; SSE42-NEXT:    movd %xmm3, %esi
-; SSE42-NEXT:    movd %xmm1, %eax
-; SSE42-NEXT:    xorl %edx, %edx
-; SSE42-NEXT:    divl %esi
-; SSE42-NEXT:    movl %edx, %esi
-; SSE42-NEXT:    movd %edx, %xmm0
-; SSE42-NEXT:    pinsrd $1, %ecx, %xmm0
-; SSE42-NEXT:    pextrd $2, %xmm3, %ecx
-; SSE42-NEXT:    pextrd $2, %xmm1, %eax
-; SSE42-NEXT:    xorl %edx, %edx
-; SSE42-NEXT:    divl %ecx
-; SSE42-NEXT:    pextrw $2, %xmm0, %edi
+; SSE42-NEXT:    movd %edi, %xmm0
+; SSE42-NEXT:    pinsrd $1, %esi, %xmm0
 ; SSE42-NEXT:    pinsrd $2, %edx, %xmm0
+; SSE42-NEXT:    movd %ecx, %xmm1
+; SSE42-NEXT:    pinsrd $1, %r8d, %xmm1
+; SSE42-NEXT:    pinsrd $2, %r9d, %xmm1
+; SSE42-NEXT:    movdqa {{.*#+}} xmm2 = [1023,1023,1023,1023]
+; SSE42-NEXT:    movdqa %xmm1, %xmm3
+; SSE42-NEXT:    pand %xmm2, %xmm3
+; SSE42-NEXT:    cvtdq2ps %xmm3, %xmm3
+; SSE42-NEXT:    pand %xmm0, %xmm2
+; SSE42-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE42-NEXT:    divps %xmm3, %xmm2
+; SSE42-NEXT:    cvttps2dq %xmm2, %xmm2
+; SSE42-NEXT:    pmulld %xmm1, %xmm2
+; SSE42-NEXT:    psubd %xmm2, %xmm0
+; SSE42-NEXT:    pextrw $2, %xmm0, %edx
 ; SSE42-NEXT:    pextrw $4, %xmm0, %ecx
-; SSE42-NEXT:    movl %esi, %eax
-; SSE42-NEXT:    movl %edi, %edx
+; SSE42-NEXT:    movd %xmm0, %eax
+; SSE42-NEXT:    # kill: def $ax killed $ax killed $eax
+; SSE42-NEXT:    # kill: def $dx killed $dx killed $edx
 ; SSE42-NEXT:    # kill: def $cx killed $cx killed $ecx
 ; SSE42-NEXT:    retq
 ;
-; AVX2-LABEL: urem_v3i10:
-; AVX2:       # %bb.0:
-; AVX2-NEXT:    vmovd %edi, %xmm0
-; AVX2-NEXT:    vpinsrd $1, %esi, %xmm0, %xmm0
-; AVX2-NEXT:    vpinsrd $2, %edx, %xmm0, %xmm0
-; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm1 = [1023,1023,1023,1023]
-; AVX2-NEXT:    vmovd %ecx, %xmm2
-; AVX2-NEXT:    vpinsrd $1, %r8d, %xmm2, %xmm2
-; AVX2-NEXT:    vpinsrd $2, %r9d, %xmm2, %xmm2
-; AVX2-NEXT:    vpand %xmm1, %xmm0, %xmm0
-; AVX2-NEXT:    vpand %xmm1, %xmm2, %xmm1
-; AVX2-NEXT:    vcvtdq2ps %xmm1, %xmm2
-; AVX2-NEXT:    vcvtdq2ps %xmm0, %xmm3
-; AVX2-NEXT:    vdivps %xmm2, %xmm3, %xmm2
-; AVX2-NEXT:    vcvttps2dq %xmm2, %xmm3
-; AVX2-NEXT:    vpsrad $31, %xmm3, %xmm4
-; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm5 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
-; AVX2-NEXT:    vsubps %xmm5, %xmm2, %xmm2
-; AVX2-NEXT:    vcvttps2dq %xmm2, %xmm2
-; AVX2-NEXT:    vpand %xmm4, %xmm2, %xmm2
-; AVX2-NEXT:    vpor %xmm2, %xmm3, %xmm2
-; AVX2-NEXT:    vpmulld %xmm1, %xmm2, %xmm1
-; AVX2-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
-; AVX2-NEXT:    vmovd %xmm0, %eax
-; AVX2-NEXT:    vpextrw $2, %xmm0, %edx
-; AVX2-NEXT:    vpextrw $4, %xmm0, %ecx
-; AVX2-NEXT:    # kill: def $ax killed $ax killed $eax
-; AVX2-NEXT:    # kill: def $dx killed $dx killed $edx
-; AVX2-NEXT:    # kill: def $cx killed $cx killed $ecx
-; AVX2-NEXT:    retq
-;
-; AVX512-LABEL: urem_v3i10:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vmovd %edi, %xmm0
-; AVX512-NEXT:    vpinsrd $1, %esi, %xmm0, %xmm0
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm0, %xmm0
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} xmm1 = [1023,1023,1023,1023]
-; AVX512-NEXT:    vpand %xmm1, %xmm0, %xmm0
-; AVX512-NEXT:    vmovd %ecx, %xmm2
-; AVX512-NEXT:    vpinsrd $1, %r8d, %xmm2, %xmm2
-; AVX512-NEXT:    vpinsrd $2, %r9d, %xmm2, %xmm2
-; AVX512-NEXT:    vpand %xmm1, %xmm2, %xmm1
-; AVX512-NEXT:    vcvtdq2ps %xmm1, %xmm2
-; AVX512-NEXT:    vcvtdq2ps %xmm0, %xmm3
-; AVX512-NEXT:    vdivps %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vcvttps2udq %xmm2, %xmm2
-; AVX512-NEXT:    vpmulld %xmm1, %xmm2, %xmm1
-; AVX512-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
-; AVX512-NEXT:    vmovd %xmm0, %eax
-; AVX512-NEXT:    vpextrw $2, %xmm0, %edx
-; AVX512-NEXT:    vpextrw $4, %xmm0, %ecx
-; AVX512-NEXT:    # kill: def $ax killed $ax killed $eax
-; AVX512-NEXT:    # kill: def $dx killed $dx killed $edx
-; AVX512-NEXT:    # kill: def $cx killed $cx killed $ecx
-; AVX512-NEXT:    retq
+; AVX-LABEL: urem_v3i10:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vmovd %edi, %xmm0
+; AVX-NEXT:    vpinsrd $1, %esi, %xmm0, %xmm0
+; AVX-NEXT:    vpinsrd $2, %edx, %xmm0, %xmm0
+; AVX-NEXT:    vmovd %ecx, %xmm1
+; AVX-NEXT:    vpinsrd $1, %r8d, %xmm1, %xmm1
+; AVX-NEXT:    vpinsrd $2, %r9d, %xmm1, %xmm1
+; AVX-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [1023,1023,1023,1023]
+; AVX-NEXT:    vpand %xmm2, %xmm1, %xmm3
+; AVX-NEXT:    vcvtdq2ps %xmm3, %xmm3
+; AVX-NEXT:    vpand %xmm2, %xmm0, %xmm2
+; AVX-NEXT:    vcvtdq2ps %xmm2, %xmm2
+; AVX-NEXT:    vdivps %xmm3, %xmm2, %xmm2
+; AVX-NEXT:    vcvttps2dq %xmm2, %xmm2
+; AVX-NEXT:    vpmulld %xmm1, %xmm2, %xmm1
+; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    vmovd %xmm0, %eax
+; AVX-NEXT:    vpextrw $2, %xmm0, %edx
+; AVX-NEXT:    vpextrw $4, %xmm0, %ecx
+; AVX-NEXT:    # kill: def $ax killed $ax killed $eax
+; AVX-NEXT:    # kill: def $dx killed $dx killed $edx
+; AVX-NEXT:    # kill: def $cx killed $cx killed $ecx
+; AVX-NEXT:    retq
   %res = call <3 x i10> @llvm.masked.urem(<3 x i10> %x, <3 x i10> %y, <3 x i1> %m)
   ret <3 x i10> %res
 }
diff --git a/llvm/test/CodeGen/X86/scalar_widen_div.ll b/llvm/test/CodeGen/X86/scalar_widen_div.ll
index f24d018aea88f..4eb8b693101da 100644
--- a/llvm/test/CodeGen/X86/scalar_widen_div.ll
+++ b/llvm/test/CodeGen/X86/scalar_widen_div.ll
@@ -4,6 +4,33 @@
 ; Verify when widening a divide/remainder operation, we only generate a
 ; divide/rem per element since divide/remainder can trap.
 
+define void @div_extract(ptr %dst, ptr %lhs, ptr %rhs) nounwind {
+; CHECK-LABEL: div_extract:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movzwl (%rsi), %eax
+; CHECK-NEXT:    movd %eax, %xmm0
+; CHECK-NEXT:    movzwl (%rdx), %eax
+; CHECK-NEXT:    movd %eax, %xmm1
+; CHECK-NEXT:    pmovzxbd {{.*#+}} xmm1 = xmm1[0],zero,zero,zero,xmm1[1],zero,zero,zero,xmm1[2],zero,zero,zero,xmm1[3],zero,zero,zero
+; CHECK-NEXT:    cvtdq2ps %xmm1, %xmm1
+; CHECK-NEXT:    pmovzxbd {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero
+; CHECK-NEXT:    cvtdq2ps %xmm0, %xmm0
+; CHECK-NEXT:    divps %xmm1, %xmm0
+; CHECK-NEXT:    cvttps2dq %xmm0, %xmm0
+; CHECK-NEXT:    pextrb $0, %xmm0, (%rdi)
+; CHECK-NEXT:    pextrb $4, %xmm0, 1(%rdi)
+; CHECK-NEXT:    retq
+  %a = load <2 x i8>, ptr %lhs
+  %b = load <2 x i8>, ptr %rhs
+  %quot = udiv <2 x i8> %a, %b
+  %elt0 = extractelement <2 x i8> %quot, i64 0
+  store i8 %elt0, ptr %dst, align 1
+  %next = getelementptr inbounds nuw i8, ptr %dst, i64 1
+  %elt1 = extractelement <2 x i8> %quot, i64 1
+  store i8 %elt1, ptr %next, align 1
+  ret void
+}
+
 define void @vectorDiv (ptr addrspace(1) %nsource, ptr addrspace(1) %dsource, ptr addrspace(1) %qdest) nounwind {
 ; CHECK-LABEL: vectorDiv:
 ; CHECK:       # %bb.0: # %entry
@@ -44,18 +71,26 @@ entry:
 define <3 x i8> @test_char_div(<3 x i8> %num, <3 x i8> %div) {
 ; CHECK-LABEL: test_char_div:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movsbl %dil, %eax
-; CHECK-NEXT:    idivb %cl
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    movsbl %sil, %eax
-; CHECK-NEXT:    idivb %r8b
-; CHECK-NEXT:    movl %eax, %esi
-; CHECK-NEXT:    movsbl %dl, %eax
-; CHECK-NEXT:    idivb %r9b
-; CHECK-NEXT:    movl %eax, %edi
-; CHECK-NEXT:    movl %ecx, %eax
-; CHECK-NEXT:    movl %esi, %edx
-; CHECK-NEXT:    movl %edi, %ecx
+; CHECK-NEXT:    movd %edi, %xmm0
+; CHECK-NEXT:    pinsrb $1, %esi, %xmm0
+; CHECK-NEXT:    pinsrb $2, %edx, %xmm0
+; CHECK-NEXT:    movd %ecx, %xmm1
+; CHECK-NEXT:    pinsrb $1, %r8d, %xmm1
+; CHECK-NEXT:    pinsrb $2, %r9d, %xmm1
+; CHECK-NEXT:    pmovsxbd %xmm1, %xmm1
+; CHECK-NEXT:    cvtdq2ps %xmm1, %xmm1
+; CHECK-NEXT:    pmovsxbd %xmm0, %xmm0
+; CHECK-NEXT:    cvtdq2ps %xmm0, %xmm0
+; CHECK-NEXT:    divps %xmm1, %xmm0
+; CHECK-NEXT:    cvttps2dq %xmm0, %xmm0
+; CHECK-NEXT:    packssdw %xmm0, %xmm0
+; CHECK-NEXT:    packsswb %xmm0, %xmm0
+; CHECK-NEXT:    movd %xmm0, %eax
+; CHECK-NEXT:    pextrb $1, %xmm0, %edx
+; CHECK-NEXT:    pextrb $2, %xmm0, %ecx
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
+; CHECK-NEXT:    # kill: def $dl killed $dl killed $edx
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; CHECK-NEXT:    retq
   %div.r = sdiv <3 x i8> %num, %div
   ret <3 x i8>  %div.r
@@ -64,18 +99,26 @@ define <3 x i8> @test_char_div(<3 x i8> %num, <3 x i8> %div) {
 define <3 x i8> @test_uchar_div(<3 x i8> %num, <3 x i8> %div) {
 ; CHECK-LABEL: test_uchar_div:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movzbl %dil, %eax
-; CHECK-NEXT:    divb %cl
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    movzbl %sil, %eax
-; CHECK-NEXT:    divb %r8b
-; CHECK-NEXT:    movl %eax, %esi
-; CHECK-NEXT:    movzbl %dl, %eax
-; CHECK-NEXT:    divb %r9b
-; CHECK-NEXT:    movl %eax, %edi
-; CHECK-NEXT:    movl %ecx, %eax
-; CHECK-NEXT:    movl %esi, %edx
-; CHECK-NEXT:    movl %edi, %ecx
+; CHECK-NEXT:    movd %edi, %xmm0
+; CHECK-NEXT:    pinsrb $1, %esi, %xmm0
+; CHECK-NEXT:    pinsrb $2, %edx, %xmm0
+; CHECK-NEXT:    movd %ecx, %xmm1
+; CHECK-NEXT:    pinsrb $1, %r8d, %xmm1
+; CHECK-NEXT:    pinsrb $2, %r9d, %xmm1
+; CHECK-NEXT:    pmovzxbd {{.*#+}} xmm1 = xmm1[0],zero,zero,zero,xmm1[1],zero,zero,zero,xmm1[2],zero,zero,zero,xmm1[3],zero,zero,zero
+; CHECK-NEXT:    cvtdq2ps %xmm1, %xmm1
+; CHECK-NEXT:    pmovzxbd {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero
+; CHECK-NEXT:    cvtdq2ps %xmm0, %xmm0
+; CHECK-NEXT:    divps %xmm1, %xmm0
+; CHECK-NEXT:    cvttps2dq %xmm0, %xmm0
+; CHECK-NEXT:    packusdw %xmm0, %xmm0
+; CHECK-NEXT:    packuswb %xmm0, %xmm0
+; CHECK-NEXT:    movd %xmm0, %eax
+; CHECK-NEXT:    pextrb $1, %xmm0, %edx
+; CHECK-NEXT:    pextrb $2, %xmm0, %ecx
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
+; CHECK-NEXT:    # kill: def $dl killed $dl killed $edx
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
 ; CHECK-NEXT:    retq
   %div.r = udiv <3 x i8> %num, %div
   ret <3 x i8>  %div.r
@@ -84,41 +127,23 @@ define <3 x i8> @test_uchar_div(<3 x i8> %num, <3 x i8> %div) {
 define <5 x i16> @test_short_div(<5 x i16> %num, <5 x i16> %div) {
 ; CHECK-LABEL: test_short_div:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pextrw $4, %xmm0, %eax
-; CHECK-NEXT:    pextrw $4, %xmm1, %ecx
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT:    cwtd
-; CHECK-NEXT:    idivw %cx
-; CHECK-NEXT:    movl %eax, %ecx
-; CHECK-NEXT:    pextrw $3, %xmm0, %eax
-; CHECK-NEXT:    pextrw $3, %xmm1, %esi
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT:    cwtd
-; CHECK-NEXT:    idivw %si
-; CHECK-NEXT:    movl %eax, %esi
-; CHECK-NEXT:    pextrw $2, %xmm0, %eax
-; CHECK-NEXT:    pextrw $2, %xmm1, %edi
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT:    cwtd
-; CHECK-NEXT:    idivw %di
-; CHECK-NEXT:    movl %eax, %edi
-; CHECK-NEXT:    movd %xmm0, %eax
-; CHECK-NEXT:    movd %xmm1, %r8d
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT:    cwtd
-; CHECK-NEXT:    idivw %r8w
-; CHECK-NEXT:    movl %eax, %r8d
-; CHECK-NEXT:    pextrw $1, %xmm0, %eax
-; CHECK-NEXT:    pextrw $1, %xmm1, %r9d
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT:    cwtd
-; CHECK-NEXT:    idivw %r9w
-; CHECK-NEXT:    # kill: def $ax killed $ax def $eax
-; CHECK-NEXT:    movd %r8d, %xmm0
-; CHECK-NEXT:    pinsrw $1, %eax, %xmm0
-; CHECK-NEXT:    pinsrw $2, %edi, %xmm0
-; CHECK-NEXT:    pinsrw $3, %esi, %xmm0
-; CHECK-NEXT:    pinsrw $4, %ecx, %xmm0
+; CHECK-NEXT:    pmovsxwd %xmm1, %xmm2
+; CHECK-NEXT:    cvtdq2ps %xmm2, %xmm2
+; CHECK-NEXT:    pmovsxwd %xmm0, %xmm3
+; CHECK-NEXT:    cvtdq2ps %xmm3, %xmm3
+; CHECK-NEXT:    divps %xmm2, %xmm3
+; CHECK-NEXT:    cvttps2dq %xmm3, %xmm2
+; CHECK-NEXT:    packssdw %xmm2, %xmm2
+; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,2,3]
+; CHECK-NEXT:    pmovsxwd %xmm1, %xmm1
+; CHECK-NEXT:    cvtdq2ps %xmm1, %xmm1
+; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
+; CHECK-NEXT:    pmovsxwd %xmm0, %xmm0
+; CHECK-NEXT:    cvtdq2ps %xmm0, %xmm0
+; CHECK-NEXT:    divps %xmm1, %xmm0
+; CHECK-NEXT:    cvttps2dq %xmm0, %xmm0
+; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0]
+; CHECK-NEXT:    movdqa %xmm2, %xmm0
 ; CHECK-NEXT:    retq
   %div.r = sdiv <5 x i16> %num, %div
   ret <5 x i16>  %div.r
@@ -234,41 +259,24 @@ define <4 x i8> @test_char_rem(<4 x i8> %num, <4 x i8> %rem) {
 define <5 x i16> @test_short_rem(<5 x i16> %num, <5 x i16> %rem) {
 ; CHECK-LABEL: test_short_rem:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pextrw $4, %xmm0, %eax
-; CHECK-NEXT:    pextrw $4, %xmm1, %ecx
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT:    cwtd
-; CHECK-NEXT:    idivw %cx
-; CHECK-NEXT:    movl %edx, %ecx
-; CHECK-NEXT:    pextrw $3, %xmm0, %eax
-; CHECK-NEXT:    pextrw $3, %xmm1, %esi
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT:    cwtd
-; CHECK-NEXT:    idivw %si
-; CHECK-NEXT:    movl %edx, %esi
-; CHECK-NEXT:    pextrw $2, %xmm0, %eax
-; CHECK-NEXT:    pextrw $2, %xmm1, %edi
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT:    cwtd
-; CHECK-NEXT:    idivw %di
-; CHECK-NEXT:    movl %edx, %edi
-; CHECK-NEXT:    movd %xmm0, %eax
-; CHECK-NEXT:    movd %xmm1, %r8d
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT:    cwtd
-; CHECK-NEXT:    idivw %r8w
-; CHECK-NEXT:    movl %edx, %r8d
-; CHECK-NEXT:    pextrw $1, %xmm0, %eax
-; CHECK-NEXT:    pextrw $1, %xmm1, %r9d
-; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT:    cwtd
-; CHECK-NEXT:    idivw %r9w
-; CHECK-NEXT:    # kill: def $dx killed $dx def $edx
-; CHECK-NEXT:    movd %r8d, %xmm0
-; CHECK-NEXT:    pinsrw $1, %edx, %xmm0
-; CHECK-NEXT:    pinsrw $2, %edi, %xmm0
-; CHECK-NEXT:    pinsrw $3, %esi, %xmm0
-; CHECK-NEXT:    pinsrw $4, %ecx, %xmm0
+; CHECK-NEXT:    pmovsxwd %xmm1, %xmm2
+; CHECK-NEXT:    cvtdq2ps %xmm2, %xmm2
+; CHECK-NEXT:    pmovsxwd %xmm0, %xmm3
+; CHECK-NEXT:    cvtdq2ps %xmm3, %xmm3
+; CHECK-NEXT:    divps %xmm2, %xmm3
+; CHECK-NEXT:    cvttps2dq %xmm3, %xmm2
+; CHECK-NEXT:    packssdw %xmm2, %xmm2
+; CHECK-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[2,3,2,3]
+; CHECK-NEXT:    pmovsxwd %xmm3, %xmm3
+; CHECK-NEXT:    cvtdq2ps %xmm3, %xmm3
+; CHECK-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[2,3,2,3]
+; CHECK-NEXT:    pmovsxwd %xmm4, %xmm4
+; CHECK-NEXT:    cvtdq2ps %xmm4, %xmm4
+; CHECK-NEXT:    divps %xmm3, %xmm4
+; CHECK-NEXT:    cvttps2dq %xmm4, %xmm3
+; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
+; CHECK-NEXT:    pmullw %xmm1, %xmm2
+; CHECK-NEXT:    psubw %xmm2, %xmm0
 ; CHECK-NEXT:    retq
   %rem.r = srem <5 x i16> %num, %rem
   ret <5 x i16>  %rem.r
@@ -333,11 +341,11 @@ define void @test_int_div(ptr %dest, ptr %old, i32 %n) {
 ; CHECK-LABEL: test_int_div:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    testl %edx, %edx
-; CHECK-NEXT:    jle .LBB12_3
+; CHECK-NEXT:    jle .LBB13_3
 ; CHECK-NEXT:  # %bb.1: # %bb.nph
 ; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    .p2align 4
-; CHECK-NEXT:  .LBB12_2: # %for.body
+; CHECK-NEXT:  .LBB13_2: # %for.body
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    movdqa (%rdi,%rax), %xmm0
 ; CHECK-NEXT:    movdqa (%rsi,%rax), %xmm1
@@ -355,8 +363,8 @@ define void @test_int_div(ptr %dest, ptr %old, i32 %n) {
 ; CHECK-NEXT:    movss %xmm2, 8(%rdi,%rax)
 ; CHECK-NEXT:    addq $16, %rax
 ; CHECK-NEXT:    decl %edx
-; CHECK-NEXT:    jne .LBB12_2
-; CHECK-NEXT:  .LBB12_3: # %for.end
+; CHECK-NEXT:    jne .LBB13_2
+; CHECK-NEXT:  .LBB13_3: # %for.end
 ; CHECK-NEXT:    retq
 entry:
   %cmp13 = icmp sgt i32 %n, 0
diff --git a/llvm/test/CodeGen/X86/vector-idiv-udiv-256.ll b/llvm/test/CodeGen/X86/vector-idiv-udiv-256.ll
index 7ca985872b875..1353c09e4e3f1 100644
--- a/llvm/test/CodeGen/X86/vector-idiv-udiv-256.ll
+++ b/llvm/test/CodeGen/X86/vector-idiv-udiv-256.ll
@@ -443,6 +443,120 @@ define <8 x i32> @test_divv_8i32(<8 x i32> %a, <8 x i32> %b) nounwind {
   ret <8 x i32> %res
 }
 
+
+define <7 x i32> @test_divv_7i32(<7 x i32> %a, <7 x i32> %b) nounwind {
+; AVX1-LABEL: test_divv_7i32:
+; AVX1:       # %bb.0:
+; AVX1-NEXT:    vpextrd $1, %xmm0, %eax
+; AVX1-NEXT:    vpextrd $1, %xmm1, %ecx
+; AVX1-NEXT:    xorl %edx, %edx
+; AVX1-NEXT:    divl %ecx
+; AVX1-NEXT:    movl %eax, %ecx
+; AVX1-NEXT:    vmovd %xmm0, %eax
+; AVX1-NEXT:    vmovd %xmm1, %esi
+; AVX1-NEXT:    xorl %edx, %edx
+; AVX1-NEXT:    divl %esi
+; AVX1-NEXT:    vmovd %eax, %xmm2
+; AVX1-NEXT:    vpinsrd $1, %ecx, %xmm2, %xmm2
+; AVX1-NEXT:    vpextrd $2, %xmm0, %eax
+; AVX1-NEXT:    vpextrd $2, %xmm1, %ecx
+; AVX1-NEXT:    xorl %edx, %edx
+; AVX1-NEXT:    divl %ecx
+; AVX1-NEXT:    vpinsrd $2, %eax, %xmm2, %xmm2
+; AVX1-NEXT:    vpextrd $3, %xmm0, %eax
+; AVX1-NEXT:    vpextrd $3, %xmm1, %ecx
+; AVX1-NEXT:    xorl %edx, %edx
+; AVX1-NEXT:    divl %ecx
+; AVX1-NEXT:    vpinsrd $3, %eax, %xmm2, %xmm2
+; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
+; AVX1-NEXT:    vpextrd $2, %xmm0, %eax
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
+; AVX1-NEXT:    vpextrd $2, %xmm1, %ecx
+; AVX1-NEXT:    xorl %edx, %edx
+; AVX1-NEXT:    divl %ecx
+; AVX1-NEXT:    movl %eax, %ecx
+; AVX1-NEXT:    vpextrd $1, %xmm0, %eax
+; AVX1-NEXT:    vpextrd $1, %xmm1, %esi
+; AVX1-NEXT:    xorl %edx, %edx
+; AVX1-NEXT:    divl %esi
+; AVX1-NEXT:    movl %eax, %esi
+; AVX1-NEXT:    vmovd %xmm0, %eax
+; AVX1-NEXT:    vmovd %xmm1, %edi
+; AVX1-NEXT:    xorl %edx, %edx
+; AVX1-NEXT:    divl %edi
+; AVX1-NEXT:    vmovd %eax, %xmm0
+; AVX1-NEXT:    vpinsrd $1, %esi, %xmm0, %xmm0
+; AVX1-NEXT:    vpinsrd $2, %ecx, %xmm0, %xmm0
+; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm2, %ymm0
+; AVX1-NEXT:    retq
+;
+; AVX2NOBW-LABEL: test_divv_7i32:
+; AVX2NOBW:       # %bb.0:
+; AVX2NOBW-NEXT:    vpmovzxdq {{.*#+}} ymm2 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero
+; AVX2NOBW-NEXT:    vpbroadcastq {{.*#+}} ymm3 = [4.503599627370496E+15,4.503599627370496E+15,4.503599627370496E+15,4.503599627370496E+15]
+; AVX2NOBW-NEXT:    vpor %ymm3, %ymm2, %ymm2
+; AVX2NOBW-NEXT:    vsubpd %ymm3, %ymm2, %ymm2
+; AVX2NOBW-NEXT:    vpmovzxdq {{.*#+}} ymm4 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero
+; AVX2NOBW-NEXT:    vpor %ymm3, %ymm4, %ymm4
+; AVX2NOBW-NEXT:    vsubpd %ymm3, %ymm4, %ymm4
+; AVX2NOBW-NEXT:    vdivpd %ymm2, %ymm4, %ymm2
+; AVX2NOBW-NEXT:    vbroadcastsd {{.*#+}} ymm4 = [2.147483648E+9,2.147483648E+9,2.147483648E+9,2.147483648E+9]
+; AVX2NOBW-NEXT:    vsubpd %ymm4, %ymm2, %ymm5
+; AVX2NOBW-NEXT:    vcvttpd2dq %ymm5, %xmm5
+; AVX2NOBW-NEXT:    vextracti128 $1, %ymm1, %xmm1
+; AVX2NOBW-NEXT:    vpmovzxdq {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero
+; AVX2NOBW-NEXT:    vpor %ymm3, %ymm1, %ymm1
+; AVX2NOBW-NEXT:    vsubpd %ymm3, %ymm1, %ymm1
+; AVX2NOBW-NEXT:    vextracti128 $1, %ymm0, %xmm0
+; AVX2NOBW-NEXT:    vpmovzxdq {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero
+; AVX2NOBW-NEXT:    vpor %ymm3, %ymm0, %ymm0
+; AVX2NOBW-NEXT:    vsubpd %ymm3, %ymm0, %ymm0
+; AVX2NOBW-NEXT:    vdivpd %ymm1, %ymm0, %ymm0
+; AVX2NOBW-NEXT:    vsubpd %ymm4, %ymm0, %ymm1
+; AVX2NOBW-NEXT:    vcvttpd2dq %ymm1, %xmm1
+; AVX2NOBW-NEXT:    vinsertf128 $1, %xmm1, %ymm5, %ymm1
+; AVX2NOBW-NEXT:    vcvttpd2dq %ymm2, %xmm2
+; AVX2NOBW-NEXT:    vcvttpd2dq %ymm0, %xmm0
+; AVX2NOBW-NEXT:    vinsertf128 $1, %xmm0, %ymm2, %ymm0
+; AVX2NOBW-NEXT:    vpsrad $31, %ymm0, %ymm2
+; AVX2NOBW-NEXT:    vandpd %ymm2, %ymm1, %ymm1
+; AVX2NOBW-NEXT:    vorpd %ymm1, %ymm0, %ymm0
+; AVX2NOBW-NEXT:    retq
+;
+; AVX512BW-LABEL: test_divv_7i32:
+; AVX512BW:       # %bb.0:
+; AVX512BW-NEXT:    vcvtudq2pd %ymm1, %zmm1
+; AVX512BW-NEXT:    vcvtudq2pd %ymm0, %zmm0
+; AVX512BW-NEXT:    vdivpd %zmm1, %zmm0, %zmm0
+; AVX512BW-NEXT:    vcvttpd2udq %zmm0, %ymm0
+; AVX512BW-NEXT:    retq
+  %res = udiv <7 x i32> %a, %b
+  ret <7 x i32> %res
+}
+
+define i32 @test_divv_7i32_extract0(<7 x i32> %a, <7 x i32> %b) nounwind {
+; AVX1-LABEL: test_divv_7i32_extract0:
+; AVX1:       # %bb.0:
+; AVX1-NEXT:    vmovd %xmm0, %eax
+; AVX1-NEXT:    vmovd %xmm1, %ecx
+; AVX1-NEXT:    xorl %edx, %edx
+; AVX1-NEXT:    divl %ecx
+; AVX1-NEXT:    vzeroupper
+; AVX1-NEXT:    retq
+;
+; AVX2-LABEL: test_divv_7i32_extract0:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vmovd %xmm0, %eax
+; AVX2-NEXT:    vmovd %xmm1, %ecx
+; AVX2-NEXT:    xorl %edx, %edx
+; AVX2-NEXT:    divl %ecx
+; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    retq
+  %res = udiv <7 x i32> %a, %b
+  %elt = extractelement <7 x i32> %res, i32 0
+  ret i32 %elt
+}
+
 ;
 ; urem by 7
 ;



More information about the llvm-commits mailing list