[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