[llvm] [X86] Narrow vXi32/vXi64 usubsat to vpsubusb/vpsubusw when LHS is known to fit in fewer bits (PR #206592)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 5 04:28:50 PDT 2026


https://github.com/sipher-01 updated https://github.com/llvm/llvm-project/pull/206592

>From 92f2f1b52486aea60a70334ad749684d38142392 Mon Sep 17 00:00:00 2001
From: Sipher <sourav2003singhkatoch at gmail.com>
Date: Tue, 30 Jun 2026 03:04:39 +0530
Subject: [PATCH] [X86] Narrow vXi32/vXi64 USUBSAT to vXi8/vXi16 when LHS fits
 in fewer bits

When countMaxActiveBits(LHS) <= 8 or <= 16, reinterpret a wide vector
USUBSAT as vpsubusb/vpsubusw by OR-ing the upper bits of the RHS with 1s
so those byte/word lanes saturate to zero harmlessly.

This turns llvm.usub.sat.v8i64 emulation (vpmaxuq + vpsubq, 2 insns)
into a single vpsubusb when the LHS is known to fit in 8 bits.

Fixes https://github.com/llvm/llvm-project/issues/195462
---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  34 ++++++
 llvm/test/CodeGen/AArch64/usub_sat_vec.ll     |  31 +++--
 llvm/test/CodeGen/X86/combine-icmp.ll         |  17 +--
 llvm/test/CodeGen/X86/combine-sub-usat.ll     |  18 ++-
 llvm/test/CodeGen/X86/intrinsic-cttz-elts.ll  |  60 ++++------
 llvm/test/CodeGen/X86/psubus.ll               | 112 +++++++++---------
 llvm/test/CodeGen/X86/usubsat-narrow.ll       |  70 +++++++++++
 llvm/test/CodeGen/X86/var-permute-128.ll      |  22 ++--
 llvm/test/CodeGen/X86/vec_setcc-2.ll          |  10 +-
 .../CodeGen/X86/vector-extract-last-active.ll |  18 +--
 10 files changed, 249 insertions(+), 143 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/usubsat-narrow.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c590f3c189ece..798269d9ad5bf 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -4709,6 +4709,40 @@ SDValue DAGCombiner::visitSUBSAT(SDNode *N) {
   if (DAG.willNotOverflowSub(IsSigned, N0, N1))
     return DAG.getNode(ISD::SUB, DL, VT, N0, N1);
 
+  // Narrow a vXiN USUBSAT to a smaller type when the LHS is known to fit in
+  // fewer bits. If countMaxActiveBits(N0) <= NarrowBits, OR the upper bits of
+  // N1 with 1s so the narrow sat-sub saturates to zero in those positions.
+  // This allows targets with native narrow USUBSAT (e.g. vpsubusb/vpsubusw)
+  // to avoid emulation with vpmaxu + vsub.
+  if (!IsSigned && VT.isVector() && VT.isSimple()) {
+    unsigned ScalarBits = VT.getScalarSizeInBits();
+    if (ScalarBits > 8) {
+      KnownBits Known = DAG.computeKnownBits(N0);
+      unsigned ActiveBits = Known.countMaxActiveBits();
+      unsigned NarrowBits = 0;
+      if (ActiveBits <= 8)
+        NarrowBits = 8;
+      else if (ActiveBits <= 16 && ScalarBits > 16)
+        NarrowBits = 16;
+      if (NarrowBits) {
+        unsigned Scale = ScalarBits / NarrowBits;
+        unsigned NumElts = VT.getVectorNumElements() * Scale;
+        MVT NarrowSVT = MVT::getIntegerVT(NarrowBits);
+        MVT NarrowVT = MVT::getVectorVT(NarrowSVT, NumElts);
+        if (TLI.isOperationLegalOrCustom(ISD::USUBSAT, NarrowVT)) {
+          APInt UpperMask = APInt::getBitsSetFrom(ScalarBits, NarrowBits);
+          SDValue Mask = DAG.getConstant(UpperMask, DL, VT);
+          SDValue N1WithUpperOnes = DAG.getNode(ISD::OR, DL, VT, N1, Mask);
+          SDValue NarrowN0 = DAG.getBitcast(NarrowVT, N0);
+          SDValue NarrowN1 = DAG.getBitcast(NarrowVT, N1WithUpperOnes);
+          SDValue NarrowSub =
+              DAG.getNode(ISD::USUBSAT, DL, NarrowVT, NarrowN0, NarrowN1);
+          return DAG.getBitcast(VT, NarrowSub);
+        }
+      }
+    }
+  }
+
   return SDValue();
 }
 
diff --git a/llvm/test/CodeGen/AArch64/usub_sat_vec.ll b/llvm/test/CodeGen/AArch64/usub_sat_vec.ll
index 8ffafb247c568..58c9d6bf34479 100644
--- a/llvm/test/CodeGen/AArch64/usub_sat_vec.ll
+++ b/llvm/test/CodeGen/AArch64/usub_sat_vec.ll
@@ -113,11 +113,12 @@ define void @v8i8(ptr %px, ptr %py, ptr %pz) nounwind {
 define void @v4i8(ptr %px, ptr %py, ptr %pz) nounwind {
 ; CHECK-SD-LABEL: v4i8:
 ; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    ldr s0, [x0]
-; CHECK-SD-NEXT:    ldr s1, [x1]
+; CHECK-SD-NEXT:    ldr s0, [x1]
+; CHECK-SD-NEXT:    ldr s1, [x0]
 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
 ; CHECK-SD-NEXT:    ushll v1.8h, v1.8b, #0
-; CHECK-SD-NEXT:    uqsub v0.4h, v0.4h, v1.4h
+; CHECK-SD-NEXT:    orr v0.4h, #255, lsl #8
+; CHECK-SD-NEXT:    uqsub v0.8b, v1.8b, v0.8b
 ; CHECK-SD-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
 ; CHECK-SD-NEXT:    str s0, [x2]
 ; CHECK-SD-NEXT:    ret
@@ -139,13 +140,15 @@ define void @v4i8(ptr %px, ptr %py, ptr %pz) nounwind {
 define void @v2i8(ptr %px, ptr %py, ptr %pz) nounwind {
 ; CHECK-SD-LABEL: v2i8:
 ; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    ldr h0, [x0]
-; CHECK-SD-NEXT:    ldr h1, [x1]
-; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
+; CHECK-SD-NEXT:    ldr h0, [x1]
+; CHECK-SD-NEXT:    ldr h1, [x0]
+; CHECK-SD-NEXT:    movi d2, #0xffffff00ffffff00
+; CHECK-SD-NEXT:    zip1 v0.8b, v0.8b, v0.8b
 ; CHECK-SD-NEXT:    ushll v1.8h, v1.8b, #0
-; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
 ; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
-; CHECK-SD-NEXT:    uqsub v0.2s, v0.2s, v1.2s
+; CHECK-SD-NEXT:    zip1 v0.4h, v0.4h, v0.4h
+; CHECK-SD-NEXT:    orr v0.8b, v0.8b, v2.8b
+; CHECK-SD-NEXT:    uqsub v0.8b, v1.8b, v0.8b
 ; CHECK-SD-NEXT:    mov s1, v0.s[1]
 ; CHECK-SD-NEXT:    str b0, [x2]
 ; CHECK-SD-NEXT:    stur b1, [x2, #1]
@@ -189,11 +192,13 @@ define void @v4i16(ptr %px, ptr %py, ptr %pz) nounwind {
 define void @v2i16(ptr %px, ptr %py, ptr %pz) nounwind {
 ; CHECK-SD-LABEL: v2i16:
 ; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    ldr s0, [x0]
-; CHECK-SD-NEXT:    ldr s1, [x1]
-; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
-; CHECK-SD-NEXT:    ushll v1.4s, v1.4h, #0
-; CHECK-SD-NEXT:    uqsub v0.2s, v0.2s, v1.2s
+; CHECK-SD-NEXT:    ldr s0, [x1]
+; CHECK-SD-NEXT:    movi d1, #0xffff0000ffff0000
+; CHECK-SD-NEXT:    ldr s2, [x0]
+; CHECK-SD-NEXT:    zip1 v0.4h, v0.4h, v0.4h
+; CHECK-SD-NEXT:    ushll v2.4s, v2.4h, #0
+; CHECK-SD-NEXT:    orr v0.8b, v0.8b, v1.8b
+; CHECK-SD-NEXT:    uqsub v0.4h, v2.4h, v0.4h
 ; CHECK-SD-NEXT:    mov s1, v0.s[1]
 ; CHECK-SD-NEXT:    str h0, [x2]
 ; CHECK-SD-NEXT:    str h1, [x2, #2]
diff --git a/llvm/test/CodeGen/X86/combine-icmp.ll b/llvm/test/CodeGen/X86/combine-icmp.ll
index 3b44339dc0b4a..d2c12de2d0a73 100644
--- a/llvm/test/CodeGen/X86/combine-icmp.ll
+++ b/llvm/test/CodeGen/X86/combine-icmp.ll
@@ -100,15 +100,18 @@ define i8 @concat_icmp_v8i32_v4i32(<4 x i32> %a0, <4 x i32> %a1) {
 define i16 @concat_icmp_v16i16_v8i16(<8 x i16> %a0, <8 x i16> %a1) {
 ; SSE2-LABEL: concat_icmp_v16i16_v8i16:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [2,2,2,2,2,2,2,2]
-; SSE2-NEXT:    movdqa %xmm2, %xmm3
-; SSE2-NEXT:    psubusw %xmm0, %xmm3
+; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [65280,65280,65280,65280,65280,65280,65280,65280]
+; SSE2-NEXT:    por %xmm2, %xmm0
+; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [2,2,2,2,2,2,2,2]
+; SSE2-NEXT:    movdqa %xmm3, %xmm4
+; SSE2-NEXT:    psubusb %xmm0, %xmm4
 ; SSE2-NEXT:    pxor %xmm0, %xmm0
+; SSE2-NEXT:    pcmpeqw %xmm0, %xmm4
+; SSE2-NEXT:    por %xmm2, %xmm1
+; SSE2-NEXT:    psubusb %xmm1, %xmm3
 ; SSE2-NEXT:    pcmpeqw %xmm0, %xmm3
-; SSE2-NEXT:    psubusw %xmm1, %xmm2
-; SSE2-NEXT:    pcmpeqw %xmm0, %xmm2
-; SSE2-NEXT:    packsswb %xmm2, %xmm3
-; SSE2-NEXT:    pmovmskb %xmm3, %eax
+; SSE2-NEXT:    packsswb %xmm3, %xmm4
+; SSE2-NEXT:    pmovmskb %xmm4, %eax
 ; SSE2-NEXT:    # kill: def $ax killed $ax killed $eax
 ; SSE2-NEXT:    retq
 ;
diff --git a/llvm/test/CodeGen/X86/combine-sub-usat.ll b/llvm/test/CodeGen/X86/combine-sub-usat.ll
index e601c5733bd42..78a32b4d49349 100644
--- a/llvm/test/CodeGen/X86/combine-sub-usat.ll
+++ b/llvm/test/CodeGen/X86/combine-sub-usat.ll
@@ -220,14 +220,16 @@ define <8 x i16> @combine_no_overflow_v8i16(<8 x i16> %a0, <8 x i16> %a1) {
 ; SSE:       # %bb.0:
 ; SSE-NEXT:    psrlw $10, %xmm0
 ; SSE-NEXT:    psrlw $10, %xmm1
-; SSE-NEXT:    psubusw %xmm1, %xmm0
+; SSE-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE-NEXT:    psubusb %xmm1, %xmm0
 ; SSE-NEXT:    retq
 ;
 ; AVX-LABEL: combine_no_overflow_v8i16:
 ; AVX:       # %bb.0:
 ; AVX-NEXT:    vpsrlw $10, %xmm0, %xmm0
 ; AVX-NEXT:    vpsrlw $10, %xmm1, %xmm1
-; AVX-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    vpor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
+; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
 ; AVX-NEXT:    retq
   %1 = lshr <8 x i16> %a0, <i16 10, i16 10, i16 10, i16 10, i16 10, i16 10, i16 10, i16 10>
   %2 = lshr <8 x i16> %a1, <i16 10, i16 10, i16 10, i16 10, i16 10, i16 10, i16 10, i16 10>
@@ -256,28 +258,32 @@ define <8 x i8> @combine_trunc_v8i16_v8i8(<8 x i8> %a0, <8 x i16> %a1) {
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    pxor %xmm2, %xmm2
 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3],xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7]
-; SSE2-NEXT:    psubusw %xmm1, %xmm0
+; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    psubusb %xmm1, %xmm0
 ; SSE2-NEXT:    packuswb %xmm0, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: combine_trunc_v8i16_v8i8:
 ; SSE41:       # %bb.0:
 ; SSE41-NEXT:    pmovzxbw {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
-; SSE41-NEXT:    psubusw %xmm1, %xmm0
+; SSE41-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE41-NEXT:    psubusb %xmm1, %xmm0
 ; SSE41-NEXT:    packuswb %xmm0, %xmm0
 ; SSE41-NEXT:    retq
 ;
 ; SSE42-LABEL: combine_trunc_v8i16_v8i8:
 ; SSE42:       # %bb.0:
 ; SSE42-NEXT:    pmovzxbw {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
-; SSE42-NEXT:    psubusw %xmm1, %xmm0
+; SSE42-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE42-NEXT:    psubusb %xmm1, %xmm0
 ; SSE42-NEXT:    packuswb %xmm0, %xmm0
 ; SSE42-NEXT:    retq
 ;
 ; AVX-LABEL: combine_trunc_v8i16_v8i8:
 ; AVX:       # %bb.0:
 ; AVX-NEXT:    vpmovzxbw {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
-; AVX-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    vpor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
+; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
 ; AVX-NEXT:    vpackuswb %xmm0, %xmm0, %xmm0
 ; AVX-NEXT:    retq
   %1 = zext <8 x i8> %a0 to <8 x i16>
diff --git a/llvm/test/CodeGen/X86/intrinsic-cttz-elts.ll b/llvm/test/CodeGen/X86/intrinsic-cttz-elts.ll
index 65231c484db98..93aba5d87ea1e 100644
--- a/llvm/test/CodeGen/X86/intrinsic-cttz-elts.ll
+++ b/llvm/test/CodeGen/X86/intrinsic-cttz-elts.ll
@@ -1,28 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
 ; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
 
 define i8 @ctz_v8i16(<8 x i16> %a) {
-; CHECK-LABEL: .LCPI0_0:
-; CHECK-NEXT:   .short 8
-; CHECK-NEXT:   .short 7
-; CHECK-NEXT:   .short 6
-; CHECK-NEXT:   .short 5
-; CHECK-NEXT:   .short 4
-; CHECK-NEXT:   .short 3
-; CHECK-NEXT:   .short 2
-; CHECK-NEXT:   .short 1
 ; CHECK-LABEL: ctz_v8i16:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pxor %xmm1, %xmm1
 ; CHECK-NEXT:    pcmpeqw %xmm0, %xmm1
 ; CHECK-NEXT:    pandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
-; CHECK-NEXT:    psubusw %xmm1, %xmm0
-; CHECK-NEXT:    paddw %xmm1, %xmm0
-; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
-; CHECK-NEXT:    psubusw %xmm0, %xmm1
-; CHECK-NEXT:    paddw %xmm0, %xmm1
-; CHECK-NEXT:    pextrw $1, %xmm1, %ecx
-; CHECK-NEXT:    movd %xmm1, %eax
+; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [65280,65280,65280,65280,65280,65280,65280,65280]
+; CHECK-NEXT:    por %xmm1, %xmm0
+; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3]
+; CHECK-NEXT:    psubusb %xmm0, %xmm2
+; CHECK-NEXT:    paddw %xmm1, %xmm2
+; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[1,1,1,1]
+; CHECK-NEXT:    psubusw %xmm2, %xmm0
+; CHECK-NEXT:    paddw %xmm2, %xmm0
+; CHECK-NEXT:    pextrw $1, %xmm0, %ecx
+; CHECK-NEXT:    movd %xmm0, %eax
 ; CHECK-NEXT:    cmpw %cx, %ax
 ; CHECK-NEXT:    cmoval %eax, %ecx
 ; CHECK-NEXT:    movl $8, %eax
@@ -34,11 +28,6 @@ define i8 @ctz_v8i16(<8 x i16> %a) {
 }
 
 define i16 @ctz_v4i32(<4 x i32> %a) {
-; CHECK-LABEL: .LCPI1_0:
-; CHECK-NEXT:   .long 4
-; CHECK-NEXT:   .long 3
-; CHECK-NEXT:   .long 2
-; CHECK-NEXT:   .long 1
 ; CHECK-LABEL: ctz_v4i32:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pxor %xmm1, %xmm1
@@ -69,28 +58,21 @@ define i16 @ctz_v4i32(<4 x i32> %a) {
 ; ZERO IS POISON
 
 define i8 @ctz_v8i16_poison(<8 x i16> %a) {
-; CHECK-LABEL: .LCPI2_0:
-; CHECK-NEXT:   .short 8
-; CHECK-NEXT:   .short 7
-; CHECK-NEXT:   .short 6
-; CHECK-NEXT:   .short 5
-; CHECK-NEXT:   .short 4
-; CHECK-NEXT:   .short 3
-; CHECK-NEXT:   .short 2
-; CHECK-NEXT:   .short 1
 ; CHECK-LABEL: ctz_v8i16_poison:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pxor %xmm1, %xmm1
 ; CHECK-NEXT:    pcmpeqw %xmm0, %xmm1
 ; CHECK-NEXT:    pandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
-; CHECK-NEXT:    psubusw %xmm1, %xmm0
-; CHECK-NEXT:    paddw %xmm1, %xmm0
-; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
-; CHECK-NEXT:    psubusw %xmm0, %xmm1
-; CHECK-NEXT:    paddw %xmm0, %xmm1
-; CHECK-NEXT:    pextrw $1, %xmm1, %ecx
-; CHECK-NEXT:    movd %xmm1, %eax
+; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [65280,65280,65280,65280,65280,65280,65280,65280]
+; CHECK-NEXT:    por %xmm1, %xmm0
+; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3]
+; CHECK-NEXT:    psubusb %xmm0, %xmm2
+; CHECK-NEXT:    paddw %xmm1, %xmm2
+; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[1,1,1,1]
+; CHECK-NEXT:    psubusw %xmm2, %xmm0
+; CHECK-NEXT:    paddw %xmm2, %xmm0
+; CHECK-NEXT:    pextrw $1, %xmm0, %ecx
+; CHECK-NEXT:    movd %xmm0, %eax
 ; CHECK-NEXT:    cmpw %cx, %ax
 ; CHECK-NEXT:    cmoval %eax, %ecx
 ; CHECK-NEXT:    movl $8, %eax
diff --git a/llvm/test/CodeGen/X86/psubus.ll b/llvm/test/CodeGen/X86/psubus.ll
index b93862be0a1b4..c0c71804ab425 100644
--- a/llvm/test/CodeGen/X86/psubus.ll
+++ b/llvm/test/CodeGen/X86/psubus.ll
@@ -2916,40 +2916,33 @@ define <8 x i32> @test34(<8 x i32> %a0, <8 x i64> %a1) {
 ; SSE2OR3-NEXT:    pxor %xmm8, %xmm3
 ; SSE2OR3-NEXT:    por %xmm2, %xmm3
 ; SSE2OR3-NEXT:    shufps {{.*#+}} xmm3 = xmm3[0,2],xmm9[0,2]
-; SSE2OR3-NEXT:    movdqa %xmm0, %xmm2
-; SSE2OR3-NEXT:    psubd %xmm3, %xmm2
-; SSE2OR3-NEXT:    pxor %xmm6, %xmm3
-; SSE2OR3-NEXT:    por %xmm6, %xmm0
-; SSE2OR3-NEXT:    pcmpgtd %xmm3, %xmm0
-; SSE2OR3-NEXT:    pand %xmm2, %xmm0
-; SSE2OR3-NEXT:    movdqa %xmm5, %xmm2
-; SSE2OR3-NEXT:    pxor %xmm6, %xmm2
-; SSE2OR3-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[0,0,2,2]
-; SSE2OR3-NEXT:    movdqa %xmm7, %xmm9
-; SSE2OR3-NEXT:    pcmpgtd %xmm3, %xmm9
-; SSE2OR3-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
-; SSE2OR3-NEXT:    pcmpeqd %xmm6, %xmm2
-; SSE2OR3-NEXT:    pand %xmm9, %xmm2
-; SSE2OR3-NEXT:    pand %xmm2, %xmm5
-; SSE2OR3-NEXT:    pxor %xmm8, %xmm2
-; SSE2OR3-NEXT:    por %xmm5, %xmm2
-; SSE2OR3-NEXT:    movdqa %xmm4, %xmm3
+; SSE2OR3-NEXT:    movaps {{.*#+}} xmm2 = [4294967040,4294967040,4294967040,4294967040]
+; SSE2OR3-NEXT:    orps %xmm2, %xmm3
+; SSE2OR3-NEXT:    psubusb %xmm3, %xmm0
+; SSE2OR3-NEXT:    movdqa %xmm5, %xmm3
 ; SSE2OR3-NEXT:    pxor %xmm6, %xmm3
-; SSE2OR3-NEXT:    pshufd {{.*#+}} xmm5 = xmm3[0,0,2,2]
-; SSE2OR3-NEXT:    pcmpgtd %xmm5, %xmm7
+; SSE2OR3-NEXT:    pshufd {{.*#+}} xmm9 = xmm3[0,0,2,2]
+; SSE2OR3-NEXT:    movdqa %xmm7, %xmm10
+; SSE2OR3-NEXT:    pcmpgtd %xmm9, %xmm10
 ; SSE2OR3-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
 ; SSE2OR3-NEXT:    pcmpeqd %xmm6, %xmm3
-; SSE2OR3-NEXT:    pand %xmm7, %xmm3
-; SSE2OR3-NEXT:    pxor %xmm3, %xmm8
-; SSE2OR3-NEXT:    pand %xmm4, %xmm3
-; SSE2OR3-NEXT:    por %xmm8, %xmm3
-; SSE2OR3-NEXT:    shufps {{.*#+}} xmm3 = xmm3[0,2],xmm2[0,2]
-; SSE2OR3-NEXT:    movdqa %xmm1, %xmm2
-; SSE2OR3-NEXT:    psubd %xmm3, %xmm2
-; SSE2OR3-NEXT:    pxor %xmm6, %xmm3
-; SSE2OR3-NEXT:    por %xmm6, %xmm1
-; SSE2OR3-NEXT:    pcmpgtd %xmm3, %xmm1
-; SSE2OR3-NEXT:    pand %xmm2, %xmm1
+; SSE2OR3-NEXT:    pand %xmm10, %xmm3
+; SSE2OR3-NEXT:    pand %xmm3, %xmm5
+; SSE2OR3-NEXT:    pxor %xmm8, %xmm3
+; SSE2OR3-NEXT:    por %xmm5, %xmm3
+; SSE2OR3-NEXT:    movdqa %xmm4, %xmm5
+; SSE2OR3-NEXT:    pxor %xmm6, %xmm5
+; SSE2OR3-NEXT:    pshufd {{.*#+}} xmm9 = xmm5[0,0,2,2]
+; SSE2OR3-NEXT:    pcmpgtd %xmm9, %xmm7
+; SSE2OR3-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3]
+; SSE2OR3-NEXT:    pcmpeqd %xmm6, %xmm5
+; SSE2OR3-NEXT:    pand %xmm7, %xmm5
+; SSE2OR3-NEXT:    pxor %xmm5, %xmm8
+; SSE2OR3-NEXT:    pand %xmm4, %xmm5
+; SSE2OR3-NEXT:    por %xmm8, %xmm5
+; SSE2OR3-NEXT:    shufps {{.*#+}} xmm5 = xmm5[0,2],xmm3[0,2]
+; SSE2OR3-NEXT:    orps %xmm2, %xmm5
+; SSE2OR3-NEXT:    psubusb %xmm5, %xmm1
 ; SSE2OR3-NEXT:    retq
 ;
 ; SSE41-LABEL: test34:
@@ -2982,29 +2975,30 @@ define <8 x i32> @test34(<8 x i32> %a0, <8 x i64> %a1) {
 ; SSE41-NEXT:    movapd %xmm8, %xmm3
 ; SSE41-NEXT:    blendvpd %xmm0, %xmm2, %xmm3
 ; SSE41-NEXT:    shufps {{.*#+}} xmm3 = xmm3[0,2],xmm10[0,2]
-; SSE41-NEXT:    pmaxud %xmm3, %xmm6
-; SSE41-NEXT:    psubd %xmm3, %xmm6
+; SSE41-NEXT:    movaps {{.*#+}} xmm2 = [4294967040,4294967040,4294967040,4294967040]
+; SSE41-NEXT:    orps %xmm2, %xmm3
+; SSE41-NEXT:    psubusb %xmm3, %xmm6
 ; SSE41-NEXT:    movdqa %xmm5, %xmm0
 ; SSE41-NEXT:    pxor %xmm7, %xmm0
-; SSE41-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[0,0,2,2]
-; SSE41-NEXT:    movdqa %xmm9, %xmm3
-; SSE41-NEXT:    pcmpgtd %xmm2, %xmm3
+; SSE41-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[0,0,2,2]
+; SSE41-NEXT:    movdqa %xmm9, %xmm10
+; SSE41-NEXT:    pcmpgtd %xmm3, %xmm10
 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
 ; SSE41-NEXT:    pcmpeqd %xmm7, %xmm0
-; SSE41-NEXT:    pand %xmm3, %xmm0
-; SSE41-NEXT:    movapd %xmm8, %xmm2
-; SSE41-NEXT:    blendvpd %xmm0, %xmm5, %xmm2
+; SSE41-NEXT:    pand %xmm10, %xmm0
+; SSE41-NEXT:    movapd %xmm8, %xmm3
+; SSE41-NEXT:    blendvpd %xmm0, %xmm5, %xmm3
 ; SSE41-NEXT:    movdqa %xmm4, %xmm0
 ; SSE41-NEXT:    pxor %xmm7, %xmm0
-; SSE41-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[0,0,2,2]
-; SSE41-NEXT:    pcmpgtd %xmm3, %xmm9
+; SSE41-NEXT:    pshufd {{.*#+}} xmm5 = xmm0[0,0,2,2]
+; SSE41-NEXT:    pcmpgtd %xmm5, %xmm9
 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
 ; SSE41-NEXT:    pcmpeqd %xmm7, %xmm0
 ; SSE41-NEXT:    pand %xmm9, %xmm0
 ; SSE41-NEXT:    blendvpd %xmm0, %xmm4, %xmm8
-; SSE41-NEXT:    shufps {{.*#+}} xmm8 = xmm8[0,2],xmm2[0,2]
-; SSE41-NEXT:    pmaxud %xmm8, %xmm1
-; SSE41-NEXT:    psubd %xmm8, %xmm1
+; SSE41-NEXT:    shufps {{.*#+}} xmm8 = xmm8[0,2],xmm3[0,2]
+; SSE41-NEXT:    orps %xmm2, %xmm8
+; SSE41-NEXT:    psubusb %xmm8, %xmm1
 ; SSE41-NEXT:    movdqa %xmm6, %xmm0
 ; SSE41-NEXT:    retq
 ;
@@ -3025,19 +3019,20 @@ define <8 x i32> @test34(<8 x i32> %a0, <8 x i64> %a1) {
 ; AVX1-NEXT:    vpcmpgtq %xmm5, %xmm6, %xmm5
 ; AVX1-NEXT:    vblendvpd %xmm5, %xmm2, %xmm7, %xmm2
 ; AVX1-NEXT:    vshufps {{.*#+}} xmm2 = xmm2[0,2],xmm3[0,2]
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
-; AVX1-NEXT:    vpmaxud %xmm2, %xmm3, %xmm3
-; AVX1-NEXT:    vpsubd %xmm2, %xmm3, %xmm2
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
-; AVX1-NEXT:    vpxor %xmm4, %xmm3, %xmm5
-; AVX1-NEXT:    vpcmpgtq %xmm5, %xmm6, %xmm5
-; AVX1-NEXT:    vblendvpd %xmm5, %xmm3, %xmm7, %xmm3
+; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm3 = [4294967040,4294967040,4294967040,4294967040]
+; AVX1-NEXT:    vorps %xmm3, %xmm2, %xmm2
+; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
+; AVX1-NEXT:    vpsubusb %xmm2, %xmm5, %xmm2
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm5
+; AVX1-NEXT:    vpxor %xmm4, %xmm5, %xmm8
+; AVX1-NEXT:    vpcmpgtq %xmm8, %xmm6, %xmm8
+; AVX1-NEXT:    vblendvpd %xmm8, %xmm5, %xmm7, %xmm5
 ; AVX1-NEXT:    vpxor %xmm4, %xmm1, %xmm4
 ; AVX1-NEXT:    vpcmpgtq %xmm4, %xmm6, %xmm4
 ; AVX1-NEXT:    vblendvpd %xmm4, %xmm1, %xmm7, %xmm1
-; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[0,2],xmm3[0,2]
-; AVX1-NEXT:    vpmaxud %xmm1, %xmm0, %xmm0
-; AVX1-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
+; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[0,2],xmm5[0,2]
+; AVX1-NEXT:    vorps %xmm3, %xmm1, %xmm1
+; AVX1-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
 ; AVX1-NEXT:    retq
 ;
@@ -3056,16 +3051,17 @@ define <8 x i32> @test34(<8 x i32> %a0, <8 x i64> %a1) {
 ; AVX2-NEXT:    vblendvpd %ymm3, %ymm1, %ymm6, %ymm1
 ; AVX2-NEXT:    vshufps {{.*#+}} ymm1 = ymm1[0,2],ymm2[0,2],ymm1[4,6],ymm2[4,6]
 ; AVX2-NEXT:    vpermpd {{.*#+}} ymm1 = ymm1[0,2,1,3]
-; AVX2-NEXT:    vpmaxud %ymm1, %ymm0, %ymm0
-; AVX2-NEXT:    vpsubd %ymm1, %ymm0, %ymm0
+; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm2 = [4294967040,4294967040,4294967040,4294967040,4294967040,4294967040,4294967040,4294967040]
+; AVX2-NEXT:    vorps %ymm2, %ymm1, %ymm1
+; AVX2-NEXT:    vpsubusb %ymm1, %ymm0, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test34:
 ; AVX512:       # %bb.0:
 ; AVX512-NEXT:    vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm0, %ymm0
 ; AVX512-NEXT:    vpmovusqd %zmm1, %ymm1
-; AVX512-NEXT:    vpmaxud %ymm1, %ymm0, %ymm0
-; AVX512-NEXT:    vpsubd %ymm1, %ymm0, %ymm0
+; AVX512-NEXT:    vpord {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm1, %ymm1
+; AVX512-NEXT:    vpsubusb %ymm1, %ymm0, %ymm0
 ; AVX512-NEXT:    retq
   %mask = and <8 x i32> %a0, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
   %zext = zext <8 x i32> %mask to <8 x i64>
diff --git a/llvm/test/CodeGen/X86/usubsat-narrow.ll b/llvm/test/CodeGen/X86/usubsat-narrow.ll
new file mode 100644
index 0000000000000..4ac6e1652b70a
--- /dev/null
+++ b/llvm/test/CodeGen/X86/usubsat-narrow.ll
@@ -0,0 +1,70 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+avx512vl | FileCheck %s
+
+declare <8 x i64> @llvm.usub.sat.v8i64(<8 x i64>, <8 x i64>)
+declare <4 x i64> @llvm.usub.sat.v4i64(<4 x i64>, <4 x i64>)
+declare <8 x i32> @llvm.usub.sat.v8i32(<8 x i32>, <8 x i32>)
+
+; v8i64 narrowed to v64i8 - LHS masked to 8 bits, should use vpsubusb
+define <8 x i64> @usubsat_v8i64_i8_narrow(<8 x i64> %x, <8 x i64> %y) nounwind {
+; CHECK-LABEL: usubsat_v8i64_i8_narrow:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vpandq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm0
+; CHECK-NEXT:    vporq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %zmm1
+; CHECK-NEXT:    vpsubusb %zmm1, %zmm0, %zmm0
+; CHECK-NEXT:    retq
+  %masked = and <8 x i64> %x, <i64 255, i64 255, i64 255, i64 255, i64 255, i64 255, i64 255, i64 255>
+  %z = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %masked, <8 x i64> %y)
+  ret <8 x i64> %z
+}
+
+; v4i64 narrowed to v32i8 - LHS masked to 8 bits, should use vpsubusb
+define <4 x i64> @usubsat_v4i64_i8_narrow(<4 x i64> %x, <4 x i64> %y) nounwind {
+; CHECK-LABEL: usubsat_v4i64_i8_narrow:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vpandq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm0, %ymm0
+; CHECK-NEXT:    vporq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm1, %ymm1
+; CHECK-NEXT:    vpsubusb %ymm1, %ymm0, %ymm0
+; CHECK-NEXT:    retq
+  %masked = and <4 x i64> %x, <i64 255, i64 255, i64 255, i64 255>
+  %z = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %masked, <4 x i64> %y)
+  ret <4 x i64> %z
+}
+
+; v8i32 narrowed to v32i8 - LHS masked to 8 bits, should use vpsubusb
+define <8 x i32> @usubsat_v8i32_i8_narrow(<8 x i32> %x, <8 x i32> %y) nounwind {
+; CHECK-LABEL: usubsat_v8i32_i8_narrow:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm0, %ymm0
+; CHECK-NEXT:    vpord {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm1, %ymm1
+; CHECK-NEXT:    vpsubusb %ymm1, %ymm0, %ymm0
+; CHECK-NEXT:    retq
+  %masked = and <8 x i32> %x, <i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255>
+  %z = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %masked, <8 x i32> %y)
+  ret <8 x i32> %z
+}
+
+; v8i32 narrowed to v16i16 - LHS masked to 16 bits, should use vpsubusw
+define <8 x i32> @usubsat_v8i32_i16_narrow(<8 x i32> %x, <8 x i32> %y) nounwind {
+; CHECK-LABEL: usubsat_v8i32_i16_narrow:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vpxor %xmm2, %xmm2, %xmm2
+; CHECK-NEXT:    vpblendw {{.*#+}} ymm0 = ymm0[0],ymm2[1],ymm0[2],ymm2[3],ymm0[4],ymm2[5],ymm0[6],ymm2[7],ymm0[8],ymm2[9],ymm0[10],ymm2[11],ymm0[12],ymm2[13],ymm0[14],ymm2[15]
+; CHECK-NEXT:    vpord {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm1, %ymm1
+; CHECK-NEXT:    vpsubusw %ymm1, %ymm0, %ymm0
+; CHECK-NEXT:    retq
+  %masked = and <8 x i32> %x, <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>
+  %z = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %masked, <8 x i32> %y)
+  ret <8 x i32> %z
+}
+
+; Negative test: LHS values may exceed 16 bits, should NOT narrow
+define <8 x i32> @usubsat_v8i32_no_narrow(<8 x i32> %x, <8 x i32> %y) nounwind {
+; CHECK-LABEL: usubsat_v8i32_no_narrow:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vpmaxud %ymm1, %ymm0, %ymm0
+; CHECK-NEXT:    vpsubd %ymm1, %ymm0, %ymm0
+; CHECK-NEXT:    retq
+  %z = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %x, <8 x i32> %y)
+  ret <8 x i32> %z
+}
diff --git a/llvm/test/CodeGen/X86/var-permute-128.ll b/llvm/test/CodeGen/X86/var-permute-128.ll
index dbfad9562d65a..0e7e6eaa873ae 100644
--- a/llvm/test/CodeGen/X86/var-permute-128.ll
+++ b/llvm/test/CodeGen/X86/var-permute-128.ll
@@ -492,9 +492,11 @@ define <8 x i16> @var_shuffle_v8i16(<8 x i16> %v, <8 x i16> %indices) nounwind {
 define <8 x i16> @var_shuffle_zero_v8i16(<8 x i16> %v, <8 x i16> %indices) nounwind {
 ; SSE3-LABEL: var_shuffle_zero_v8i16:
 ; SSE3:       # %bb.0:
-; SSE3-NEXT:    movdqa %xmm0, %xmm2
+; SSE3-NEXT:    movaps %xmm0, %xmm2
+; SSE3-NEXT:    movdqa {{.*#+}} xmm0 = [65280,65280,65280,65280,65280,65280,65280,65280]
+; SSE3-NEXT:    por %xmm1, %xmm0
 ; SSE3-NEXT:    movdqa {{.*#+}} xmm3 = [8,8,8,8,8,8,8,8]
-; SSE3-NEXT:    psubusw %xmm1, %xmm3
+; SSE3-NEXT:    psubusb %xmm0, %xmm3
 ; SSE3-NEXT:    pxor %xmm0, %xmm0
 ; SSE3-NEXT:    pcmpeqw %xmm3, %xmm0
 ; SSE3-NEXT:    por %xmm0, %xmm1
@@ -506,7 +508,7 @@ define <8 x i16> @var_shuffle_zero_v8i16(<8 x i16> %v, <8 x i16> %indices) nounw
 ; SSE3-NEXT:    pextrw $5, %xmm1, %r9d
 ; SSE3-NEXT:    pextrw $6, %xmm1, %r10d
 ; SSE3-NEXT:    pextrw $7, %xmm1, %esi
-; SSE3-NEXT:    movdqa %xmm2, -24(%rsp)
+; SSE3-NEXT:    movaps %xmm2, -24(%rsp)
 ; SSE3-NEXT:    andl $7, %eax
 ; SSE3-NEXT:    movzwl -24(%rsp,%rax,2), %eax
 ; SSE3-NEXT:    andl $7, %ecx
@@ -543,14 +545,16 @@ define <8 x i16> @var_shuffle_zero_v8i16(<8 x i16> %v, <8 x i16> %indices) nounw
 ;
 ; SSSE3-LABEL: var_shuffle_zero_v8i16:
 ; SSSE3:       # %bb.0:
-; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [8,8,8,8,8,8,8,8]
-; SSSE3-NEXT:    psubusw %xmm1, %xmm2
-; SSSE3-NEXT:    pxor %xmm3, %xmm3
-; SSSE3-NEXT:    pcmpeqw %xmm2, %xmm3
-; SSSE3-NEXT:    por %xmm3, %xmm1
+; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [65280,65280,65280,65280,65280,65280,65280,65280]
+; SSSE3-NEXT:    por %xmm1, %xmm2
+; SSSE3-NEXT:    movdqa {{.*#+}} xmm3 = [8,8,8,8,8,8,8,8]
+; SSSE3-NEXT:    psubusb %xmm2, %xmm3
+; SSSE3-NEXT:    pxor %xmm2, %xmm2
+; SSSE3-NEXT:    pcmpeqw %xmm3, %xmm2
+; SSSE3-NEXT:    por %xmm2, %xmm1
 ; SSSE3-NEXT:    pmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 # [514,514,514,514,514,514,514,514]
 ; SSSE3-NEXT:    paddw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 # [256,256,256,256,256,256,256,256]
-; SSSE3-NEXT:    por %xmm3, %xmm1
+; SSSE3-NEXT:    por %xmm2, %xmm1
 ; SSSE3-NEXT:    pshufb %xmm1, %xmm0
 ; SSSE3-NEXT:    retq
 ;
diff --git a/llvm/test/CodeGen/X86/vec_setcc-2.ll b/llvm/test/CodeGen/X86/vec_setcc-2.ll
index 5a71878ea4579..d19315e7ee612 100644
--- a/llvm/test/CodeGen/X86/vec_setcc-2.ll
+++ b/llvm/test/CodeGen/X86/vec_setcc-2.ll
@@ -195,7 +195,8 @@ define <8 x i1> @ugt_v8i16_splat(<8 x i16> %x) {
 ; SSE2-LABEL: ugt_v8i16_splat:
 ; SSE2:       ## %bb.0:
 ; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [243,243,243,243,243,243,243,243]
-; SSE2-NEXT:    psubusw %xmm0, %xmm1
+; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    psubusb %xmm0, %xmm1
 ; SSE2-NEXT:    pxor %xmm0, %xmm0
 ; SSE2-NEXT:    pcmpeqw %xmm1, %xmm0
 ; SSE2-NEXT:    retq
@@ -264,7 +265,8 @@ define <8 x i1> @uge_v8i16_splat(<8 x i16> %x) {
 ; SSE2-LABEL: uge_v8i16_splat:
 ; SSE2:       ## %bb.0:
 ; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [242,242,242,242,242,242,242,242]
-; SSE2-NEXT:    psubusw %xmm0, %xmm1
+; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    psubusb %xmm0, %xmm1
 ; SSE2-NEXT:    pxor %xmm0, %xmm0
 ; SSE2-NEXT:    pcmpeqw %xmm1, %xmm0
 ; SSE2-NEXT:    retq
@@ -531,8 +533,10 @@ define <4 x i1> @ugt_v4i32_splat_commute(<4 x i32> %x) {
 define <8 x i16> @PR39859(<8 x i16> %x, <8 x i16> %y) {
 ; SSE2-LABEL: PR39859:
 ; SSE2:       ## %bb.0:
+; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [65280,65280,65280,65280,65280,65280,65280,65280]
+; SSE2-NEXT:    por %xmm0, %xmm2
 ; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [43,43,43,43,43,43,43,43]
-; SSE2-NEXT:    psubusw %xmm0, %xmm3
+; SSE2-NEXT:    psubusb %xmm2, %xmm3
 ; SSE2-NEXT:    pxor %xmm2, %xmm2
 ; SSE2-NEXT:    pcmpeqw %xmm3, %xmm2
 ; SSE2-NEXT:    pand %xmm2, %xmm1
diff --git a/llvm/test/CodeGen/X86/vector-extract-last-active.ll b/llvm/test/CodeGen/X86/vector-extract-last-active.ll
index 3f0a0c587415e..8e11c65849839 100644
--- a/llvm/test/CodeGen/X86/vector-extract-last-active.ll
+++ b/llvm/test/CodeGen/X86/vector-extract-last-active.ll
@@ -158,14 +158,16 @@ define i32 @extract_last_active_v8i32(<8 x i32> %a, <8 x i1> %c) {
 ; CHECK-NEXT:    cmpb $1, %cl
 ; CHECK-NEXT:    sbbl %eax, %eax
 ; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3]
-; CHECK-NEXT:    psubusw %xmm2, %xmm0
-; CHECK-NEXT:    paddw %xmm2, %xmm0
-; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
-; CHECK-NEXT:    psubusw %xmm0, %xmm1
-; CHECK-NEXT:    paddw %xmm0, %xmm1
-; CHECK-NEXT:    pextrw $1, %xmm1, %ecx
-; CHECK-NEXT:    movd %xmm1, %edx
+; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [65280,65280,65280,65280,65280,65280,65280,65280]
+; CHECK-NEXT:    por %xmm2, %xmm0
+; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm2[2,3,2,3]
+; CHECK-NEXT:    psubusb %xmm0, %xmm1
+; CHECK-NEXT:    paddw %xmm2, %xmm1
+; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
+; CHECK-NEXT:    psubusw %xmm1, %xmm0
+; CHECK-NEXT:    paddw %xmm1, %xmm0
+; CHECK-NEXT:    pextrw $1, %xmm0, %ecx
+; CHECK-NEXT:    movd %xmm0, %edx
 ; CHECK-NEXT:    cmpw %cx, %dx
 ; CHECK-NEXT:    cmoval %edx, %ecx
 ; CHECK-NEXT:    andl $7, %ecx



More information about the llvm-commits mailing list