[llvm] [DAG] foldAddToAvg - add patterns to form avgceil(A, B) from ((A >> 1) + (B >> 1)) + ((A | B) & 1) (PR #174719)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 11 05:26:16 PST 2026


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

>From 7437ed2a28a950c2984e071eb32343de582ef970 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Wed, 7 Jan 2026 09:05:12 +0000
Subject: [PATCH] [DAG] foldAddToAvg - add patterns to form avgceil(A, B) from
 ((A >> 1) + (B >> 1)) + ((A | B) & 1)

Alive2 proof: https://alive2.llvm.org/ce/z/mcatXZ

Fixes #128377
---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |   16 +
 llvm/test/CodeGen/AArch64/avg.ll              |   28 +-
 llvm/test/CodeGen/PowerPC/vavg.ll             |  128 +-
 llvm/test/CodeGen/X86/avgceils.ll             | 1428 ++++++-----------
 llvm/test/CodeGen/X86/avgceilu.ll             | 1078 +++----------
 5 files changed, 784 insertions(+), 1894 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index ee28260a74127..280bdfcff0011 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -3164,6 +3164,7 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
 
 // Attempt to form avgfloor(A, B) from (A & B) + ((A ^ B) >> 1)
 // Attempt to form avgfloor(A, B) from ((A >> 1) + (B >> 1)) + (A & B & 1)
+// Attempt to form avgceil(A, B) from ((A >> 1) + (B >> 1)) + ((A | B) & 1)
 SDValue DAGCombiner::foldAddToAvg(SDNode *N, const SDLoc &DL) {
   SDValue N0 = N->getOperand(0);
   EVT VT = N0.getValueType();
@@ -3190,6 +3191,21 @@ SDValue DAGCombiner::foldAddToAvg(SDNode *N, const SDLoc &DL) {
     return DAG.getNode(ISD::AVGFLOORS, DL, VT, A, B);
   }
 
+  if ((!LegalOperations || hasOperation(ISD::AVGCEILU, VT)) &&
+      sd_match(N,
+               m_ReassociatableAdd(m_And(m_Or(m_Value(A), m_Value(B)), m_One()),
+                                   m_Srl(m_Deferred(A), m_One()),
+                                   m_Srl(m_Deferred(B), m_One())))) {
+    return DAG.getNode(ISD::AVGCEILU, DL, VT, A, B);
+  }
+  if ((!LegalOperations || hasOperation(ISD::AVGCEILS, VT)) &&
+      sd_match(N,
+               m_ReassociatableAdd(m_And(m_Or(m_Value(A), m_Value(B)), m_One()),
+                                   m_Sra(m_Deferred(A), m_One()),
+                                   m_Sra(m_Deferred(B), m_One())))) {
+    return DAG.getNode(ISD::AVGCEILS, DL, VT, A, B);
+  }
+
   return SDValue();
 }
 
diff --git a/llvm/test/CodeGen/AArch64/avg.ll b/llvm/test/CodeGen/AArch64/avg.ll
index 6792751b40f68..fbe8391ae45b5 100644
--- a/llvm/test/CodeGen/AArch64/avg.ll
+++ b/llvm/test/CodeGen/AArch64/avg.ll
@@ -193,12 +193,7 @@ define <8 x i16> @add_avgceilu2(<8 x i16> %a0, <8 x i16> %a1) {
 define <16 x i8> @lsb_avgceilu_v16i8(<16 x i8> %a, <16 x i8> %b) {
 ; CHECK-LABEL: lsb_avgceilu_v16i8:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    movi v2.16b, #1
-; CHECK-NEXT:    ushr v3.16b, v1.16b, #1
-; CHECK-NEXT:    orr v1.16b, v1.16b, v0.16b
-; CHECK-NEXT:    usra v3.16b, v0.16b, #1
-; CHECK-NEXT:    and v1.16b, v1.16b, v2.16b
-; CHECK-NEXT:    add v0.16b, v3.16b, v1.16b
+; CHECK-NEXT:    urhadd v0.16b, v1.16b, v0.16b
 ; CHECK-NEXT:    ret
   %a_shr_1 = lshr <16 x i8> %a, splat (i8 1)
   %b_shr_1 = lshr <16 x i8> %b, splat (i8 1)
@@ -212,12 +207,7 @@ define <16 x i8> @lsb_avgceilu_v16i8(<16 x i8> %a, <16 x i8> %b) {
 define <8 x i16> @lsb_avgceilu_v8i16(<8 x i16> %a, <8 x i16> %b) {
 ; CHECK-LABEL: lsb_avgceilu_v8i16:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    movi v2.8h, #1
-; CHECK-NEXT:    ushr v3.8h, v1.8h, #1
-; CHECK-NEXT:    orr v1.16b, v1.16b, v0.16b
-; CHECK-NEXT:    usra v3.8h, v0.8h, #1
-; CHECK-NEXT:    and v1.16b, v1.16b, v2.16b
-; CHECK-NEXT:    add v0.8h, v3.8h, v1.8h
+; CHECK-NEXT:    urhadd v0.8h, v1.8h, v0.8h
 ; CHECK-NEXT:    ret
   %a_shr_1 = lshr <8 x i16> %a, splat (i16 1)
   %b_shr_1 = lshr <8 x i16> %b, splat (i16 1)
@@ -324,12 +314,7 @@ define <8 x i16> @add_avgceils2(<8 x i16> %a0, <8 x i16> %a1) {
 define <16 x i8> @lsb_avgceils_v16i8(<16 x i8> %a, <16 x i8> %b) {
 ; CHECK-LABEL: lsb_avgceils_v16i8:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    movi v2.16b, #1
-; CHECK-NEXT:    sshr v3.16b, v1.16b, #1
-; CHECK-NEXT:    orr v1.16b, v1.16b, v0.16b
-; CHECK-NEXT:    ssra v3.16b, v0.16b, #1
-; CHECK-NEXT:    and v1.16b, v1.16b, v2.16b
-; CHECK-NEXT:    add v0.16b, v3.16b, v1.16b
+; CHECK-NEXT:    srhadd v0.16b, v1.16b, v0.16b
 ; CHECK-NEXT:    ret
   %a_shr_1 = ashr <16 x i8> %a, splat (i8 1)
   %b_shr_1 = ashr <16 x i8> %b, splat (i8 1)
@@ -343,12 +328,7 @@ define <16 x i8> @lsb_avgceils_v16i8(<16 x i8> %a, <16 x i8> %b) {
 define <8 x i16> @lsb_avgceils_v8i16(<8 x i16> %a, <8 x i16> %b) {
 ; CHECK-LABEL: lsb_avgceils_v8i16:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    movi v2.8h, #1
-; CHECK-NEXT:    sshr v3.8h, v1.8h, #1
-; CHECK-NEXT:    orr v1.16b, v1.16b, v0.16b
-; CHECK-NEXT:    ssra v3.8h, v0.8h, #1
-; CHECK-NEXT:    and v1.16b, v1.16b, v2.16b
-; CHECK-NEXT:    add v0.8h, v3.8h, v1.8h
+; CHECK-NEXT:    srhadd v0.8h, v1.8h, v0.8h
 ; CHECK-NEXT:    ret
   %a_shr_1 = ashr <8 x i16> %a, splat (i16 1)
   %b_shr_1 = ashr <8 x i16> %b, splat (i16 1)
diff --git a/llvm/test/CodeGen/PowerPC/vavg.ll b/llvm/test/CodeGen/PowerPC/vavg.ll
index 9a8de8d82a323..31a876116523b 100644
--- a/llvm/test/CodeGen/PowerPC/vavg.ll
+++ b/llvm/test/CodeGen/PowerPC/vavg.ll
@@ -244,35 +244,29 @@ entry:
 define <16 x i8> @test_avgceilu_v16i8(<16 x i8> %a, <16 x i8> %b) {
 ; CHECK-P9-LABEL: test_avgceilu_v16i8:
 ; CHECK-P9:       # %bb.0:
-; CHECK-P9-NEXT:    xxspltib 36, 1
-; CHECK-P9-NEXT:    xxlor 0, 35, 34
-; CHECK-P9-NEXT:    vsrb 5, 2, 4
-; CHECK-P9-NEXT:    vsrb 0, 3, 4
-; CHECK-P9-NEXT:    xxland 34, 0, 36
-; CHECK-P9-NEXT:    vaddubm 3, 0, 5
-; CHECK-P9-NEXT:    vaddubm 2, 3, 2
+; CHECK-P9-NEXT:    xxlor 36, 35, 34
+; CHECK-P9-NEXT:    xxlxor 34, 35, 34
+; CHECK-P9-NEXT:    xxspltib 35, 1
+; CHECK-P9-NEXT:    vsrb 2, 2, 3
+; CHECK-P9-NEXT:    vsububm 2, 4, 2
 ; CHECK-P9-NEXT:    blr
 ;
 ; CHECK-P8-LABEL: test_avgceilu_v16i8:
 ; CHECK-P8:       # %bb.0:
 ; CHECK-P8-NEXT:    vspltisb 4, 1
-; CHECK-P8-NEXT:    xxlor 0, 35, 34
-; CHECK-P8-NEXT:    vsrb 5, 2, 4
-; CHECK-P8-NEXT:    vsrb 0, 3, 4
-; CHECK-P8-NEXT:    xxland 34, 0, 36
-; CHECK-P8-NEXT:    vaddubm 3, 0, 5
-; CHECK-P8-NEXT:    vaddubm 2, 3, 2
+; CHECK-P8-NEXT:    xxlor 37, 35, 34
+; CHECK-P8-NEXT:    xxlxor 34, 35, 34
+; CHECK-P8-NEXT:    vsrb 2, 2, 4
+; CHECK-P8-NEXT:    vsububm 2, 5, 2
 ; CHECK-P8-NEXT:    blr
 ;
 ; CHECK-P7-LABEL: test_avgceilu_v16i8:
 ; CHECK-P7:       # %bb.0:
 ; CHECK-P7-NEXT:    vspltisb 4, 1
-; CHECK-P7-NEXT:    xxlor 0, 35, 34
-; CHECK-P7-NEXT:    vsrb 5, 2, 4
-; CHECK-P7-NEXT:    vsrb 0, 3, 4
-; CHECK-P7-NEXT:    xxland 34, 0, 36
-; CHECK-P7-NEXT:    vaddubm 3, 0, 5
-; CHECK-P7-NEXT:    vaddubm 2, 3, 2
+; CHECK-P7-NEXT:    xxlor 37, 35, 34
+; CHECK-P7-NEXT:    xxlxor 34, 35, 34
+; CHECK-P7-NEXT:    vsrb 2, 2, 4
+; CHECK-P7-NEXT:    vsububm 2, 5, 2
 ; CHECK-P7-NEXT:    blr
   %a_shr_1 = lshr <16 x i8> %a, splat (i8 1)
   %b_shr_1 = lshr <16 x i8> %b, splat (i8 1)
@@ -286,35 +280,29 @@ define <16 x i8> @test_avgceilu_v16i8(<16 x i8> %a, <16 x i8> %b) {
 define <8 x i16> @test_avgceilu_v8i16(<8 x i16> %a, <8 x i16> %b) {
 ; CHECK-P9-LABEL: test_avgceilu_v8i16:
 ; CHECK-P9:       # %bb.0:
-; CHECK-P9-NEXT:    vspltish 4, 1
-; CHECK-P9-NEXT:    xxlor 0, 35, 34
-; CHECK-P9-NEXT:    vsrh 5, 2, 4
-; CHECK-P9-NEXT:    vsrh 0, 3, 4
-; CHECK-P9-NEXT:    xxland 34, 0, 36
-; CHECK-P9-NEXT:    vadduhm 3, 0, 5
-; CHECK-P9-NEXT:    vadduhm 2, 3, 2
+; CHECK-P9-NEXT:    xxlor 36, 35, 34
+; CHECK-P9-NEXT:    xxlxor 34, 35, 34
+; CHECK-P9-NEXT:    vspltish 3, 1
+; CHECK-P9-NEXT:    vsrh 2, 2, 3
+; CHECK-P9-NEXT:    vsubuhm 2, 4, 2
 ; CHECK-P9-NEXT:    blr
 ;
 ; CHECK-P8-LABEL: test_avgceilu_v8i16:
 ; CHECK-P8:       # %bb.0:
 ; CHECK-P8-NEXT:    vspltish 4, 1
-; CHECK-P8-NEXT:    xxlor 0, 35, 34
-; CHECK-P8-NEXT:    vsrh 5, 2, 4
-; CHECK-P8-NEXT:    vsrh 0, 3, 4
-; CHECK-P8-NEXT:    xxland 34, 0, 36
-; CHECK-P8-NEXT:    vadduhm 3, 0, 5
-; CHECK-P8-NEXT:    vadduhm 2, 3, 2
+; CHECK-P8-NEXT:    xxlor 37, 35, 34
+; CHECK-P8-NEXT:    xxlxor 34, 35, 34
+; CHECK-P8-NEXT:    vsrh 2, 2, 4
+; CHECK-P8-NEXT:    vsubuhm 2, 5, 2
 ; CHECK-P8-NEXT:    blr
 ;
 ; CHECK-P7-LABEL: test_avgceilu_v8i16:
 ; CHECK-P7:       # %bb.0:
 ; CHECK-P7-NEXT:    vspltish 4, 1
-; CHECK-P7-NEXT:    xxlor 0, 35, 34
-; CHECK-P7-NEXT:    vsrh 5, 2, 4
-; CHECK-P7-NEXT:    vsrh 0, 3, 4
-; CHECK-P7-NEXT:    xxland 34, 0, 36
-; CHECK-P7-NEXT:    vadduhm 3, 0, 5
-; CHECK-P7-NEXT:    vadduhm 2, 3, 2
+; CHECK-P7-NEXT:    xxlor 37, 35, 34
+; CHECK-P7-NEXT:    xxlxor 34, 35, 34
+; CHECK-P7-NEXT:    vsrh 2, 2, 4
+; CHECK-P7-NEXT:    vsubuhm 2, 5, 2
 ; CHECK-P7-NEXT:    blr
   %a_shr_1 = lshr <8 x i16> %a, splat (i16 1)
   %b_shr_1 = lshr <8 x i16> %b, splat (i16 1)
@@ -328,35 +316,29 @@ define <8 x i16> @test_avgceilu_v8i16(<8 x i16> %a, <8 x i16> %b) {
 define <16 x i8> @test_avgceils_v16i8(<16 x i8> %a, <16 x i8> %b) {
 ; CHECK-P9-LABEL: test_avgceils_v16i8:
 ; CHECK-P9:       # %bb.0:
-; CHECK-P9-NEXT:    xxspltib 36, 1
-; CHECK-P9-NEXT:    xxlor 0, 35, 34
-; CHECK-P9-NEXT:    vsrab 5, 2, 4
-; CHECK-P9-NEXT:    vsrab 0, 3, 4
-; CHECK-P9-NEXT:    xxland 34, 0, 36
-; CHECK-P9-NEXT:    vaddubm 3, 0, 5
-; CHECK-P9-NEXT:    vaddubm 2, 3, 2
+; CHECK-P9-NEXT:    xxlor 36, 35, 34
+; CHECK-P9-NEXT:    xxlxor 34, 35, 34
+; CHECK-P9-NEXT:    xxspltib 35, 1
+; CHECK-P9-NEXT:    vsrab 2, 2, 3
+; CHECK-P9-NEXT:    vsububm 2, 4, 2
 ; CHECK-P9-NEXT:    blr
 ;
 ; CHECK-P8-LABEL: test_avgceils_v16i8:
 ; CHECK-P8:       # %bb.0:
 ; CHECK-P8-NEXT:    vspltisb 4, 1
-; CHECK-P8-NEXT:    xxlor 0, 35, 34
-; CHECK-P8-NEXT:    vsrab 5, 2, 4
-; CHECK-P8-NEXT:    vsrab 0, 3, 4
-; CHECK-P8-NEXT:    xxland 34, 0, 36
-; CHECK-P8-NEXT:    vaddubm 3, 0, 5
-; CHECK-P8-NEXT:    vaddubm 2, 3, 2
+; CHECK-P8-NEXT:    xxlor 37, 35, 34
+; CHECK-P8-NEXT:    xxlxor 34, 35, 34
+; CHECK-P8-NEXT:    vsrab 2, 2, 4
+; CHECK-P8-NEXT:    vsububm 2, 5, 2
 ; CHECK-P8-NEXT:    blr
 ;
 ; CHECK-P7-LABEL: test_avgceils_v16i8:
 ; CHECK-P7:       # %bb.0:
 ; CHECK-P7-NEXT:    vspltisb 4, 1
-; CHECK-P7-NEXT:    xxlor 0, 35, 34
-; CHECK-P7-NEXT:    vsrab 5, 2, 4
-; CHECK-P7-NEXT:    vsrab 0, 3, 4
-; CHECK-P7-NEXT:    xxland 34, 0, 36
-; CHECK-P7-NEXT:    vaddubm 3, 0, 5
-; CHECK-P7-NEXT:    vaddubm 2, 3, 2
+; CHECK-P7-NEXT:    xxlor 37, 35, 34
+; CHECK-P7-NEXT:    xxlxor 34, 35, 34
+; CHECK-P7-NEXT:    vsrab 2, 2, 4
+; CHECK-P7-NEXT:    vsububm 2, 5, 2
 ; CHECK-P7-NEXT:    blr
   %a_shr_1 = ashr <16 x i8> %a, splat (i8 1)
   %b_shr_1 = ashr <16 x i8> %b, splat (i8 1)
@@ -370,35 +352,29 @@ define <16 x i8> @test_avgceils_v16i8(<16 x i8> %a, <16 x i8> %b) {
 define <8 x i16> @test_avgceils_v8i16(<8 x i16> %a, <8 x i16> %b) {
 ; CHECK-P9-LABEL: test_avgceils_v8i16:
 ; CHECK-P9:       # %bb.0:
-; CHECK-P9-NEXT:    vspltish 4, 1
-; CHECK-P9-NEXT:    xxlor 0, 35, 34
-; CHECK-P9-NEXT:    vsrah 5, 2, 4
-; CHECK-P9-NEXT:    vsrah 0, 3, 4
-; CHECK-P9-NEXT:    xxland 34, 0, 36
-; CHECK-P9-NEXT:    vadduhm 3, 0, 5
-; CHECK-P9-NEXT:    vadduhm 2, 3, 2
+; CHECK-P9-NEXT:    xxlor 36, 35, 34
+; CHECK-P9-NEXT:    xxlxor 34, 35, 34
+; CHECK-P9-NEXT:    vspltish 3, 1
+; CHECK-P9-NEXT:    vsrah 2, 2, 3
+; CHECK-P9-NEXT:    vsubuhm 2, 4, 2
 ; CHECK-P9-NEXT:    blr
 ;
 ; CHECK-P8-LABEL: test_avgceils_v8i16:
 ; CHECK-P8:       # %bb.0:
 ; CHECK-P8-NEXT:    vspltish 4, 1
-; CHECK-P8-NEXT:    xxlor 0, 35, 34
-; CHECK-P8-NEXT:    vsrah 5, 2, 4
-; CHECK-P8-NEXT:    vsrah 0, 3, 4
-; CHECK-P8-NEXT:    xxland 34, 0, 36
-; CHECK-P8-NEXT:    vadduhm 3, 0, 5
-; CHECK-P8-NEXT:    vadduhm 2, 3, 2
+; CHECK-P8-NEXT:    xxlor 37, 35, 34
+; CHECK-P8-NEXT:    xxlxor 34, 35, 34
+; CHECK-P8-NEXT:    vsrah 2, 2, 4
+; CHECK-P8-NEXT:    vsubuhm 2, 5, 2
 ; CHECK-P8-NEXT:    blr
 ;
 ; CHECK-P7-LABEL: test_avgceils_v8i16:
 ; CHECK-P7:       # %bb.0:
 ; CHECK-P7-NEXT:    vspltish 4, 1
-; CHECK-P7-NEXT:    xxlor 0, 35, 34
-; CHECK-P7-NEXT:    vsrah 5, 2, 4
-; CHECK-P7-NEXT:    vsrah 0, 3, 4
-; CHECK-P7-NEXT:    xxland 34, 0, 36
-; CHECK-P7-NEXT:    vadduhm 3, 0, 5
-; CHECK-P7-NEXT:    vadduhm 2, 3, 2
+; CHECK-P7-NEXT:    xxlor 37, 35, 34
+; CHECK-P7-NEXT:    xxlxor 34, 35, 34
+; CHECK-P7-NEXT:    vsrah 2, 2, 4
+; CHECK-P7-NEXT:    vsubuhm 2, 5, 2
 ; CHECK-P7-NEXT:    blr
   %a_shr_1 = ashr <8 x i16> %a, splat (i16 1)
   %b_shr_1 = ashr <8 x i16> %b, splat (i16 1)
diff --git a/llvm/test/CodeGen/X86/avgceils.ll b/llvm/test/CodeGen/X86/avgceils.ll
index 8c58b937d59e6..7b17286ae7570 100644
--- a/llvm/test/CodeGen/X86/avgceils.ll
+++ b/llvm/test/CodeGen/X86/avgceils.ll
@@ -100,68 +100,38 @@ define <16 x i8> @test_ext_v16i8(<16 x i8> %a0, <16 x i8> %a1) nounwind {
 define <16 x i8> @test_lsb_v16i8(<16 x i8> %a, <16 x i8> %b) {
 ; SSE-LABEL: test_lsb_v16i8:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm2
-; SSE-NEXT:    psrlw $1, %xmm2
-; SSE-NEXT:    movdqa {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; SSE-NEXT:    pand %xmm3, %xmm2
-; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; SSE-NEXT:    pxor %xmm4, %xmm2
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    psrlw $1, %xmm1
-; SSE-NEXT:    pand %xmm3, %xmm1
-; SSE-NEXT:    pxor %xmm4, %xmm1
-; SSE-NEXT:    paddb %xmm2, %xmm1
-; SSE-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    paddb %xmm1, %xmm0
-; SSE-NEXT:    psubb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; SSE-NEXT:    pxor %xmm2, %xmm0
+; SSE-NEXT:    pxor %xmm2, %xmm1
+; SSE-NEXT:    pavgb %xmm1, %xmm0
+; SSE-NEXT:    pxor %xmm2, %xmm0
 ; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v16i8:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm2
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX1-NEXT:    vpand %xmm3, %xmm2, %xmm2
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; AVX1-NEXT:    vpxor %xmm4, %xmm2, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm1, %xmm5
-; AVX1-NEXT:    vpand %xmm3, %xmm5, %xmm3
-; AVX1-NEXT:    vpxor %xmm4, %xmm3, %xmm3
-; AVX1-NEXT:    vpaddb %xmm3, %xmm2, %xmm2
-; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX1-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX1-NEXT:    vpaddb %xmm0, %xmm2, %xmm0
-; AVX1-NEXT:    vpsubb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX1-NEXT:    vpxor %xmm2, %xmm0, %xmm0
+; AVX1-NEXT:    vpxor %xmm2, %xmm1, %xmm1
+; AVX1-NEXT:    vpavgb %xmm0, %xmm1, %xmm0
+; AVX1-NEXT:    vpxor %xmm2, %xmm0, %xmm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v16i8:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlw $1, %xmm0, %xmm2
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX2-NEXT:    vpand %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; AVX2-NEXT:    vpxor %xmm4, %xmm2, %xmm2
-; AVX2-NEXT:    vpsrlw $1, %xmm1, %xmm5
-; AVX2-NEXT:    vpand %xmm3, %xmm5, %xmm3
-; AVX2-NEXT:    vpxor %xmm4, %xmm3, %xmm3
-; AVX2-NEXT:    vpaddb %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX2-NEXT:    vpaddb %xmm0, %xmm2, %xmm0
-; AVX2-NEXT:    vpsubb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX2-NEXT:    vpbroadcastb {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX2-NEXT:    vpxor %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vpxor %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vpavgb %xmm0, %xmm1, %xmm0
+; AVX2-NEXT:    vpxor %xmm2, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v16i8:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX512-NEXT:    vpsrlw $1, %xmm0, %xmm3
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; AVX512-NEXT:    vpternlogq {{.*#+}} xmm3 = xmm4 ^ (xmm3 & xmm2)
-; AVX512-NEXT:    vpsrlw $1, %xmm1, %xmm5
-; AVX512-NEXT:    vpternlogq {{.*#+}} xmm5 = xmm4 ^ (xmm5 & xmm2)
-; AVX512-NEXT:    vpaddb %xmm5, %xmm3, %xmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = m32bcst & (xmm0 | xmm1)
-; AVX512-NEXT:    vpaddb %xmm0, %xmm2, %xmm0
-; AVX512-NEXT:    vpsubb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX512-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX512-NEXT:    vpxor %xmm2, %xmm0, %xmm0
+; AVX512-NEXT:    vpxor %xmm2, %xmm1, %xmm1
+; AVX512-NEXT:    vpavgb %xmm0, %xmm1, %xmm0
+; AVX512-NEXT:    vpxor %xmm2, %xmm0, %xmm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = ashr <16 x i8> %a, splat (i8 1)
   %b_shr_1 = ashr <16 x i8> %b, splat (i8 1)
@@ -227,43 +197,21 @@ define <8 x i16> @test_ext_v8i16(<8 x i16> %a0, <8 x i16> %a1) nounwind {
 define <8 x i16> @test_lsb_v8i16(<8 x i16> %a, <8 x i16> %b) {
 ; SSE-LABEL: test_lsb_v8i16:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm2
-; SSE-NEXT:    psraw $1, %xmm2
-; SSE-NEXT:    por %xmm1, %xmm0
+; SSE-NEXT:    movdqa %xmm1, %xmm2
+; SSE-NEXT:    por %xmm0, %xmm2
+; SSE-NEXT:    pxor %xmm0, %xmm1
 ; SSE-NEXT:    psraw $1, %xmm1
-; SSE-NEXT:    paddw %xmm2, %xmm1
-; SSE-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    paddw %xmm1, %xmm0
+; SSE-NEXT:    psubw %xmm1, %xmm2
+; SSE-NEXT:    movdqa %xmm2, %xmm0
 ; SSE-NEXT:    retq
 ;
-; AVX1-LABEL: test_lsb_v8i16:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vpsraw $1, %xmm0, %xmm2
-; AVX1-NEXT:    vpsraw $1, %xmm1, %xmm3
-; AVX1-NEXT:    vpaddw %xmm2, %xmm3, %xmm2
-; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX1-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX1-NEXT:    vpaddw %xmm0, %xmm2, %xmm0
-; AVX1-NEXT:    retq
-;
-; AVX2-LABEL: test_lsb_v8i16:
-; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsraw $1, %xmm0, %xmm2
-; AVX2-NEXT:    vpsraw $1, %xmm1, %xmm3
-; AVX2-NEXT:    vpaddw %xmm2, %xmm3, %xmm2
-; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX2-NEXT:    vpaddw %xmm0, %xmm2, %xmm0
-; AVX2-NEXT:    retq
-;
-; AVX512-LABEL: test_lsb_v8i16:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsraw $1, %xmm0, %xmm2
-; AVX512-NEXT:    vpsraw $1, %xmm1, %xmm3
-; AVX512-NEXT:    vpaddw %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = m32bcst & (xmm0 | xmm1)
-; AVX512-NEXT:    vpaddw %xmm0, %xmm2, %xmm0
-; AVX512-NEXT:    retq
+; AVX-LABEL: test_lsb_v8i16:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm2
+; AVX-NEXT:    vpxor %xmm0, %xmm1, %xmm0
+; AVX-NEXT:    vpsraw $1, %xmm0, %xmm0
+; AVX-NEXT:    vpsubw %xmm0, %xmm2, %xmm0
+; AVX-NEXT:    retq
   %a_shr_1 = ashr <8 x i16> %a, splat (i16 1)
   %b_shr_1 = ashr <8 x i16> %b, splat (i16 1)
   %a_or_b = or <8 x i16> %b, %a
@@ -328,44 +276,21 @@ define <4 x i32> @test_ext_v4i32(<4 x i32> %a0, <4 x i32> %a1) nounwind {
 define <4 x i32> @test_lsb_v4i32(<4 x i32> %a, <4 x i32> %b) {
 ; SSE-LABEL: test_lsb_v4i32:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm2
-; SSE-NEXT:    psrad $1, %xmm2
-; SSE-NEXT:    por %xmm1, %xmm0
+; SSE-NEXT:    movdqa %xmm1, %xmm2
+; SSE-NEXT:    por %xmm0, %xmm2
+; SSE-NEXT:    pxor %xmm0, %xmm1
 ; SSE-NEXT:    psrad $1, %xmm1
-; SSE-NEXT:    paddd %xmm2, %xmm1
-; SSE-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    paddd %xmm1, %xmm0
+; SSE-NEXT:    psubd %xmm1, %xmm2
+; SSE-NEXT:    movdqa %xmm2, %xmm0
 ; SSE-NEXT:    retq
 ;
-; AVX1-LABEL: test_lsb_v4i32:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vpsrad $1, %xmm0, %xmm2
-; AVX1-NEXT:    vpsrad $1, %xmm1, %xmm3
-; AVX1-NEXT:    vpaddd %xmm2, %xmm3, %xmm2
-; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX1-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX1-NEXT:    vpaddd %xmm0, %xmm2, %xmm0
-; AVX1-NEXT:    retq
-;
-; AVX2-LABEL: test_lsb_v4i32:
-; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrad $1, %xmm0, %xmm2
-; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm3 = [1,1,1,1]
-; AVX2-NEXT:    vpsrad $1, %xmm1, %xmm4
-; AVX2-NEXT:    vpaddd %xmm2, %xmm4, %xmm2
-; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX2-NEXT:    vpand %xmm3, %xmm0, %xmm0
-; AVX2-NEXT:    vpaddd %xmm0, %xmm2, %xmm0
-; AVX2-NEXT:    retq
-;
-; AVX512-LABEL: test_lsb_v4i32:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrad $1, %xmm0, %xmm2
-; AVX512-NEXT:    vpsrad $1, %xmm1, %xmm3
-; AVX512-NEXT:    vpaddd %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = m32bcst & (xmm0 | xmm1)
-; AVX512-NEXT:    vpaddd %xmm0, %xmm2, %xmm0
-; AVX512-NEXT:    retq
+; AVX-LABEL: test_lsb_v4i32:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm2
+; AVX-NEXT:    vpxor %xmm0, %xmm1, %xmm0
+; AVX-NEXT:    vpsrad $1, %xmm0, %xmm0
+; AVX-NEXT:    vpsubd %xmm0, %xmm2, %xmm0
+; AVX-NEXT:    retq
   %a_shr_1 = ashr <4 x i32> %a, splat (i32 1)
   %b_shr_1 = ashr <4 x i32> %b, splat (i32 1)
   %a_or_b = or <4 x i32> %b, %a
@@ -500,75 +425,55 @@ define <2 x i64> @test_ext_v2i64(<2 x i64> %a0, <2 x i64> %a1) nounwind {
 define <2 x i64> @test_lsb_v2i64(<2 x i64> %a, <2 x i64> %b) {
 ; SSE2-LABEL: test_lsb_v2i64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm2
-; SSE2-NEXT:    movdqa %xmm0, %xmm3
-; SSE2-NEXT:    psrlq $1, %xmm3
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm2
+; SSE2-NEXT:    movdqa %xmm1, %xmm2
+; SSE2-NEXT:    pxor %xmm0, %xmm2
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[1,3,2,3]
+; SSE2-NEXT:    psrad $1, %xmm3
+; SSE2-NEXT:    psrlq $1, %xmm2
+; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
 ; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    psrlq $1, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
-; SSE2-NEXT:    paddq %xmm3, %xmm1
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    paddq %xmm1, %xmm0
+; SSE2-NEXT:    psubq %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE4-LABEL: test_lsb_v2i64:
 ; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm2
-; SSE4-NEXT:    psrad $1, %xmm2
-; SSE4-NEXT:    movdqa %xmm0, %xmm3
-; SSE4-NEXT:    psrlq $1, %xmm3
-; SSE4-NEXT:    pblendw {{.*#+}} xmm3 = xmm3[0,1],xmm2[2,3],xmm3[4,5],xmm2[6,7]
 ; SSE4-NEXT:    movdqa %xmm1, %xmm2
-; SSE4-NEXT:    por %xmm1, %xmm0
-; SSE4-NEXT:    psrad $1, %xmm1
+; SSE4-NEXT:    pxor %xmm0, %xmm2
+; SSE4-NEXT:    movdqa %xmm2, %xmm3
+; SSE4-NEXT:    psrad $1, %xmm3
 ; SSE4-NEXT:    psrlq $1, %xmm2
-; SSE4-NEXT:    pblendw {{.*#+}} xmm2 = xmm2[0,1],xmm1[2,3],xmm2[4,5],xmm1[6,7]
-; SSE4-NEXT:    paddq %xmm3, %xmm2
-; SSE4-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE4-NEXT:    paddq %xmm2, %xmm0
+; SSE4-NEXT:    pblendw {{.*#+}} xmm2 = xmm2[0,1],xmm3[2,3],xmm2[4,5],xmm3[6,7]
+; SSE4-NEXT:    por %xmm1, %xmm0
+; SSE4-NEXT:    psubq %xmm2, %xmm0
 ; SSE4-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v2i64:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vpsrad $1, %xmm0, %xmm2
-; AVX1-NEXT:    vpsrlq $1, %xmm0, %xmm3
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1],xmm2[2,3],xmm3[4,5],xmm2[6,7]
-; AVX1-NEXT:    vpsrad $1, %xmm1, %xmm3
-; AVX1-NEXT:    vpsrlq $1, %xmm1, %xmm4
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm3 = xmm4[0,1],xmm3[2,3],xmm4[4,5],xmm3[6,7]
-; AVX1-NEXT:    vpaddq %xmm2, %xmm3, %xmm2
+; AVX1-NEXT:    vpxor %xmm0, %xmm1, %xmm2
+; AVX1-NEXT:    vpsrad $1, %xmm2, %xmm3
+; AVX1-NEXT:    vpsrlq $1, %xmm2, %xmm2
+; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm2[0,1],xmm3[2,3],xmm2[4,5],xmm3[6,7]
 ; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX1-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX1-NEXT:    vpaddq %xmm0, %xmm2, %xmm0
+; AVX1-NEXT:    vpsubq %xmm2, %xmm0, %xmm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v2i64:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrad $1, %xmm0, %xmm2
-; AVX2-NEXT:    vpsrlq $1, %xmm0, %xmm3
-; AVX2-NEXT:    vpblendd {{.*#+}} xmm2 = xmm3[0],xmm2[1],xmm3[2],xmm2[3]
-; AVX2-NEXT:    vpsrad $1, %xmm1, %xmm3
-; AVX2-NEXT:    vpsrlq $1, %xmm1, %xmm4
-; AVX2-NEXT:    vpblendd {{.*#+}} xmm3 = xmm4[0],xmm3[1],xmm4[2],xmm3[3]
-; AVX2-NEXT:    vpaddq %xmm2, %xmm3, %xmm2
+; AVX2-NEXT:    vpxor %xmm0, %xmm1, %xmm2
+; AVX2-NEXT:    vpsrad $1, %xmm2, %xmm3
+; AVX2-NEXT:    vpsrlq $1, %xmm2, %xmm2
+; AVX2-NEXT:    vpblendd {{.*#+}} xmm2 = xmm2[0],xmm3[1],xmm2[2],xmm3[3]
 ; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX2-NEXT:    vpaddq %xmm0, %xmm2, %xmm0
+; AVX2-NEXT:    vpsubq %xmm2, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v2i64:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsraq $1, %xmm0, %xmm2
-; AVX512-NEXT:    vpsraq $1, %xmm1, %xmm3
-; AVX512-NEXT:    vpaddq %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vpternlogq {{.*#+}} xmm0 = m64bcst & (xmm0 | xmm1)
-; AVX512-NEXT:    vpaddq %xmm0, %xmm2, %xmm0
+; AVX512-NEXT:    vpor %xmm0, %xmm1, %xmm2
+; AVX512-NEXT:    vpxor %xmm0, %xmm1, %xmm0
+; AVX512-NEXT:    vpsraq $1, %xmm0, %xmm0
+; AVX512-NEXT:    vpsubq %xmm0, %xmm2, %xmm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = ashr <2 x i64> %a, splat (i64 1)
   %b_shr_1 = ashr <2 x i64> %b, splat (i64 1)
@@ -690,96 +595,46 @@ define <32 x i8> @test_ext_v32i8(<32 x i8> %a0, <32 x i8> %a1) nounwind {
 define <32 x i8> @test_lsb_v32i8(<32 x i8> %a, <32 x i8> %b) {
 ; SSE-LABEL: test_lsb_v32i8:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm6
-; SSE-NEXT:    psrlw $1, %xmm6
-; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; SSE-NEXT:    pand %xmm4, %xmm6
-; SSE-NEXT:    movdqa {{.*#+}} xmm5 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; SSE-NEXT:    pxor %xmm5, %xmm6
-; SSE-NEXT:    movdqa %xmm1, %xmm7
-; SSE-NEXT:    psrlw $1, %xmm7
-; SSE-NEXT:    pand %xmm4, %xmm7
-; SSE-NEXT:    pxor %xmm5, %xmm7
-; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; SSE-NEXT:    por %xmm2, %xmm0
-; SSE-NEXT:    psrlw $1, %xmm2
-; SSE-NEXT:    pand %xmm4, %xmm2
-; SSE-NEXT:    pxor %xmm5, %xmm2
-; SSE-NEXT:    paddb %xmm6, %xmm2
-; SSE-NEXT:    por %xmm3, %xmm1
-; SSE-NEXT:    psrlw $1, %xmm3
-; SSE-NEXT:    pand %xmm4, %xmm3
-; SSE-NEXT:    pxor %xmm5, %xmm3
-; SSE-NEXT:    paddb %xmm7, %xmm3
-; SSE-NEXT:    pand %xmm8, %xmm1
-; SSE-NEXT:    paddb %xmm3, %xmm1
-; SSE-NEXT:    pand %xmm8, %xmm0
-; SSE-NEXT:    paddb %xmm2, %xmm0
-; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
-; SSE-NEXT:    psubb %xmm2, %xmm0
-; SSE-NEXT:    psubb %xmm2, %xmm1
+; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; SSE-NEXT:    pxor %xmm4, %xmm0
+; SSE-NEXT:    pxor %xmm4, %xmm2
+; SSE-NEXT:    pavgb %xmm2, %xmm0
+; SSE-NEXT:    pxor %xmm4, %xmm0
+; SSE-NEXT:    pxor %xmm4, %xmm1
+; SSE-NEXT:    pxor %xmm4, %xmm3
+; SSE-NEXT:    pavgb %xmm3, %xmm1
+; SSE-NEXT:    pxor %xmm4, %xmm1
 ; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v32i8:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm2, %xmm2
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX1-NEXT:    vpand %xmm3, %xmm2, %xmm2
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; AVX1-NEXT:    vpxor %xmm4, %xmm2, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm5
-; AVX1-NEXT:    vpand %xmm3, %xmm5, %xmm5
-; AVX1-NEXT:    vpxor %xmm4, %xmm5, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm6
-; AVX1-NEXT:    vpsrlw $1, %xmm6, %xmm6
-; AVX1-NEXT:    vpand %xmm3, %xmm6, %xmm6
-; AVX1-NEXT:    vpxor %xmm4, %xmm6, %xmm6
-; AVX1-NEXT:    vpaddb %xmm6, %xmm2, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm1, %xmm6
-; AVX1-NEXT:    vpand %xmm3, %xmm6, %xmm3
-; AVX1-NEXT:    vpxor %xmm4, %xmm3, %xmm3
-; AVX1-NEXT:    vpaddb %xmm3, %xmm5, %xmm3
-; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm0
-; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm1 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm4
-; AVX1-NEXT:    vpaddb %xmm4, %xmm2, %xmm2
-; AVX1-NEXT:    vpsubb %xmm1, %xmm2, %xmm2
-; AVX1-NEXT:    vpaddb %xmm0, %xmm3, %xmm0
-; AVX1-NEXT:    vpsubb %xmm1, %xmm0, %xmm0
-; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
+; AVX1-NEXT:    vbroadcastss {{.*#+}} ymm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX1-NEXT:    vxorps %ymm2, %ymm0, %ymm0
+; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
+; AVX1-NEXT:    vxorps %ymm2, %ymm1, %ymm1
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
+; AVX1-NEXT:    vpavgb %xmm3, %xmm4, %xmm3
+; AVX1-NEXT:    vpavgb %xmm0, %xmm1, %xmm0
+; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm0, %ymm0
+; AVX1-NEXT:    vxorps %ymm2, %ymm0, %ymm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v32i8:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlw $1, %ymm0, %ymm2
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX2-NEXT:    vpand %ymm3, %ymm2, %ymm2
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; AVX2-NEXT:    vpxor %ymm4, %ymm2, %ymm2
-; AVX2-NEXT:    vpsrlw $1, %ymm1, %ymm5
-; AVX2-NEXT:    vpand %ymm3, %ymm5, %ymm3
-; AVX2-NEXT:    vpxor %ymm4, %ymm3, %ymm3
-; AVX2-NEXT:    vpaddb %ymm3, %ymm2, %ymm2
-; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
-; AVX2-NEXT:    vpaddb %ymm0, %ymm2, %ymm0
-; AVX2-NEXT:    vpsubb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
+; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX2-NEXT:    vpxor %ymm2, %ymm0, %ymm0
+; AVX2-NEXT:    vpxor %ymm2, %ymm1, %ymm1
+; AVX2-NEXT:    vpavgb %ymm0, %ymm1, %ymm0
+; AVX2-NEXT:    vpxor %ymm2, %ymm0, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v32i8:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX512-NEXT:    vpsrlw $1, %ymm0, %ymm3
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} ymm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; AVX512-NEXT:    vpternlogq {{.*#+}} ymm3 = ymm4 ^ (ymm3 & ymm2)
-; AVX512-NEXT:    vpsrlw $1, %ymm1, %ymm5
-; AVX512-NEXT:    vpternlogq {{.*#+}} ymm5 = ymm4 ^ (ymm5 & ymm2)
-; AVX512-NEXT:    vpaddb %ymm5, %ymm3, %ymm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} ymm0 = m32bcst & (ymm0 | ymm1)
-; AVX512-NEXT:    vpaddb %ymm0, %ymm2, %ymm0
-; AVX512-NEXT:    vpsubb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
+; AVX512-NEXT:    vpbroadcastd {{.*#+}} ymm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX512-NEXT:    vpxor %ymm2, %ymm0, %ymm0
+; AVX512-NEXT:    vpxor %ymm2, %ymm1, %ymm1
+; AVX512-NEXT:    vpavgb %ymm0, %ymm1, %ymm0
+; AVX512-NEXT:    vpxor %ymm2, %ymm0, %ymm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = ashr <32 x i8> %a, splat (i8 1)
   %b_shr_1 = ashr <32 x i8> %b, splat (i8 1)
@@ -897,79 +752,49 @@ define <16 x i16> @test_ext_v16i16(<16 x i16> %a0, <16 x i16> %a1) nounwind {
 }
 
 define <16 x i16> @test_lsb_v16i16(<16 x i16> %a, <16 x i16> %b) {
-; SSE2-LABEL: test_lsb_v16i16:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm4
-; SSE2-NEXT:    psraw $1, %xmm4
-; SSE2-NEXT:    movdqa %xmm1, %xmm5
-; SSE2-NEXT:    psraw $1, %xmm5
-; SSE2-NEXT:    movdqa {{.*#+}} xmm6 = [1,1,1,1,1,1,1,1]
-; SSE2-NEXT:    por %xmm2, %xmm0
-; SSE2-NEXT:    psraw $1, %xmm2
-; SSE2-NEXT:    paddw %xmm4, %xmm2
-; SSE2-NEXT:    por %xmm3, %xmm1
-; SSE2-NEXT:    psraw $1, %xmm3
-; SSE2-NEXT:    paddw %xmm5, %xmm3
-; SSE2-NEXT:    pand %xmm6, %xmm1
-; SSE2-NEXT:    paddw %xmm3, %xmm1
-; SSE2-NEXT:    pand %xmm6, %xmm0
-; SSE2-NEXT:    paddw %xmm2, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE4-LABEL: test_lsb_v16i16:
-; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm4
-; SSE4-NEXT:    psraw $1, %xmm4
-; SSE4-NEXT:    movdqa %xmm1, %xmm5
-; SSE4-NEXT:    psraw $1, %xmm5
-; SSE4-NEXT:    pmovsxbw {{.*#+}} xmm6 = [1,1,1,1,1,1,1,1]
-; SSE4-NEXT:    por %xmm2, %xmm0
-; SSE4-NEXT:    psraw $1, %xmm2
-; SSE4-NEXT:    paddw %xmm4, %xmm2
-; SSE4-NEXT:    por %xmm3, %xmm1
-; SSE4-NEXT:    psraw $1, %xmm3
-; SSE4-NEXT:    paddw %xmm5, %xmm3
-; SSE4-NEXT:    pand %xmm6, %xmm1
-; SSE4-NEXT:    paddw %xmm3, %xmm1
-; SSE4-NEXT:    pand %xmm6, %xmm0
-; SSE4-NEXT:    paddw %xmm2, %xmm0
-; SSE4-NEXT:    retq
+; SSE-LABEL: test_lsb_v16i16:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movdqa %xmm2, %xmm4
+; SSE-NEXT:    por %xmm0, %xmm4
+; SSE-NEXT:    pxor %xmm0, %xmm2
+; SSE-NEXT:    psraw $1, %xmm2
+; SSE-NEXT:    psubw %xmm2, %xmm4
+; SSE-NEXT:    movdqa %xmm3, %xmm2
+; SSE-NEXT:    por %xmm1, %xmm2
+; SSE-NEXT:    pxor %xmm1, %xmm3
+; SSE-NEXT:    psraw $1, %xmm3
+; SSE-NEXT:    psubw %xmm3, %xmm2
+; SSE-NEXT:    movdqa %xmm4, %xmm0
+; SSE-NEXT:    movdqa %xmm2, %xmm1
+; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v16i16:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpsraw $1, %xmm2, %xmm2
-; AVX1-NEXT:    vpsraw $1, %xmm0, %xmm3
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
-; AVX1-NEXT:    vpsraw $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpaddw %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpsraw $1, %xmm1, %xmm4
-; AVX1-NEXT:    vpaddw %xmm3, %xmm4, %xmm3
-; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm0
-; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
+; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm3
+; AVX1-NEXT:    vxorps %ymm0, %ymm1, %ymm0
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
-; AVX1-NEXT:    vpaddw %xmm1, %xmm2, %xmm1
-; AVX1-NEXT:    vpaddw %xmm0, %xmm3, %xmm0
+; AVX1-NEXT:    vpsraw $1, %xmm1, %xmm1
+; AVX1-NEXT:    vpsubw %xmm1, %xmm3, %xmm1
+; AVX1-NEXT:    vpsraw $1, %xmm0, %xmm0
+; AVX1-NEXT:    vpsubw %xmm0, %xmm2, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v16i16:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsraw $1, %ymm0, %ymm2
-; AVX2-NEXT:    vpsraw $1, %ymm1, %ymm3
-; AVX2-NEXT:    vpaddw %ymm2, %ymm3, %ymm2
-; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
-; AVX2-NEXT:    vpaddw %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm2
+; AVX2-NEXT:    vpxor %ymm0, %ymm1, %ymm0
+; AVX2-NEXT:    vpsraw $1, %ymm0, %ymm0
+; AVX2-NEXT:    vpsubw %ymm0, %ymm2, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v16i16:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsraw $1, %ymm0, %ymm2
-; AVX512-NEXT:    vpsraw $1, %ymm1, %ymm3
-; AVX512-NEXT:    vpaddw %ymm2, %ymm3, %ymm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} ymm0 = m32bcst & (ymm0 | ymm1)
-; AVX512-NEXT:    vpaddw %ymm0, %ymm2, %ymm0
+; AVX512-NEXT:    vpor %ymm0, %ymm1, %ymm2
+; AVX512-NEXT:    vpxor %ymm0, %ymm1, %ymm0
+; AVX512-NEXT:    vpsraw $1, %ymm0, %ymm0
+; AVX512-NEXT:    vpsubw %ymm0, %ymm2, %ymm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = ashr <16 x i16> %a, splat (i16 1)
   %b_shr_1 = ashr <16 x i16> %b, splat (i16 1)
@@ -1087,80 +912,49 @@ define <8 x i32> @test_ext_v8i32(<8 x i32> %a0, <8 x i32> %a1) nounwind {
 }
 
 define <8 x i32> @test_lsb_v8i32(<8 x i32> %a, <8 x i32> %b) {
-; SSE2-LABEL: test_lsb_v8i32:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm4
-; SSE2-NEXT:    psrad $1, %xmm4
-; SSE2-NEXT:    movdqa %xmm1, %xmm5
-; SSE2-NEXT:    psrad $1, %xmm5
-; SSE2-NEXT:    movdqa {{.*#+}} xmm6 = [1,1,1,1]
-; SSE2-NEXT:    por %xmm2, %xmm0
-; SSE2-NEXT:    psrad $1, %xmm2
-; SSE2-NEXT:    paddd %xmm4, %xmm2
-; SSE2-NEXT:    por %xmm3, %xmm1
-; SSE2-NEXT:    psrad $1, %xmm3
-; SSE2-NEXT:    paddd %xmm5, %xmm3
-; SSE2-NEXT:    pand %xmm6, %xmm1
-; SSE2-NEXT:    paddd %xmm3, %xmm1
-; SSE2-NEXT:    pand %xmm6, %xmm0
-; SSE2-NEXT:    paddd %xmm2, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE4-LABEL: test_lsb_v8i32:
-; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm4
-; SSE4-NEXT:    psrad $1, %xmm4
-; SSE4-NEXT:    movdqa %xmm1, %xmm5
-; SSE4-NEXT:    psrad $1, %xmm5
-; SSE4-NEXT:    pmovsxbd {{.*#+}} xmm6 = [1,1,1,1]
-; SSE4-NEXT:    por %xmm2, %xmm0
-; SSE4-NEXT:    psrad $1, %xmm2
-; SSE4-NEXT:    paddd %xmm4, %xmm2
-; SSE4-NEXT:    por %xmm3, %xmm1
-; SSE4-NEXT:    psrad $1, %xmm3
-; SSE4-NEXT:    paddd %xmm5, %xmm3
-; SSE4-NEXT:    pand %xmm6, %xmm1
-; SSE4-NEXT:    paddd %xmm3, %xmm1
-; SSE4-NEXT:    pand %xmm6, %xmm0
-; SSE4-NEXT:    paddd %xmm2, %xmm0
-; SSE4-NEXT:    retq
+; SSE-LABEL: test_lsb_v8i32:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movdqa %xmm2, %xmm4
+; SSE-NEXT:    por %xmm0, %xmm4
+; SSE-NEXT:    pxor %xmm0, %xmm2
+; SSE-NEXT:    psrad $1, %xmm2
+; SSE-NEXT:    psubd %xmm2, %xmm4
+; SSE-NEXT:    movdqa %xmm3, %xmm2
+; SSE-NEXT:    por %xmm1, %xmm2
+; SSE-NEXT:    pxor %xmm1, %xmm3
+; SSE-NEXT:    psrad $1, %xmm3
+; SSE-NEXT:    psubd %xmm3, %xmm2
+; SSE-NEXT:    movdqa %xmm4, %xmm0
+; SSE-NEXT:    movdqa %xmm2, %xmm1
+; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v8i32:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpsrad $1, %xmm2, %xmm2
-; AVX1-NEXT:    vpsrad $1, %xmm0, %xmm3
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
-; AVX1-NEXT:    vpsrad $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpaddd %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpsrad $1, %xmm1, %xmm4
-; AVX1-NEXT:    vpaddd %xmm3, %xmm4, %xmm3
-; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm0
-; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
+; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm3
+; AVX1-NEXT:    vxorps %ymm0, %ymm1, %ymm0
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
-; AVX1-NEXT:    vpaddd %xmm1, %xmm2, %xmm1
-; AVX1-NEXT:    vpaddd %xmm0, %xmm3, %xmm0
+; AVX1-NEXT:    vpsrad $1, %xmm1, %xmm1
+; AVX1-NEXT:    vpsubd %xmm1, %xmm3, %xmm1
+; AVX1-NEXT:    vpsrad $1, %xmm0, %xmm0
+; AVX1-NEXT:    vpsubd %xmm0, %xmm2, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v8i32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrad $1, %ymm0, %ymm2
-; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm3 = [1,1,1,1,1,1,1,1]
-; AVX2-NEXT:    vpsrad $1, %ymm1, %ymm4
-; AVX2-NEXT:    vpaddd %ymm2, %ymm4, %ymm2
-; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpand %ymm3, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddd %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm2
+; AVX2-NEXT:    vpxor %ymm0, %ymm1, %ymm0
+; AVX2-NEXT:    vpsrad $1, %ymm0, %ymm0
+; AVX2-NEXT:    vpsubd %ymm0, %ymm2, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v8i32:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrad $1, %ymm0, %ymm2
-; AVX512-NEXT:    vpsrad $1, %ymm1, %ymm3
-; AVX512-NEXT:    vpaddd %ymm2, %ymm3, %ymm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} ymm0 = m32bcst & (ymm0 | ymm1)
-; AVX512-NEXT:    vpaddd %ymm0, %ymm2, %ymm0
+; AVX512-NEXT:    vpor %ymm0, %ymm1, %ymm2
+; AVX512-NEXT:    vpxor %ymm0, %ymm1, %ymm0
+; AVX512-NEXT:    vpsrad $1, %ymm0, %ymm0
+; AVX512-NEXT:    vpsubd %ymm0, %ymm2, %ymm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = ashr <8 x i32> %a, splat (i32 1)
   %b_shr_1 = ashr <8 x i32> %b, splat (i32 1)
@@ -1344,118 +1138,79 @@ define <4 x i64> @test_ext_v4i64(<4 x i64> %a0, <4 x i64> %a1) nounwind {
 define <4 x i64> @test_lsb_v4i64(<4 x i64> %a, <4 x i64> %b) {
 ; SSE2-LABEL: test_lsb_v4i64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm4
-; SSE2-NEXT:    movdqa %xmm0, %xmm5
-; SSE2-NEXT:    psrlq $1, %xmm5
-; SSE2-NEXT:    pshufd {{.*#+}} xmm6 = xmm5[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm6 = xmm6[0],xmm4[0],xmm6[1],xmm4[1]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm1[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm4
-; SSE2-NEXT:    movdqa %xmm1, %xmm5
-; SSE2-NEXT:    psrlq $1, %xmm5
-; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1]
-; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [1,1]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm7 = xmm2[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm7
+; SSE2-NEXT:    movdqa %xmm2, %xmm4
+; SSE2-NEXT:    pxor %xmm0, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[1,3,2,3]
+; SSE2-NEXT:    psrad $1, %xmm5
+; SSE2-NEXT:    psrlq $1, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm5[0],xmm4[1],xmm5[1]
 ; SSE2-NEXT:    por %xmm2, %xmm0
+; SSE2-NEXT:    psubq %xmm4, %xmm0
+; SSE2-NEXT:    movdqa %xmm3, %xmm2
+; SSE2-NEXT:    pxor %xmm1, %xmm2
+; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm2[1,3,2,3]
+; SSE2-NEXT:    psrad $1, %xmm4
 ; SSE2-NEXT:    psrlq $1, %xmm2
 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm7[0],xmm2[1],xmm7[1]
-; SSE2-NEXT:    paddq %xmm6, %xmm2
-; SSE2-NEXT:    pshufd {{.*#+}} xmm6 = xmm3[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm6
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
 ; SSE2-NEXT:    por %xmm3, %xmm1
-; SSE2-NEXT:    psrlq $1, %xmm3
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm6[0],xmm3[1],xmm6[1]
-; SSE2-NEXT:    paddq %xmm5, %xmm3
-; SSE2-NEXT:    pand %xmm4, %xmm1
-; SSE2-NEXT:    paddq %xmm3, %xmm1
-; SSE2-NEXT:    pand %xmm4, %xmm0
-; SSE2-NEXT:    paddq %xmm2, %xmm0
+; SSE2-NEXT:    psubq %xmm2, %xmm1
 ; SSE2-NEXT:    retq
 ;
 ; SSE4-LABEL: test_lsb_v4i64:
 ; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm4
-; SSE4-NEXT:    psrad $1, %xmm4
-; SSE4-NEXT:    movdqa %xmm0, %xmm7
-; SSE4-NEXT:    psrlq $1, %xmm7
-; SSE4-NEXT:    pblendw {{.*#+}} xmm7 = xmm7[0,1],xmm4[2,3],xmm7[4,5],xmm4[6,7]
-; SSE4-NEXT:    movdqa %xmm1, %xmm4
-; SSE4-NEXT:    psrad $1, %xmm4
-; SSE4-NEXT:    movdqa %xmm1, %xmm6
-; SSE4-NEXT:    psrlq $1, %xmm6
-; SSE4-NEXT:    pblendw {{.*#+}} xmm6 = xmm6[0,1],xmm4[2,3],xmm6[4,5],xmm4[6,7]
-; SSE4-NEXT:    pmovsxbq {{.*#+}} xmm4 = [1,1]
-; SSE4-NEXT:    movdqa %xmm2, %xmm5
+; SSE4-NEXT:    movdqa %xmm2, %xmm4
+; SSE4-NEXT:    pxor %xmm0, %xmm4
+; SSE4-NEXT:    movdqa %xmm4, %xmm5
+; SSE4-NEXT:    psrad $1, %xmm5
+; SSE4-NEXT:    psrlq $1, %xmm4
+; SSE4-NEXT:    pblendw {{.*#+}} xmm4 = xmm4[0,1],xmm5[2,3],xmm4[4,5],xmm5[6,7]
 ; SSE4-NEXT:    por %xmm2, %xmm0
-; SSE4-NEXT:    psrad $1, %xmm2
-; SSE4-NEXT:    psrlq $1, %xmm5
-; SSE4-NEXT:    pblendw {{.*#+}} xmm5 = xmm5[0,1],xmm2[2,3],xmm5[4,5],xmm2[6,7]
-; SSE4-NEXT:    paddq %xmm7, %xmm5
+; SSE4-NEXT:    psubq %xmm4, %xmm0
 ; SSE4-NEXT:    movdqa %xmm3, %xmm2
-; SSE4-NEXT:    por %xmm3, %xmm1
-; SSE4-NEXT:    psrad $1, %xmm3
+; SSE4-NEXT:    pxor %xmm1, %xmm2
+; SSE4-NEXT:    movdqa %xmm2, %xmm4
+; SSE4-NEXT:    psrad $1, %xmm4
 ; SSE4-NEXT:    psrlq $1, %xmm2
-; SSE4-NEXT:    pblendw {{.*#+}} xmm2 = xmm2[0,1],xmm3[2,3],xmm2[4,5],xmm3[6,7]
-; SSE4-NEXT:    paddq %xmm6, %xmm2
-; SSE4-NEXT:    pand %xmm4, %xmm1
-; SSE4-NEXT:    paddq %xmm2, %xmm1
-; SSE4-NEXT:    pand %xmm4, %xmm0
-; SSE4-NEXT:    paddq %xmm5, %xmm0
+; SSE4-NEXT:    pblendw {{.*#+}} xmm2 = xmm2[0,1],xmm4[2,3],xmm2[4,5],xmm4[6,7]
+; SSE4-NEXT:    por %xmm3, %xmm1
+; SSE4-NEXT:    psubq %xmm2, %xmm1
 ; SSE4-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v4i64:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
+; AVX1-NEXT:    vxorps %ymm0, %ymm1, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm3
+; AVX1-NEXT:    vpsrad $1, %xmm3, %xmm4
+; AVX1-NEXT:    vpsrlq $1, %xmm3, %xmm3
+; AVX1-NEXT:    vpblendw {{.*#+}} xmm3 = xmm3[0,1],xmm4[2,3],xmm3[4,5],xmm4[6,7]
+; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm0
+; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
+; AVX1-NEXT:    vpsubq %xmm3, %xmm1, %xmm1
 ; AVX1-NEXT:    vpsrad $1, %xmm2, %xmm3
 ; AVX1-NEXT:    vpsrlq $1, %xmm2, %xmm2
 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm2[0,1],xmm3[2,3],xmm2[4,5],xmm3[6,7]
-; AVX1-NEXT:    vpsrad $1, %xmm0, %xmm3
-; AVX1-NEXT:    vpsrlq $1, %xmm0, %xmm4
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm3 = xmm4[0,1],xmm3[2,3],xmm4[4,5],xmm3[6,7]
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
-; AVX1-NEXT:    vpsrad $1, %xmm4, %xmm5
-; AVX1-NEXT:    vpsrlq $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm4 = xmm4[0,1],xmm5[2,3],xmm4[4,5],xmm5[6,7]
-; AVX1-NEXT:    vpaddq %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpsrad $1, %xmm1, %xmm4
-; AVX1-NEXT:    vpsrlq $1, %xmm1, %xmm5
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm4 = xmm5[0,1],xmm4[2,3],xmm5[4,5],xmm4[6,7]
-; AVX1-NEXT:    vpaddq %xmm3, %xmm4, %xmm3
-; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm0
-; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
-; AVX1-NEXT:    vpaddq %xmm1, %xmm2, %xmm1
-; AVX1-NEXT:    vpaddq %xmm0, %xmm3, %xmm0
+; AVX1-NEXT:    vpsubq %xmm2, %xmm0, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v4i64:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrad $1, %ymm0, %ymm2
-; AVX2-NEXT:    vpsrlq $1, %ymm0, %ymm3
-; AVX2-NEXT:    vpblendd {{.*#+}} ymm2 = ymm3[0],ymm2[1],ymm3[2],ymm2[3],ymm3[4],ymm2[5],ymm3[6],ymm2[7]
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm3 = [1,1,1,1]
-; AVX2-NEXT:    vpsrad $1, %ymm1, %ymm4
-; AVX2-NEXT:    vpsrlq $1, %ymm1, %ymm5
-; AVX2-NEXT:    vpblendd {{.*#+}} ymm4 = ymm5[0],ymm4[1],ymm5[2],ymm4[3],ymm5[4],ymm4[5],ymm5[6],ymm4[7]
-; AVX2-NEXT:    vpaddq %ymm2, %ymm4, %ymm2
+; AVX2-NEXT:    vpxor %ymm0, %ymm1, %ymm2
+; AVX2-NEXT:    vpsrad $1, %ymm2, %ymm3
+; AVX2-NEXT:    vpsrlq $1, %ymm2, %ymm2
+; AVX2-NEXT:    vpblendd {{.*#+}} ymm2 = ymm2[0],ymm3[1],ymm2[2],ymm3[3],ymm2[4],ymm3[5],ymm2[6],ymm3[7]
 ; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpand %ymm3, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddq %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpsubq %ymm2, %ymm0, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v4i64:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsraq $1, %ymm0, %ymm2
-; AVX512-NEXT:    vpsraq $1, %ymm1, %ymm3
-; AVX512-NEXT:    vpaddq %ymm2, %ymm3, %ymm2
-; AVX512-NEXT:    vpternlogq {{.*#+}} ymm0 = m64bcst & (ymm0 | ymm1)
-; AVX512-NEXT:    vpaddq %ymm0, %ymm2, %ymm0
+; AVX512-NEXT:    vpor %ymm0, %ymm1, %ymm2
+; AVX512-NEXT:    vpxor %ymm0, %ymm1, %ymm0
+; AVX512-NEXT:    vpsraq $1, %ymm0, %ymm0
+; AVX512-NEXT:    vpsubq %ymm0, %ymm2, %ymm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = ashr <4 x i64> %a, splat (i64 1)
   %b_shr_1 = ashr <4 x i64> %b, splat (i64 1)
@@ -1617,158 +1372,66 @@ define <64 x i8> @test_ext_v64i8(<64 x i8> %a0, <64 x i8> %a1) nounwind {
 define <64 x i8> @test_lsb_v64i8(<64 x i8> %a, <64 x i8> %b) {
 ; SSE-LABEL: test_lsb_v64i8:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm12
-; SSE-NEXT:    psrlw $1, %xmm12
-; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; SSE-NEXT:    pand %xmm8, %xmm12
-; SSE-NEXT:    movdqa {{.*#+}} xmm9 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; SSE-NEXT:    pxor %xmm9, %xmm12
-; SSE-NEXT:    movdqa %xmm1, %xmm14
-; SSE-NEXT:    psrlw $1, %xmm14
-; SSE-NEXT:    pand %xmm8, %xmm14
-; SSE-NEXT:    pxor %xmm9, %xmm14
-; SSE-NEXT:    movdqa %xmm2, %xmm13
-; SSE-NEXT:    psrlw $1, %xmm13
-; SSE-NEXT:    pand %xmm8, %xmm13
-; SSE-NEXT:    pxor %xmm9, %xmm13
-; SSE-NEXT:    movdqa %xmm3, %xmm11
-; SSE-NEXT:    psrlw $1, %xmm11
-; SSE-NEXT:    pand %xmm8, %xmm11
-; SSE-NEXT:    pxor %xmm9, %xmm11
-; SSE-NEXT:    movdqa {{.*#+}} xmm10 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; SSE-NEXT:    por %xmm4, %xmm0
-; SSE-NEXT:    psrlw $1, %xmm4
-; SSE-NEXT:    pand %xmm8, %xmm4
-; SSE-NEXT:    pxor %xmm9, %xmm4
-; SSE-NEXT:    paddb %xmm12, %xmm4
-; SSE-NEXT:    por %xmm5, %xmm1
-; SSE-NEXT:    psrlw $1, %xmm5
-; SSE-NEXT:    pand %xmm8, %xmm5
-; SSE-NEXT:    pxor %xmm9, %xmm5
-; SSE-NEXT:    paddb %xmm14, %xmm5
-; SSE-NEXT:    por %xmm6, %xmm2
-; SSE-NEXT:    psrlw $1, %xmm6
-; SSE-NEXT:    pand %xmm8, %xmm6
-; SSE-NEXT:    pxor %xmm9, %xmm6
-; SSE-NEXT:    paddb %xmm13, %xmm6
-; SSE-NEXT:    por %xmm7, %xmm3
-; SSE-NEXT:    psrlw $1, %xmm7
-; SSE-NEXT:    pand %xmm8, %xmm7
-; SSE-NEXT:    pxor %xmm9, %xmm7
-; SSE-NEXT:    paddb %xmm11, %xmm7
-; SSE-NEXT:    pand %xmm10, %xmm3
-; SSE-NEXT:    paddb %xmm7, %xmm3
-; SSE-NEXT:    pand %xmm10, %xmm2
-; SSE-NEXT:    paddb %xmm6, %xmm2
-; SSE-NEXT:    pand %xmm10, %xmm1
-; SSE-NEXT:    paddb %xmm5, %xmm1
-; SSE-NEXT:    pand %xmm10, %xmm0
-; SSE-NEXT:    paddb %xmm4, %xmm0
-; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
-; SSE-NEXT:    psubb %xmm4, %xmm0
-; SSE-NEXT:    psubb %xmm4, %xmm1
-; SSE-NEXT:    psubb %xmm4, %xmm2
-; SSE-NEXT:    psubb %xmm4, %xmm3
+; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; SSE-NEXT:    pxor %xmm8, %xmm0
+; SSE-NEXT:    pxor %xmm8, %xmm4
+; SSE-NEXT:    pavgb %xmm4, %xmm0
+; SSE-NEXT:    pxor %xmm8, %xmm0
+; SSE-NEXT:    pxor %xmm8, %xmm1
+; SSE-NEXT:    pxor %xmm8, %xmm5
+; SSE-NEXT:    pavgb %xmm5, %xmm1
+; SSE-NEXT:    pxor %xmm8, %xmm1
+; SSE-NEXT:    pxor %xmm8, %xmm2
+; SSE-NEXT:    pxor %xmm8, %xmm6
+; SSE-NEXT:    pavgb %xmm6, %xmm2
+; SSE-NEXT:    pxor %xmm8, %xmm2
+; SSE-NEXT:    pxor %xmm8, %xmm3
+; SSE-NEXT:    pxor %xmm8, %xmm7
+; SSE-NEXT:    pavgb %xmm7, %xmm3
+; SSE-NEXT:    pxor %xmm8, %xmm3
 ; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v64i8:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm4
-; AVX1-NEXT:    vpsrlw $1, %xmm4, %xmm5
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm4 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX1-NEXT:    vpand %xmm4, %xmm5, %xmm6
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm5 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; AVX1-NEXT:    vpxor %xmm5, %xmm6, %xmm6
-; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm7
-; AVX1-NEXT:    vpand %xmm4, %xmm7, %xmm7
-; AVX1-NEXT:    vpxor %xmm5, %xmm7, %xmm7
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm8
-; AVX1-NEXT:    vpsrlw $1, %xmm8, %xmm8
-; AVX1-NEXT:    vpand %xmm4, %xmm8, %xmm8
-; AVX1-NEXT:    vpxor %xmm5, %xmm8, %xmm8
-; AVX1-NEXT:    vpsrlw $1, %xmm1, %xmm9
-; AVX1-NEXT:    vpand %xmm4, %xmm9, %xmm9
-; AVX1-NEXT:    vpxor %xmm5, %xmm9, %xmm9
-; AVX1-NEXT:    vbroadcastss {{.*#+}} ymm10 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm11
-; AVX1-NEXT:    vpsrlw $1, %xmm11, %xmm11
-; AVX1-NEXT:    vpand %xmm4, %xmm11, %xmm11
-; AVX1-NEXT:    vpxor %xmm5, %xmm11, %xmm11
-; AVX1-NEXT:    vpaddb %xmm6, %xmm11, %xmm6
-; AVX1-NEXT:    vpsrlw $1, %xmm2, %xmm11
-; AVX1-NEXT:    vpand %xmm4, %xmm11, %xmm11
-; AVX1-NEXT:    vpxor %xmm5, %xmm11, %xmm11
-; AVX1-NEXT:    vpaddb %xmm7, %xmm11, %xmm7
-; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm11
-; AVX1-NEXT:    vpsrlw $1, %xmm11, %xmm11
-; AVX1-NEXT:    vpand %xmm4, %xmm11, %xmm11
-; AVX1-NEXT:    vpxor %xmm5, %xmm11, %xmm11
-; AVX1-NEXT:    vpaddb %xmm11, %xmm8, %xmm8
-; AVX1-NEXT:    vpsrlw $1, %xmm3, %xmm11
-; AVX1-NEXT:    vpand %xmm4, %xmm11, %xmm4
-; AVX1-NEXT:    vpxor %xmm5, %xmm4, %xmm4
-; AVX1-NEXT:    vpaddb %xmm4, %xmm9, %xmm4
-; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm0
-; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm1
-; AVX1-NEXT:    vandps %ymm1, %ymm10, %ymm1
-; AVX1-NEXT:    vandps %ymm0, %ymm10, %ymm0
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
-; AVX1-NEXT:    vpaddb %xmm3, %xmm6, %xmm3
-; AVX1-NEXT:    vpsubb %xmm2, %xmm3, %xmm3
-; AVX1-NEXT:    vpaddb %xmm0, %xmm7, %xmm0
-; AVX1-NEXT:    vpsubb %xmm2, %xmm0, %xmm0
-; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm0, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
-; AVX1-NEXT:    vpaddb %xmm3, %xmm8, %xmm3
-; AVX1-NEXT:    vpsubb %xmm2, %xmm3, %xmm3
-; AVX1-NEXT:    vpaddb %xmm1, %xmm4, %xmm1
-; AVX1-NEXT:    vpsubb %xmm2, %xmm1, %xmm1
-; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm1, %ymm1
+; AVX1-NEXT:    vbroadcastss {{.*#+}} ymm4 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX1-NEXT:    vxorps %ymm4, %ymm0, %ymm0
+; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
+; AVX1-NEXT:    vxorps %ymm4, %ymm2, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm6
+; AVX1-NEXT:    vpavgb %xmm5, %xmm6, %xmm5
+; AVX1-NEXT:    vpavgb %xmm0, %xmm2, %xmm0
+; AVX1-NEXT:    vinsertf128 $1, %xmm5, %ymm0, %ymm0
+; AVX1-NEXT:    vxorps %ymm4, %ymm0, %ymm0
+; AVX1-NEXT:    vxorps %ymm4, %ymm1, %ymm1
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; AVX1-NEXT:    vxorps %ymm4, %ymm3, %ymm3
+; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm5
+; AVX1-NEXT:    vpavgb %xmm2, %xmm5, %xmm2
+; AVX1-NEXT:    vpavgb %xmm1, %xmm3, %xmm1
+; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
+; AVX1-NEXT:    vxorps %ymm4, %ymm1, %ymm1
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v64i8:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlw $1, %ymm0, %ymm4
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm5 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX2-NEXT:    vpand %ymm5, %ymm4, %ymm4
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm6 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; AVX2-NEXT:    vpxor %ymm6, %ymm4, %ymm4
-; AVX2-NEXT:    vpsrlw $1, %ymm1, %ymm7
-; AVX2-NEXT:    vpand %ymm5, %ymm7, %ymm7
-; AVX2-NEXT:    vpxor %ymm6, %ymm7, %ymm7
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm8 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; AVX2-NEXT:    vpsrlw $1, %ymm2, %ymm9
-; AVX2-NEXT:    vpand %ymm5, %ymm9, %ymm9
-; AVX2-NEXT:    vpxor %ymm6, %ymm9, %ymm9
-; AVX2-NEXT:    vpaddb %ymm4, %ymm9, %ymm4
-; AVX2-NEXT:    vpsrlw $1, %ymm3, %ymm9
-; AVX2-NEXT:    vpand %ymm5, %ymm9, %ymm5
-; AVX2-NEXT:    vpxor %ymm6, %ymm5, %ymm5
-; AVX2-NEXT:    vpaddb %ymm5, %ymm7, %ymm5
-; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm0
-; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm1
-; AVX2-NEXT:    vpand %ymm1, %ymm8, %ymm1
-; AVX2-NEXT:    vpaddb %ymm1, %ymm5, %ymm1
-; AVX2-NEXT:    vpand %ymm0, %ymm8, %ymm0
-; AVX2-NEXT:    vpaddb %ymm0, %ymm4, %ymm0
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
-; AVX2-NEXT:    vpsubb %ymm2, %ymm0, %ymm0
-; AVX2-NEXT:    vpsubb %ymm2, %ymm1, %ymm1
+; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm4 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX2-NEXT:    vpxor %ymm4, %ymm0, %ymm0
+; AVX2-NEXT:    vpxor %ymm4, %ymm2, %ymm2
+; AVX2-NEXT:    vpavgb %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpxor %ymm4, %ymm0, %ymm0
+; AVX2-NEXT:    vpxor %ymm4, %ymm1, %ymm1
+; AVX2-NEXT:    vpxor %ymm4, %ymm3, %ymm2
+; AVX2-NEXT:    vpavgb %ymm1, %ymm2, %ymm1
+; AVX2-NEXT:    vpxor %ymm4, %ymm1, %ymm1
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v64i8:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} zmm2 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX512-NEXT:    vpsrlw $1, %zmm0, %zmm3
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} zmm4 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
-; AVX512-NEXT:    vpternlogq {{.*#+}} zmm3 = zmm4 ^ (zmm3 & zmm2)
-; AVX512-NEXT:    vpsrlw $1, %zmm1, %zmm5
-; AVX512-NEXT:    vpternlogq {{.*#+}} zmm5 = zmm4 ^ (zmm5 & zmm2)
-; AVX512-NEXT:    vpaddb %zmm5, %zmm3, %zmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} zmm0 = m32bcst & (zmm0 | zmm1)
-; AVX512-NEXT:    vpaddb %zmm0, %zmm2, %zmm0
-; AVX512-NEXT:    vpsubb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %zmm0, %zmm0
+; AVX512-NEXT:    vpbroadcastd {{.*#+}} zmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
+; AVX512-NEXT:    vpxorq %zmm2, %zmm0, %zmm0
+; AVX512-NEXT:    vpxorq %zmm2, %zmm1, %zmm1
+; AVX512-NEXT:    vpavgb %zmm0, %zmm1, %zmm0
+; AVX512-NEXT:    vpxorq %zmm2, %zmm0, %zmm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = ashr <64 x i8> %a, splat (i8 1)
   %b_shr_1 = ashr <64 x i8> %b, splat (i8 1)
@@ -1936,129 +1599,74 @@ define <32 x i16> @test_ext_v32i16(<32 x i16> %a0, <32 x i16> %a1) nounwind {
 }
 
 define <32 x i16> @test_lsb_v32i16(<32 x i16> %a, <32 x i16> %b) {
-; SSE2-LABEL: test_lsb_v32i16:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm11
-; SSE2-NEXT:    psraw $1, %xmm11
-; SSE2-NEXT:    movdqa %xmm1, %xmm12
-; SSE2-NEXT:    psraw $1, %xmm12
-; SSE2-NEXT:    movdqa %xmm2, %xmm10
-; SSE2-NEXT:    psraw $1, %xmm10
-; SSE2-NEXT:    movdqa %xmm3, %xmm9
-; SSE2-NEXT:    psraw $1, %xmm9
-; SSE2-NEXT:    movdqa {{.*#+}} xmm8 = [1,1,1,1,1,1,1,1]
-; SSE2-NEXT:    por %xmm4, %xmm0
-; SSE2-NEXT:    psraw $1, %xmm4
-; SSE2-NEXT:    paddw %xmm11, %xmm4
-; SSE2-NEXT:    por %xmm5, %xmm1
-; SSE2-NEXT:    psraw $1, %xmm5
-; SSE2-NEXT:    paddw %xmm12, %xmm5
-; SSE2-NEXT:    por %xmm6, %xmm2
-; SSE2-NEXT:    psraw $1, %xmm6
-; SSE2-NEXT:    paddw %xmm10, %xmm6
-; SSE2-NEXT:    por %xmm7, %xmm3
-; SSE2-NEXT:    psraw $1, %xmm7
-; SSE2-NEXT:    paddw %xmm9, %xmm7
-; SSE2-NEXT:    pand %xmm8, %xmm3
-; SSE2-NEXT:    paddw %xmm7, %xmm3
-; SSE2-NEXT:    pand %xmm8, %xmm2
-; SSE2-NEXT:    paddw %xmm6, %xmm2
-; SSE2-NEXT:    pand %xmm8, %xmm1
-; SSE2-NEXT:    paddw %xmm5, %xmm1
-; SSE2-NEXT:    pand %xmm8, %xmm0
-; SSE2-NEXT:    paddw %xmm4, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE4-LABEL: test_lsb_v32i16:
-; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm11
-; SSE4-NEXT:    psraw $1, %xmm11
-; SSE4-NEXT:    movdqa %xmm1, %xmm12
-; SSE4-NEXT:    psraw $1, %xmm12
-; SSE4-NEXT:    movdqa %xmm2, %xmm10
-; SSE4-NEXT:    psraw $1, %xmm10
-; SSE4-NEXT:    movdqa %xmm3, %xmm9
-; SSE4-NEXT:    psraw $1, %xmm9
-; SSE4-NEXT:    pmovsxbw {{.*#+}} xmm8 = [1,1,1,1,1,1,1,1]
-; SSE4-NEXT:    por %xmm4, %xmm0
-; SSE4-NEXT:    psraw $1, %xmm4
-; SSE4-NEXT:    paddw %xmm11, %xmm4
-; SSE4-NEXT:    por %xmm5, %xmm1
-; SSE4-NEXT:    psraw $1, %xmm5
-; SSE4-NEXT:    paddw %xmm12, %xmm5
-; SSE4-NEXT:    por %xmm6, %xmm2
-; SSE4-NEXT:    psraw $1, %xmm6
-; SSE4-NEXT:    paddw %xmm10, %xmm6
-; SSE4-NEXT:    por %xmm7, %xmm3
-; SSE4-NEXT:    psraw $1, %xmm7
-; SSE4-NEXT:    paddw %xmm9, %xmm7
-; SSE4-NEXT:    pand %xmm8, %xmm3
-; SSE4-NEXT:    paddw %xmm7, %xmm3
-; SSE4-NEXT:    pand %xmm8, %xmm2
-; SSE4-NEXT:    paddw %xmm6, %xmm2
-; SSE4-NEXT:    pand %xmm8, %xmm1
-; SSE4-NEXT:    paddw %xmm5, %xmm1
-; SSE4-NEXT:    pand %xmm8, %xmm0
-; SSE4-NEXT:    paddw %xmm4, %xmm0
-; SSE4-NEXT:    retq
+; SSE-LABEL: test_lsb_v32i16:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movdqa %xmm4, %xmm8
+; SSE-NEXT:    por %xmm0, %xmm8
+; SSE-NEXT:    pxor %xmm0, %xmm4
+; SSE-NEXT:    psraw $1, %xmm4
+; SSE-NEXT:    psubw %xmm4, %xmm8
+; SSE-NEXT:    movdqa %xmm5, %xmm4
+; SSE-NEXT:    por %xmm1, %xmm4
+; SSE-NEXT:    pxor %xmm1, %xmm5
+; SSE-NEXT:    psraw $1, %xmm5
+; SSE-NEXT:    psubw %xmm5, %xmm4
+; SSE-NEXT:    movdqa %xmm6, %xmm5
+; SSE-NEXT:    por %xmm2, %xmm5
+; SSE-NEXT:    pxor %xmm2, %xmm6
+; SSE-NEXT:    psraw $1, %xmm6
+; SSE-NEXT:    psubw %xmm6, %xmm5
+; SSE-NEXT:    movdqa %xmm7, %xmm6
+; SSE-NEXT:    por %xmm3, %xmm6
+; SSE-NEXT:    pxor %xmm3, %xmm7
+; SSE-NEXT:    psraw $1, %xmm7
+; SSE-NEXT:    psubw %xmm7, %xmm6
+; SSE-NEXT:    movdqa %xmm8, %xmm0
+; SSE-NEXT:    movdqa %xmm4, %xmm1
+; SSE-NEXT:    movdqa %xmm5, %xmm2
+; SSE-NEXT:    movdqa %xmm6, %xmm3
+; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v32i16:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm4
-; AVX1-NEXT:    vpsraw $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpsraw $1, %xmm0, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm6
-; AVX1-NEXT:    vpsraw $1, %xmm6, %xmm6
-; AVX1-NEXT:    vpsraw $1, %xmm1, %xmm7
-; AVX1-NEXT:    vbroadcastss {{.*#+}} ymm8 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm9
-; AVX1-NEXT:    vpsraw $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpaddw %xmm4, %xmm9, %xmm4
-; AVX1-NEXT:    vpsraw $1, %xmm2, %xmm9
-; AVX1-NEXT:    vpaddw %xmm5, %xmm9, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm9
-; AVX1-NEXT:    vpsraw $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpaddw %xmm6, %xmm9, %xmm6
-; AVX1-NEXT:    vpsraw $1, %xmm3, %xmm9
-; AVX1-NEXT:    vpaddw %xmm7, %xmm9, %xmm7
-; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm0
-; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm1
-; AVX1-NEXT:    vandps %ymm1, %ymm8, %ymm1
-; AVX1-NEXT:    vandps %ymm0, %ymm8, %ymm0
+; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm4
+; AVX1-NEXT:    vextractf128 $1, %ymm4, %xmm5
+; AVX1-NEXT:    vxorps %ymm0, %ymm2, %ymm0
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpaddw %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpaddw %xmm0, %xmm5, %xmm0
+; AVX1-NEXT:    vpsraw $1, %xmm2, %xmm2
+; AVX1-NEXT:    vpsubw %xmm2, %xmm5, %xmm2
+; AVX1-NEXT:    vpsraw $1, %xmm0, %xmm0
+; AVX1-NEXT:    vpsubw %xmm0, %xmm4, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
-; AVX1-NEXT:    vpaddw %xmm2, %xmm6, %xmm2
-; AVX1-NEXT:    vpaddw %xmm1, %xmm7, %xmm1
-; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
+; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
+; AVX1-NEXT:    vxorps %ymm1, %ymm3, %ymm1
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
+; AVX1-NEXT:    vpsraw $1, %xmm3, %xmm3
+; AVX1-NEXT:    vpsubw %xmm3, %xmm4, %xmm3
+; AVX1-NEXT:    vpsraw $1, %xmm1, %xmm1
+; AVX1-NEXT:    vpsubw %xmm1, %xmm2, %xmm1
+; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm1, %ymm1
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v32i16:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsraw $1, %ymm0, %ymm4
-; AVX2-NEXT:    vpsraw $1, %ymm1, %ymm5
-; AVX2-NEXT:    vpbroadcastw {{.*#+}} ymm6 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; AVX2-NEXT:    vpsraw $1, %ymm2, %ymm7
-; AVX2-NEXT:    vpaddw %ymm4, %ymm7, %ymm4
-; AVX2-NEXT:    vpsraw $1, %ymm3, %ymm7
-; AVX2-NEXT:    vpaddw %ymm5, %ymm7, %ymm5
-; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm0
-; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm1, %ymm1
-; AVX2-NEXT:    vpaddw %ymm1, %ymm5, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddw %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm4
+; AVX2-NEXT:    vpxor %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpsraw $1, %ymm0, %ymm0
+; AVX2-NEXT:    vpsubw %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm2
+; AVX2-NEXT:    vpxor %ymm1, %ymm3, %ymm1
+; AVX2-NEXT:    vpsraw $1, %ymm1, %ymm1
+; AVX2-NEXT:    vpsubw %ymm1, %ymm2, %ymm1
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v32i16:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsraw $1, %zmm0, %zmm2
-; AVX512-NEXT:    vpsraw $1, %zmm1, %zmm3
-; AVX512-NEXT:    vpaddw %zmm2, %zmm3, %zmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} zmm0 = m32bcst & (zmm0 | zmm1)
-; AVX512-NEXT:    vpaddw %zmm0, %zmm2, %zmm0
+; AVX512-NEXT:    vporq %zmm0, %zmm1, %zmm2
+; AVX512-NEXT:    vpxorq %zmm0, %zmm1, %zmm0
+; AVX512-NEXT:    vpsraw $1, %zmm0, %zmm0
+; AVX512-NEXT:    vpsubw %zmm0, %zmm2, %zmm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = ashr <32 x i16> %a, splat (i16 1)
   %b_shr_1 = ashr <32 x i16> %b, splat (i16 1)
@@ -2226,129 +1834,74 @@ define <16 x i32> @test_ext_v16i32(<16 x i32> %a0, <16 x i32> %a1) nounwind {
 }
 
 define <16 x i32> @test_lsb_v16i32(<16 x i32> %a, <16 x i32> %b) {
-; SSE2-LABEL: test_lsb_v16i32:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm11
-; SSE2-NEXT:    psrad $1, %xmm11
-; SSE2-NEXT:    movdqa %xmm1, %xmm12
-; SSE2-NEXT:    psrad $1, %xmm12
-; SSE2-NEXT:    movdqa %xmm2, %xmm10
-; SSE2-NEXT:    psrad $1, %xmm10
-; SSE2-NEXT:    movdqa %xmm3, %xmm9
-; SSE2-NEXT:    psrad $1, %xmm9
-; SSE2-NEXT:    movdqa {{.*#+}} xmm8 = [1,1,1,1]
-; SSE2-NEXT:    por %xmm4, %xmm0
-; SSE2-NEXT:    psrad $1, %xmm4
-; SSE2-NEXT:    paddd %xmm11, %xmm4
-; SSE2-NEXT:    por %xmm5, %xmm1
-; SSE2-NEXT:    psrad $1, %xmm5
-; SSE2-NEXT:    paddd %xmm12, %xmm5
-; SSE2-NEXT:    por %xmm6, %xmm2
-; SSE2-NEXT:    psrad $1, %xmm6
-; SSE2-NEXT:    paddd %xmm10, %xmm6
-; SSE2-NEXT:    por %xmm7, %xmm3
-; SSE2-NEXT:    psrad $1, %xmm7
-; SSE2-NEXT:    paddd %xmm9, %xmm7
-; SSE2-NEXT:    pand %xmm8, %xmm3
-; SSE2-NEXT:    paddd %xmm7, %xmm3
-; SSE2-NEXT:    pand %xmm8, %xmm2
-; SSE2-NEXT:    paddd %xmm6, %xmm2
-; SSE2-NEXT:    pand %xmm8, %xmm1
-; SSE2-NEXT:    paddd %xmm5, %xmm1
-; SSE2-NEXT:    pand %xmm8, %xmm0
-; SSE2-NEXT:    paddd %xmm4, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE4-LABEL: test_lsb_v16i32:
-; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm11
-; SSE4-NEXT:    psrad $1, %xmm11
-; SSE4-NEXT:    movdqa %xmm1, %xmm12
-; SSE4-NEXT:    psrad $1, %xmm12
-; SSE4-NEXT:    movdqa %xmm2, %xmm10
-; SSE4-NEXT:    psrad $1, %xmm10
-; SSE4-NEXT:    movdqa %xmm3, %xmm9
-; SSE4-NEXT:    psrad $1, %xmm9
-; SSE4-NEXT:    pmovsxbd {{.*#+}} xmm8 = [1,1,1,1]
-; SSE4-NEXT:    por %xmm4, %xmm0
-; SSE4-NEXT:    psrad $1, %xmm4
-; SSE4-NEXT:    paddd %xmm11, %xmm4
-; SSE4-NEXT:    por %xmm5, %xmm1
-; SSE4-NEXT:    psrad $1, %xmm5
-; SSE4-NEXT:    paddd %xmm12, %xmm5
-; SSE4-NEXT:    por %xmm6, %xmm2
-; SSE4-NEXT:    psrad $1, %xmm6
-; SSE4-NEXT:    paddd %xmm10, %xmm6
-; SSE4-NEXT:    por %xmm7, %xmm3
-; SSE4-NEXT:    psrad $1, %xmm7
-; SSE4-NEXT:    paddd %xmm9, %xmm7
-; SSE4-NEXT:    pand %xmm8, %xmm3
-; SSE4-NEXT:    paddd %xmm7, %xmm3
-; SSE4-NEXT:    pand %xmm8, %xmm2
-; SSE4-NEXT:    paddd %xmm6, %xmm2
-; SSE4-NEXT:    pand %xmm8, %xmm1
-; SSE4-NEXT:    paddd %xmm5, %xmm1
-; SSE4-NEXT:    pand %xmm8, %xmm0
-; SSE4-NEXT:    paddd %xmm4, %xmm0
-; SSE4-NEXT:    retq
+; SSE-LABEL: test_lsb_v16i32:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movdqa %xmm4, %xmm8
+; SSE-NEXT:    por %xmm0, %xmm8
+; SSE-NEXT:    pxor %xmm0, %xmm4
+; SSE-NEXT:    psrad $1, %xmm4
+; SSE-NEXT:    psubd %xmm4, %xmm8
+; SSE-NEXT:    movdqa %xmm5, %xmm4
+; SSE-NEXT:    por %xmm1, %xmm4
+; SSE-NEXT:    pxor %xmm1, %xmm5
+; SSE-NEXT:    psrad $1, %xmm5
+; SSE-NEXT:    psubd %xmm5, %xmm4
+; SSE-NEXT:    movdqa %xmm6, %xmm5
+; SSE-NEXT:    por %xmm2, %xmm5
+; SSE-NEXT:    pxor %xmm2, %xmm6
+; SSE-NEXT:    psrad $1, %xmm6
+; SSE-NEXT:    psubd %xmm6, %xmm5
+; SSE-NEXT:    movdqa %xmm7, %xmm6
+; SSE-NEXT:    por %xmm3, %xmm6
+; SSE-NEXT:    pxor %xmm3, %xmm7
+; SSE-NEXT:    psrad $1, %xmm7
+; SSE-NEXT:    psubd %xmm7, %xmm6
+; SSE-NEXT:    movdqa %xmm8, %xmm0
+; SSE-NEXT:    movdqa %xmm4, %xmm1
+; SSE-NEXT:    movdqa %xmm5, %xmm2
+; SSE-NEXT:    movdqa %xmm6, %xmm3
+; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v16i32:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm4
-; AVX1-NEXT:    vpsrad $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpsrad $1, %xmm0, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm6
-; AVX1-NEXT:    vpsrad $1, %xmm6, %xmm6
-; AVX1-NEXT:    vpsrad $1, %xmm1, %xmm7
-; AVX1-NEXT:    vbroadcastss {{.*#+}} ymm8 = [1,1,1,1,1,1,1,1]
-; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm9
-; AVX1-NEXT:    vpsrad $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpaddd %xmm4, %xmm9, %xmm4
-; AVX1-NEXT:    vpsrad $1, %xmm2, %xmm9
-; AVX1-NEXT:    vpaddd %xmm5, %xmm9, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm9
-; AVX1-NEXT:    vpsrad $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpaddd %xmm6, %xmm9, %xmm6
-; AVX1-NEXT:    vpsrad $1, %xmm3, %xmm9
-; AVX1-NEXT:    vpaddd %xmm7, %xmm9, %xmm7
-; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm0
-; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm1
-; AVX1-NEXT:    vandps %ymm1, %ymm8, %ymm1
-; AVX1-NEXT:    vandps %ymm0, %ymm8, %ymm0
+; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm4
+; AVX1-NEXT:    vextractf128 $1, %ymm4, %xmm5
+; AVX1-NEXT:    vxorps %ymm0, %ymm2, %ymm0
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpaddd %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpaddd %xmm0, %xmm5, %xmm0
+; AVX1-NEXT:    vpsrad $1, %xmm2, %xmm2
+; AVX1-NEXT:    vpsubd %xmm2, %xmm5, %xmm2
+; AVX1-NEXT:    vpsrad $1, %xmm0, %xmm0
+; AVX1-NEXT:    vpsubd %xmm0, %xmm4, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
-; AVX1-NEXT:    vpaddd %xmm2, %xmm6, %xmm2
-; AVX1-NEXT:    vpaddd %xmm1, %xmm7, %xmm1
-; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
+; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
+; AVX1-NEXT:    vxorps %ymm1, %ymm3, %ymm1
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
+; AVX1-NEXT:    vpsrad $1, %xmm3, %xmm3
+; AVX1-NEXT:    vpsubd %xmm3, %xmm4, %xmm3
+; AVX1-NEXT:    vpsrad $1, %xmm1, %xmm1
+; AVX1-NEXT:    vpsubd %xmm1, %xmm2, %xmm1
+; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm1, %ymm1
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v16i32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrad $1, %ymm0, %ymm4
-; AVX2-NEXT:    vpsrad $1, %ymm1, %ymm5
-; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm6 = [1,1,1,1,1,1,1,1]
-; AVX2-NEXT:    vpsrad $1, %ymm2, %ymm7
-; AVX2-NEXT:    vpaddd %ymm4, %ymm7, %ymm4
-; AVX2-NEXT:    vpsrad $1, %ymm3, %ymm7
-; AVX2-NEXT:    vpaddd %ymm5, %ymm7, %ymm5
-; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm0
-; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm1, %ymm1
-; AVX2-NEXT:    vpaddd %ymm1, %ymm5, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddd %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm4
+; AVX2-NEXT:    vpxor %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpsrad $1, %ymm0, %ymm0
+; AVX2-NEXT:    vpsubd %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm2
+; AVX2-NEXT:    vpxor %ymm1, %ymm3, %ymm1
+; AVX2-NEXT:    vpsrad $1, %ymm1, %ymm1
+; AVX2-NEXT:    vpsubd %ymm1, %ymm2, %ymm1
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v16i32:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrad $1, %zmm0, %zmm2
-; AVX512-NEXT:    vpsrad $1, %zmm1, %zmm3
-; AVX512-NEXT:    vpaddd %zmm2, %zmm3, %zmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} zmm0 = m32bcst & (zmm0 | zmm1)
-; AVX512-NEXT:    vpaddd %zmm0, %zmm2, %zmm0
+; AVX512-NEXT:    vpord %zmm0, %zmm1, %zmm2
+; AVX512-NEXT:    vpxord %zmm0, %zmm1, %zmm0
+; AVX512-NEXT:    vpsrad $1, %zmm0, %zmm0
+; AVX512-NEXT:    vpsubd %zmm0, %zmm2, %zmm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = ashr <16 x i32> %a, splat (i32 1)
   %b_shr_1 = ashr <16 x i32> %b, splat (i32 1)
@@ -2638,207 +2191,132 @@ define <8 x i64> @test_ext_v8i64(<8 x i64> %a0, <8 x i64> %a1) nounwind {
 define <8 x i64> @test_lsb_v8i64(<8 x i64> %a, <8 x i64> %b) {
 ; SSE2-LABEL: test_lsb_v8i64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    pshufd {{.*#+}} xmm8 = xmm0[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm8
-; SSE2-NEXT:    movdqa %xmm0, %xmm9
-; SSE2-NEXT:    psrlq $1, %xmm9
-; SSE2-NEXT:    pshufd {{.*#+}} xmm12 = xmm9[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm12 = xmm12[0],xmm8[0],xmm12[1],xmm8[1]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm8 = xmm1[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm8
-; SSE2-NEXT:    movdqa %xmm1, %xmm9
-; SSE2-NEXT:    psrlq $1, %xmm9
-; SSE2-NEXT:    pshufd {{.*#+}} xmm11 = xmm9[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm11 = xmm11[0],xmm8[0],xmm11[1],xmm8[1]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm8 = xmm2[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm8
-; SSE2-NEXT:    movdqa %xmm2, %xmm9
-; SSE2-NEXT:    psrlq $1, %xmm9
-; SSE2-NEXT:    pshufd {{.*#+}} xmm10 = xmm9[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm10 = xmm10[0],xmm8[0],xmm10[1],xmm8[1]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm8 = xmm3[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm8
-; SSE2-NEXT:    movdqa %xmm3, %xmm9
-; SSE2-NEXT:    psrlq $1, %xmm9
-; SSE2-NEXT:    pshufd {{.*#+}} xmm9 = xmm9[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm9 = xmm9[0],xmm8[0],xmm9[1],xmm8[1]
-; SSE2-NEXT:    movdqa {{.*#+}} xmm8 = [1,1]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm13 = xmm4[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm13
+; SSE2-NEXT:    movdqa %xmm4, %xmm8
+; SSE2-NEXT:    pxor %xmm0, %xmm8
+; SSE2-NEXT:    pshufd {{.*#+}} xmm9 = xmm8[1,3,2,3]
+; SSE2-NEXT:    psrad $1, %xmm9
+; SSE2-NEXT:    psrlq $1, %xmm8
+; SSE2-NEXT:    pshufd {{.*#+}} xmm8 = xmm8[0,2,2,3]
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm8 = xmm8[0],xmm9[0],xmm8[1],xmm9[1]
 ; SSE2-NEXT:    por %xmm4, %xmm0
+; SSE2-NEXT:    psubq %xmm8, %xmm0
+; SSE2-NEXT:    movdqa %xmm5, %xmm4
+; SSE2-NEXT:    pxor %xmm1, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm8 = xmm4[1,3,2,3]
+; SSE2-NEXT:    psrad $1, %xmm8
 ; SSE2-NEXT:    psrlq $1, %xmm4
 ; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm13[0],xmm4[1],xmm13[1]
-; SSE2-NEXT:    paddq %xmm12, %xmm4
-; SSE2-NEXT:    pshufd {{.*#+}} xmm12 = xmm5[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm12
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm8[0],xmm4[1],xmm8[1]
 ; SSE2-NEXT:    por %xmm5, %xmm1
-; SSE2-NEXT:    psrlq $1, %xmm5
-; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm5 = xmm5[0],xmm12[0],xmm5[1],xmm12[1]
-; SSE2-NEXT:    paddq %xmm11, %xmm5
-; SSE2-NEXT:    pshufd {{.*#+}} xmm11 = xmm6[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm11
+; SSE2-NEXT:    psubq %xmm4, %xmm1
+; SSE2-NEXT:    movdqa %xmm6, %xmm4
+; SSE2-NEXT:    pxor %xmm2, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[1,3,2,3]
+; SSE2-NEXT:    psrad $1, %xmm5
+; SSE2-NEXT:    psrlq $1, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm5[0],xmm4[1],xmm5[1]
 ; SSE2-NEXT:    por %xmm6, %xmm2
-; SSE2-NEXT:    psrlq $1, %xmm6
-; SSE2-NEXT:    pshufd {{.*#+}} xmm6 = xmm6[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm6 = xmm6[0],xmm11[0],xmm6[1],xmm11[1]
-; SSE2-NEXT:    paddq %xmm10, %xmm6
-; SSE2-NEXT:    pshufd {{.*#+}} xmm10 = xmm7[1,3,2,3]
-; SSE2-NEXT:    psrad $1, %xmm10
+; SSE2-NEXT:    psubq %xmm4, %xmm2
+; SSE2-NEXT:    movdqa %xmm7, %xmm4
+; SSE2-NEXT:    pxor %xmm3, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[1,3,2,3]
+; SSE2-NEXT:    psrad $1, %xmm5
+; SSE2-NEXT:    psrlq $1, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm5[0],xmm4[1],xmm5[1]
 ; SSE2-NEXT:    por %xmm7, %xmm3
-; SSE2-NEXT:    psrlq $1, %xmm7
-; SSE2-NEXT:    pshufd {{.*#+}} xmm7 = xmm7[0,2,2,3]
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm7 = xmm7[0],xmm10[0],xmm7[1],xmm10[1]
-; SSE2-NEXT:    paddq %xmm9, %xmm7
-; SSE2-NEXT:    pand %xmm8, %xmm3
-; SSE2-NEXT:    paddq %xmm7, %xmm3
-; SSE2-NEXT:    pand %xmm8, %xmm2
-; SSE2-NEXT:    paddq %xmm6, %xmm2
-; SSE2-NEXT:    pand %xmm8, %xmm1
-; SSE2-NEXT:    paddq %xmm5, %xmm1
-; SSE2-NEXT:    pand %xmm8, %xmm0
-; SSE2-NEXT:    paddq %xmm4, %xmm0
+; SSE2-NEXT:    psubq %xmm4, %xmm3
 ; SSE2-NEXT:    retq
 ;
 ; SSE4-LABEL: test_lsb_v8i64:
 ; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm8
-; SSE4-NEXT:    psrad $1, %xmm8
-; SSE4-NEXT:    movdqa %xmm0, %xmm13
-; SSE4-NEXT:    psrlq $1, %xmm13
-; SSE4-NEXT:    pblendw {{.*#+}} xmm13 = xmm13[0,1],xmm8[2,3],xmm13[4,5],xmm8[6,7]
-; SSE4-NEXT:    movdqa %xmm1, %xmm8
-; SSE4-NEXT:    psrad $1, %xmm8
-; SSE4-NEXT:    movdqa %xmm1, %xmm12
-; SSE4-NEXT:    psrlq $1, %xmm12
-; SSE4-NEXT:    pblendw {{.*#+}} xmm12 = xmm12[0,1],xmm8[2,3],xmm12[4,5],xmm8[6,7]
-; SSE4-NEXT:    movdqa %xmm2, %xmm8
-; SSE4-NEXT:    psrad $1, %xmm8
-; SSE4-NEXT:    movdqa %xmm2, %xmm11
-; SSE4-NEXT:    psrlq $1, %xmm11
-; SSE4-NEXT:    pblendw {{.*#+}} xmm11 = xmm11[0,1],xmm8[2,3],xmm11[4,5],xmm8[6,7]
-; SSE4-NEXT:    movdqa %xmm3, %xmm8
-; SSE4-NEXT:    psrad $1, %xmm8
-; SSE4-NEXT:    movdqa %xmm3, %xmm10
-; SSE4-NEXT:    psrlq $1, %xmm10
-; SSE4-NEXT:    pblendw {{.*#+}} xmm10 = xmm10[0,1],xmm8[2,3],xmm10[4,5],xmm8[6,7]
-; SSE4-NEXT:    pmovsxbq {{.*#+}} xmm8 = [1,1]
-; SSE4-NEXT:    movdqa %xmm4, %xmm9
+; SSE4-NEXT:    movdqa %xmm4, %xmm8
+; SSE4-NEXT:    pxor %xmm0, %xmm8
+; SSE4-NEXT:    movdqa %xmm8, %xmm9
+; SSE4-NEXT:    psrad $1, %xmm9
+; SSE4-NEXT:    psrlq $1, %xmm8
+; SSE4-NEXT:    pblendw {{.*#+}} xmm8 = xmm8[0,1],xmm9[2,3],xmm8[4,5],xmm9[6,7]
 ; SSE4-NEXT:    por %xmm4, %xmm0
-; SSE4-NEXT:    psrad $1, %xmm4
-; SSE4-NEXT:    psrlq $1, %xmm9
-; SSE4-NEXT:    pblendw {{.*#+}} xmm9 = xmm9[0,1],xmm4[2,3],xmm9[4,5],xmm4[6,7]
-; SSE4-NEXT:    paddq %xmm13, %xmm9
+; SSE4-NEXT:    psubq %xmm8, %xmm0
 ; SSE4-NEXT:    movdqa %xmm5, %xmm4
+; SSE4-NEXT:    pxor %xmm1, %xmm4
+; SSE4-NEXT:    movdqa %xmm4, %xmm8
+; SSE4-NEXT:    psrad $1, %xmm8
+; SSE4-NEXT:    psrlq $1, %xmm4
+; SSE4-NEXT:    pblendw {{.*#+}} xmm4 = xmm4[0,1],xmm8[2,3],xmm4[4,5],xmm8[6,7]
 ; SSE4-NEXT:    por %xmm5, %xmm1
+; SSE4-NEXT:    psubq %xmm4, %xmm1
+; SSE4-NEXT:    movdqa %xmm6, %xmm4
+; SSE4-NEXT:    pxor %xmm2, %xmm4
+; SSE4-NEXT:    movdqa %xmm4, %xmm5
 ; SSE4-NEXT:    psrad $1, %xmm5
 ; SSE4-NEXT:    psrlq $1, %xmm4
 ; SSE4-NEXT:    pblendw {{.*#+}} xmm4 = xmm4[0,1],xmm5[2,3],xmm4[4,5],xmm5[6,7]
-; SSE4-NEXT:    paddq %xmm12, %xmm4
-; SSE4-NEXT:    movdqa %xmm6, %xmm5
 ; SSE4-NEXT:    por %xmm6, %xmm2
-; SSE4-NEXT:    psrad $1, %xmm6
-; SSE4-NEXT:    psrlq $1, %xmm5
-; SSE4-NEXT:    pblendw {{.*#+}} xmm5 = xmm5[0,1],xmm6[2,3],xmm5[4,5],xmm6[6,7]
-; SSE4-NEXT:    paddq %xmm11, %xmm5
-; SSE4-NEXT:    movdqa %xmm7, %xmm6
+; SSE4-NEXT:    psubq %xmm4, %xmm2
+; SSE4-NEXT:    movdqa %xmm7, %xmm4
+; SSE4-NEXT:    pxor %xmm3, %xmm4
+; SSE4-NEXT:    movdqa %xmm4, %xmm5
+; SSE4-NEXT:    psrad $1, %xmm5
+; SSE4-NEXT:    psrlq $1, %xmm4
+; SSE4-NEXT:    pblendw {{.*#+}} xmm4 = xmm4[0,1],xmm5[2,3],xmm4[4,5],xmm5[6,7]
 ; SSE4-NEXT:    por %xmm7, %xmm3
-; SSE4-NEXT:    psrad $1, %xmm7
-; SSE4-NEXT:    psrlq $1, %xmm6
-; SSE4-NEXT:    pblendw {{.*#+}} xmm6 = xmm6[0,1],xmm7[2,3],xmm6[4,5],xmm7[6,7]
-; SSE4-NEXT:    paddq %xmm10, %xmm6
-; SSE4-NEXT:    pand %xmm8, %xmm3
-; SSE4-NEXT:    paddq %xmm6, %xmm3
-; SSE4-NEXT:    pand %xmm8, %xmm2
-; SSE4-NEXT:    paddq %xmm5, %xmm2
-; SSE4-NEXT:    pand %xmm8, %xmm1
-; SSE4-NEXT:    paddq %xmm4, %xmm1
-; SSE4-NEXT:    pand %xmm8, %xmm0
-; SSE4-NEXT:    paddq %xmm9, %xmm0
+; SSE4-NEXT:    psubq %xmm4, %xmm3
 ; SSE4-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v8i64:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm4
+; AVX1-NEXT:    vxorps %ymm0, %ymm2, %ymm4
+; AVX1-NEXT:    vextractf128 $1, %ymm4, %xmm5
+; AVX1-NEXT:    vpsrad $1, %xmm5, %xmm6
+; AVX1-NEXT:    vpsrlq $1, %xmm5, %xmm5
+; AVX1-NEXT:    vpblendw {{.*#+}} xmm5 = xmm5[0,1],xmm6[2,3],xmm5[4,5],xmm6[6,7]
+; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm0
+; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
+; AVX1-NEXT:    vpsubq %xmm5, %xmm2, %xmm2
 ; AVX1-NEXT:    vpsrad $1, %xmm4, %xmm5
 ; AVX1-NEXT:    vpsrlq $1, %xmm4, %xmm4
 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm4 = xmm4[0,1],xmm5[2,3],xmm4[4,5],xmm5[6,7]
-; AVX1-NEXT:    vpsrad $1, %xmm0, %xmm5
-; AVX1-NEXT:    vpsrlq $1, %xmm0, %xmm6
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm5 = xmm6[0,1],xmm5[2,3],xmm6[4,5],xmm5[6,7]
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm6
-; AVX1-NEXT:    vpsrad $1, %xmm6, %xmm7
-; AVX1-NEXT:    vpsrlq $1, %xmm6, %xmm6
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm6 = xmm6[0,1],xmm7[2,3],xmm6[4,5],xmm7[6,7]
-; AVX1-NEXT:    vpsrad $1, %xmm1, %xmm7
-; AVX1-NEXT:    vpsrlq $1, %xmm1, %xmm8
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm7 = xmm8[0,1],xmm7[2,3],xmm8[4,5],xmm7[6,7]
-; AVX1-NEXT:    vbroadcastsd {{.*#+}} ymm8 = [1,1,1,1]
-; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm9
-; AVX1-NEXT:    vpsrad $1, %xmm9, %xmm10
-; AVX1-NEXT:    vpsrlq $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm9 = xmm9[0,1],xmm10[2,3],xmm9[4,5],xmm10[6,7]
-; AVX1-NEXT:    vpaddq %xmm4, %xmm9, %xmm4
-; AVX1-NEXT:    vpsrad $1, %xmm2, %xmm9
-; AVX1-NEXT:    vpsrlq $1, %xmm2, %xmm10
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm9 = xmm10[0,1],xmm9[2,3],xmm10[4,5],xmm9[6,7]
-; AVX1-NEXT:    vpaddq %xmm5, %xmm9, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm9
-; AVX1-NEXT:    vpsrad $1, %xmm9, %xmm10
-; AVX1-NEXT:    vpsrlq $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm9 = xmm9[0,1],xmm10[2,3],xmm9[4,5],xmm10[6,7]
-; AVX1-NEXT:    vpaddq %xmm6, %xmm9, %xmm6
-; AVX1-NEXT:    vpsrad $1, %xmm3, %xmm9
-; AVX1-NEXT:    vpsrlq $1, %xmm3, %xmm10
-; AVX1-NEXT:    vpblendw {{.*#+}} xmm9 = xmm10[0,1],xmm9[2,3],xmm10[4,5],xmm9[6,7]
-; AVX1-NEXT:    vpaddq %xmm7, %xmm9, %xmm7
-; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm0
-; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm1
-; AVX1-NEXT:    vandps %ymm1, %ymm8, %ymm1
-; AVX1-NEXT:    vandps %ymm0, %ymm8, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpaddq %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpaddq %xmm0, %xmm5, %xmm0
+; AVX1-NEXT:    vpsubq %xmm4, %xmm0, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
-; AVX1-NEXT:    vpaddq %xmm2, %xmm6, %xmm2
-; AVX1-NEXT:    vpaddq %xmm1, %xmm7, %xmm1
-; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
+; AVX1-NEXT:    vxorps %ymm1, %ymm3, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
+; AVX1-NEXT:    vpsrad $1, %xmm4, %xmm5
+; AVX1-NEXT:    vpsrlq $1, %xmm4, %xmm4
+; AVX1-NEXT:    vpblendw {{.*#+}} xmm4 = xmm4[0,1],xmm5[2,3],xmm4[4,5],xmm5[6,7]
+; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm1
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
+; AVX1-NEXT:    vpsubq %xmm4, %xmm3, %xmm3
+; AVX1-NEXT:    vpsrad $1, %xmm2, %xmm4
+; AVX1-NEXT:    vpsrlq $1, %xmm2, %xmm2
+; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm2[0,1],xmm4[2,3],xmm2[4,5],xmm4[6,7]
+; AVX1-NEXT:    vpsubq %xmm2, %xmm1, %xmm1
+; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm1, %ymm1
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v8i64:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrad $1, %ymm0, %ymm4
-; AVX2-NEXT:    vpsrlq $1, %ymm0, %ymm5
-; AVX2-NEXT:    vpblendd {{.*#+}} ymm4 = ymm5[0],ymm4[1],ymm5[2],ymm4[3],ymm5[4],ymm4[5],ymm5[6],ymm4[7]
-; AVX2-NEXT:    vpsrad $1, %ymm1, %ymm5
-; AVX2-NEXT:    vpsrlq $1, %ymm1, %ymm6
-; AVX2-NEXT:    vpblendd {{.*#+}} ymm5 = ymm6[0],ymm5[1],ymm6[2],ymm5[3],ymm6[4],ymm5[5],ymm6[6],ymm5[7]
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm6 = [1,1,1,1]
-; AVX2-NEXT:    vpsrad $1, %ymm2, %ymm7
-; AVX2-NEXT:    vpsrlq $1, %ymm2, %ymm8
-; AVX2-NEXT:    vpblendd {{.*#+}} ymm7 = ymm8[0],ymm7[1],ymm8[2],ymm7[3],ymm8[4],ymm7[5],ymm8[6],ymm7[7]
-; AVX2-NEXT:    vpaddq %ymm4, %ymm7, %ymm4
-; AVX2-NEXT:    vpsrad $1, %ymm3, %ymm7
-; AVX2-NEXT:    vpsrlq $1, %ymm3, %ymm8
-; AVX2-NEXT:    vpblendd {{.*#+}} ymm7 = ymm8[0],ymm7[1],ymm8[2],ymm7[3],ymm8[4],ymm7[5],ymm8[6],ymm7[7]
-; AVX2-NEXT:    vpaddq %ymm5, %ymm7, %ymm5
+; AVX2-NEXT:    vpxor %ymm0, %ymm2, %ymm4
+; AVX2-NEXT:    vpsrad $1, %ymm4, %ymm5
+; AVX2-NEXT:    vpsrlq $1, %ymm4, %ymm4
+; AVX2-NEXT:    vpblendd {{.*#+}} ymm4 = ymm4[0],ymm5[1],ymm4[2],ymm5[3],ymm4[4],ymm5[5],ymm4[6],ymm5[7]
 ; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpsubq %ymm4, %ymm0, %ymm0
+; AVX2-NEXT:    vpxor %ymm1, %ymm3, %ymm2
+; AVX2-NEXT:    vpsrad $1, %ymm2, %ymm4
+; AVX2-NEXT:    vpsrlq $1, %ymm2, %ymm2
+; AVX2-NEXT:    vpblendd {{.*#+}} ymm2 = ymm2[0],ymm4[1],ymm2[2],ymm4[3],ymm2[4],ymm4[5],ymm2[6],ymm4[7]
 ; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm1, %ymm1
-; AVX2-NEXT:    vpaddq %ymm1, %ymm5, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddq %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpsubq %ymm2, %ymm1, %ymm1
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v8i64:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsraq $1, %zmm0, %zmm2
-; AVX512-NEXT:    vpsraq $1, %zmm1, %zmm3
-; AVX512-NEXT:    vpaddq %zmm2, %zmm3, %zmm2
-; AVX512-NEXT:    vpternlogq {{.*#+}} zmm0 = m64bcst & (zmm0 | zmm1)
-; AVX512-NEXT:    vpaddq %zmm0, %zmm2, %zmm0
+; AVX512-NEXT:    vporq %zmm0, %zmm1, %zmm2
+; AVX512-NEXT:    vpxorq %zmm0, %zmm1, %zmm0
+; AVX512-NEXT:    vpsraq $1, %zmm0, %zmm0
+; AVX512-NEXT:    vpsubq %zmm0, %zmm2, %zmm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = ashr <8 x i64> %a, splat (i64 1)
   %b_shr_1 = ashr <8 x i64> %b, splat (i64 1)
diff --git a/llvm/test/CodeGen/X86/avgceilu.ll b/llvm/test/CodeGen/X86/avgceilu.ll
index ffbcc262ff96d..23b26e57ce19d 100644
--- a/llvm/test/CodeGen/X86/avgceilu.ll
+++ b/llvm/test/CodeGen/X86/avgceilu.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE2
-; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE4
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse2 | FileCheck %s --check-prefixes=SSE
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE
 ; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1
 ; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2
 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=AVX,AVX512
@@ -48,55 +48,13 @@ define <16 x i8> @test_ext_v16i8(<16 x i8> %a0, <16 x i8> %a1) nounwind {
 define <16 x i8> @test_lsb_v16i8(<16 x i8> %a, <16 x i8> %b) {
 ; SSE-LABEL: test_lsb_v16i8:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm2
-; SSE-NEXT:    psrlw $1, %xmm2
-; SSE-NEXT:    movdqa {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; SSE-NEXT:    pand %xmm3, %xmm2
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    psrlw $1, %xmm1
-; SSE-NEXT:    pand %xmm3, %xmm1
-; SSE-NEXT:    paddb %xmm2, %xmm1
-; SSE-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    paddb %xmm1, %xmm0
+; SSE-NEXT:    pavgb %xmm1, %xmm0
 ; SSE-NEXT:    retq
 ;
-; AVX1-LABEL: test_lsb_v16i8:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm2
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX1-NEXT:    vpand %xmm3, %xmm2, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm1, %xmm4
-; AVX1-NEXT:    vpand %xmm3, %xmm4, %xmm3
-; AVX1-NEXT:    vpaddb %xmm2, %xmm3, %xmm2
-; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX1-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX1-NEXT:    vpaddb %xmm0, %xmm2, %xmm0
-; AVX1-NEXT:    retq
-;
-; AVX2-LABEL: test_lsb_v16i8:
-; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlw $1, %xmm0, %xmm2
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX2-NEXT:    vpand %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vpsrlw $1, %xmm1, %xmm4
-; AVX2-NEXT:    vpand %xmm3, %xmm4, %xmm3
-; AVX2-NEXT:    vpaddb %xmm2, %xmm3, %xmm2
-; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX2-NEXT:    vpaddb %xmm0, %xmm2, %xmm0
-; AVX2-NEXT:    retq
-;
-; AVX512-LABEL: test_lsb_v16i8:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrlw $1, %xmm0, %xmm2
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX512-NEXT:    vpand %xmm3, %xmm2, %xmm2
-; AVX512-NEXT:    vpsrlw $1, %xmm1, %xmm4
-; AVX512-NEXT:    vpand %xmm3, %xmm4, %xmm3
-; AVX512-NEXT:    vpaddb %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = m32bcst & (xmm0 | xmm1)
-; AVX512-NEXT:    vpaddb %xmm0, %xmm2, %xmm0
-; AVX512-NEXT:    retq
+; AVX-LABEL: test_lsb_v16i8:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vpavgb %xmm0, %xmm1, %xmm0
+; AVX-NEXT:    retq
   %a_shr_1 = lshr <16 x i8> %a, splat (i8 1)
   %b_shr_1 = lshr <16 x i8> %b, splat (i8 1)
   %a_or_b = or <16 x i8> %b, %a
@@ -145,43 +103,13 @@ define <8 x i16> @test_ext_v8i16(<8 x i16> %a0, <8 x i16> %a1) nounwind {
 define <8 x i16> @test_lsb_v8i16(<8 x i16> %a, <8 x i16> %b) {
 ; SSE-LABEL: test_lsb_v8i16:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm2
-; SSE-NEXT:    psrlw $1, %xmm2
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    psrlw $1, %xmm1
-; SSE-NEXT:    paddw %xmm2, %xmm1
-; SSE-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    paddw %xmm1, %xmm0
+; SSE-NEXT:    pavgw %xmm1, %xmm0
 ; SSE-NEXT:    retq
 ;
-; AVX1-LABEL: test_lsb_v8i16:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm1, %xmm3
-; AVX1-NEXT:    vpaddw %xmm2, %xmm3, %xmm2
-; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX1-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX1-NEXT:    vpaddw %xmm0, %xmm2, %xmm0
-; AVX1-NEXT:    retq
-;
-; AVX2-LABEL: test_lsb_v8i16:
-; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlw $1, %xmm0, %xmm2
-; AVX2-NEXT:    vpsrlw $1, %xmm1, %xmm3
-; AVX2-NEXT:    vpaddw %xmm2, %xmm3, %xmm2
-; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX2-NEXT:    vpaddw %xmm0, %xmm2, %xmm0
-; AVX2-NEXT:    retq
-;
-; AVX512-LABEL: test_lsb_v8i16:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrlw $1, %xmm0, %xmm2
-; AVX512-NEXT:    vpsrlw $1, %xmm1, %xmm3
-; AVX512-NEXT:    vpaddw %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = m32bcst & (xmm0 | xmm1)
-; AVX512-NEXT:    vpaddw %xmm0, %xmm2, %xmm0
-; AVX512-NEXT:    retq
+; AVX-LABEL: test_lsb_v8i16:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vpavgw %xmm0, %xmm1, %xmm0
+; AVX-NEXT:    retq
   %a_shr_1 = lshr <8 x i16> %a, splat (i16 1)
   %b_shr_1 = lshr <8 x i16> %b, splat (i16 1)
   %a_or_b = or <8 x i16> %b, %a
@@ -246,44 +174,21 @@ define <4 x i32> @test_ext_v4i32(<4 x i32> %a0, <4 x i32> %a1) nounwind {
 define <4 x i32> @test_lsb_v4i32(<4 x i32> %a, <4 x i32> %b) {
 ; SSE-LABEL: test_lsb_v4i32:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm2
-; SSE-NEXT:    psrld $1, %xmm2
-; SSE-NEXT:    por %xmm1, %xmm0
+; SSE-NEXT:    movdqa %xmm1, %xmm2
+; SSE-NEXT:    por %xmm0, %xmm2
+; SSE-NEXT:    pxor %xmm0, %xmm1
 ; SSE-NEXT:    psrld $1, %xmm1
-; SSE-NEXT:    paddd %xmm2, %xmm1
-; SSE-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    paddd %xmm1, %xmm0
+; SSE-NEXT:    psubd %xmm1, %xmm2
+; SSE-NEXT:    movdqa %xmm2, %xmm0
 ; SSE-NEXT:    retq
 ;
-; AVX1-LABEL: test_lsb_v4i32:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vpsrld $1, %xmm0, %xmm2
-; AVX1-NEXT:    vpsrld $1, %xmm1, %xmm3
-; AVX1-NEXT:    vpaddd %xmm2, %xmm3, %xmm2
-; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX1-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX1-NEXT:    vpaddd %xmm0, %xmm2, %xmm0
-; AVX1-NEXT:    retq
-;
-; AVX2-LABEL: test_lsb_v4i32:
-; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrld $1, %xmm0, %xmm2
-; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm3 = [1,1,1,1]
-; AVX2-NEXT:    vpsrld $1, %xmm1, %xmm4
-; AVX2-NEXT:    vpaddd %xmm2, %xmm4, %xmm2
-; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX2-NEXT:    vpand %xmm3, %xmm0, %xmm0
-; AVX2-NEXT:    vpaddd %xmm0, %xmm2, %xmm0
-; AVX2-NEXT:    retq
-;
-; AVX512-LABEL: test_lsb_v4i32:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrld $1, %xmm0, %xmm2
-; AVX512-NEXT:    vpsrld $1, %xmm1, %xmm3
-; AVX512-NEXT:    vpaddd %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = m32bcst & (xmm0 | xmm1)
-; AVX512-NEXT:    vpaddd %xmm0, %xmm2, %xmm0
-; AVX512-NEXT:    retq
+; AVX-LABEL: test_lsb_v4i32:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm2
+; AVX-NEXT:    vpxor %xmm0, %xmm1, %xmm0
+; AVX-NEXT:    vpsrld $1, %xmm0, %xmm0
+; AVX-NEXT:    vpsubd %xmm0, %xmm2, %xmm0
+; AVX-NEXT:    retq
   %a_shr_1 = lshr <4 x i32> %a, splat (i32 1)
   %b_shr_1 = lshr <4 x i32> %b, splat (i32 1)
   %a_or_b = or <4 x i32> %b, %a
@@ -348,43 +253,21 @@ define <2 x i64> @test_ext_v2i64(<2 x i64> %a0, <2 x i64> %a1) nounwind {
 define <2 x i64> @test_lsb_v2i64(<2 x i64> %a, <2 x i64> %b) {
 ; SSE-LABEL: test_lsb_v2i64:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm2
-; SSE-NEXT:    psrlq $1, %xmm2
-; SSE-NEXT:    por %xmm1, %xmm0
+; SSE-NEXT:    movdqa %xmm1, %xmm2
+; SSE-NEXT:    por %xmm0, %xmm2
+; SSE-NEXT:    pxor %xmm0, %xmm1
 ; SSE-NEXT:    psrlq $1, %xmm1
-; SSE-NEXT:    paddq %xmm2, %xmm1
-; SSE-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    paddq %xmm1, %xmm0
+; SSE-NEXT:    psubq %xmm1, %xmm2
+; SSE-NEXT:    movdqa %xmm2, %xmm0
 ; SSE-NEXT:    retq
 ;
-; AVX1-LABEL: test_lsb_v2i64:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vpsrlq $1, %xmm0, %xmm2
-; AVX1-NEXT:    vpsrlq $1, %xmm1, %xmm3
-; AVX1-NEXT:    vpaddq %xmm2, %xmm3, %xmm2
-; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX1-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX1-NEXT:    vpaddq %xmm0, %xmm2, %xmm0
-; AVX1-NEXT:    retq
-;
-; AVX2-LABEL: test_lsb_v2i64:
-; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlq $1, %xmm0, %xmm2
-; AVX2-NEXT:    vpsrlq $1, %xmm1, %xmm3
-; AVX2-NEXT:    vpaddq %xmm2, %xmm3, %xmm2
-; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; AVX2-NEXT:    vpaddq %xmm0, %xmm2, %xmm0
-; AVX2-NEXT:    retq
-;
-; AVX512-LABEL: test_lsb_v2i64:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrlq $1, %xmm0, %xmm2
-; AVX512-NEXT:    vpsrlq $1, %xmm1, %xmm3
-; AVX512-NEXT:    vpaddq %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vpternlogq {{.*#+}} xmm0 = m64bcst & (xmm0 | xmm1)
-; AVX512-NEXT:    vpaddq %xmm0, %xmm2, %xmm0
-; AVX512-NEXT:    retq
+; AVX-LABEL: test_lsb_v2i64:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm2
+; AVX-NEXT:    vpxor %xmm0, %xmm1, %xmm0
+; AVX-NEXT:    vpsrlq $1, %xmm0, %xmm0
+; AVX-NEXT:    vpsubq %xmm0, %xmm2, %xmm0
+; AVX-NEXT:    retq
   %a_shr_1 = lshr <2 x i64> %a, splat (i64 1)
   %b_shr_1 = lshr <2 x i64> %b, splat (i64 1)
   %a_or_b = or <2 x i64> %b, %a
@@ -467,74 +350,27 @@ define <32 x i8> @test_ext_v32i8(<32 x i8> %a0, <32 x i8> %a1) nounwind {
 define <32 x i8> @test_lsb_v32i8(<32 x i8> %a, <32 x i8> %b) {
 ; SSE-LABEL: test_lsb_v32i8:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm4
-; SSE-NEXT:    psrlw $1, %xmm4
-; SSE-NEXT:    movdqa {{.*#+}} xmm5 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; SSE-NEXT:    pand %xmm5, %xmm4
-; SSE-NEXT:    movdqa %xmm1, %xmm6
-; SSE-NEXT:    psrlw $1, %xmm6
-; SSE-NEXT:    pand %xmm5, %xmm6
-; SSE-NEXT:    movdqa {{.*#+}} xmm7 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; SSE-NEXT:    por %xmm2, %xmm0
-; SSE-NEXT:    psrlw $1, %xmm2
-; SSE-NEXT:    pand %xmm5, %xmm2
-; SSE-NEXT:    paddb %xmm4, %xmm2
-; SSE-NEXT:    por %xmm3, %xmm1
-; SSE-NEXT:    psrlw $1, %xmm3
-; SSE-NEXT:    pand %xmm5, %xmm3
-; SSE-NEXT:    paddb %xmm6, %xmm3
-; SSE-NEXT:    pand %xmm7, %xmm1
-; SSE-NEXT:    paddb %xmm3, %xmm1
-; SSE-NEXT:    pand %xmm7, %xmm0
-; SSE-NEXT:    paddb %xmm2, %xmm0
+; SSE-NEXT:    pavgb %xmm2, %xmm0
+; SSE-NEXT:    pavgb %xmm3, %xmm1
 ; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v32i8:
 ; AVX1:       # %bb.0:
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm2, %xmm2
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX1-NEXT:    vpand %xmm3, %xmm2, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm4
-; AVX1-NEXT:    vpand %xmm3, %xmm4, %xmm4
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm5
-; AVX1-NEXT:    vpsrlw $1, %xmm5, %xmm5
-; AVX1-NEXT:    vpand %xmm3, %xmm5, %xmm5
-; AVX1-NEXT:    vpaddb %xmm2, %xmm5, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm1, %xmm5
-; AVX1-NEXT:    vpand %xmm3, %xmm5, %xmm3
-; AVX1-NEXT:    vpaddb %xmm4, %xmm3, %xmm3
-; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm0
-; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
-; AVX1-NEXT:    vpaddb %xmm1, %xmm2, %xmm1
-; AVX1-NEXT:    vpaddb %xmm0, %xmm3, %xmm0
-; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
+; AVX1-NEXT:    vpavgb %xmm2, %xmm3, %xmm2
+; AVX1-NEXT:    vpavgb %xmm0, %xmm1, %xmm0
+; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v32i8:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlw $1, %ymm0, %ymm2
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX2-NEXT:    vpand %ymm3, %ymm2, %ymm2
-; AVX2-NEXT:    vpsrlw $1, %ymm1, %ymm4
-; AVX2-NEXT:    vpand %ymm3, %ymm4, %ymm3
-; AVX2-NEXT:    vpaddb %ymm2, %ymm3, %ymm2
-; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
-; AVX2-NEXT:    vpaddb %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpavgb %ymm0, %ymm1, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v32i8:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrlw $1, %ymm0, %ymm2
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} ymm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX512-NEXT:    vpand %ymm3, %ymm2, %ymm2
-; AVX512-NEXT:    vpsrlw $1, %ymm1, %ymm4
-; AVX512-NEXT:    vpand %ymm3, %ymm4, %ymm3
-; AVX512-NEXT:    vpaddb %ymm2, %ymm3, %ymm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} ymm0 = m32bcst & (ymm0 | ymm1)
-; AVX512-NEXT:    vpaddb %ymm0, %ymm2, %ymm0
+; AVX512-NEXT:    vpavgb %ymm0, %ymm1, %ymm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = lshr <32 x i8> %a, splat (i8 1)
   %b_shr_1 = lshr <32 x i8> %b, splat (i8 1)
@@ -612,79 +448,29 @@ define <16 x i16> @test_ext_v16i16(<16 x i16> %a0, <16 x i16> %a1) nounwind {
 }
 
 define <16 x i16> @test_lsb_v16i16(<16 x i16> %a, <16 x i16> %b) {
-; SSE2-LABEL: test_lsb_v16i16:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm4
-; SSE2-NEXT:    psrlw $1, %xmm4
-; SSE2-NEXT:    movdqa %xmm1, %xmm5
-; SSE2-NEXT:    psrlw $1, %xmm5
-; SSE2-NEXT:    movdqa {{.*#+}} xmm6 = [1,1,1,1,1,1,1,1]
-; SSE2-NEXT:    por %xmm2, %xmm0
-; SSE2-NEXT:    psrlw $1, %xmm2
-; SSE2-NEXT:    paddw %xmm4, %xmm2
-; SSE2-NEXT:    por %xmm3, %xmm1
-; SSE2-NEXT:    psrlw $1, %xmm3
-; SSE2-NEXT:    paddw %xmm5, %xmm3
-; SSE2-NEXT:    pand %xmm6, %xmm1
-; SSE2-NEXT:    paddw %xmm3, %xmm1
-; SSE2-NEXT:    pand %xmm6, %xmm0
-; SSE2-NEXT:    paddw %xmm2, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE4-LABEL: test_lsb_v16i16:
-; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm4
-; SSE4-NEXT:    psrlw $1, %xmm4
-; SSE4-NEXT:    movdqa %xmm1, %xmm5
-; SSE4-NEXT:    psrlw $1, %xmm5
-; SSE4-NEXT:    pmovsxbw {{.*#+}} xmm6 = [1,1,1,1,1,1,1,1]
-; SSE4-NEXT:    por %xmm2, %xmm0
-; SSE4-NEXT:    psrlw $1, %xmm2
-; SSE4-NEXT:    paddw %xmm4, %xmm2
-; SSE4-NEXT:    por %xmm3, %xmm1
-; SSE4-NEXT:    psrlw $1, %xmm3
-; SSE4-NEXT:    paddw %xmm5, %xmm3
-; SSE4-NEXT:    pand %xmm6, %xmm1
-; SSE4-NEXT:    paddw %xmm3, %xmm1
-; SSE4-NEXT:    pand %xmm6, %xmm0
-; SSE4-NEXT:    paddw %xmm2, %xmm0
-; SSE4-NEXT:    retq
+; SSE-LABEL: test_lsb_v16i16:
+; SSE:       # %bb.0:
+; SSE-NEXT:    pavgw %xmm2, %xmm0
+; SSE-NEXT:    pavgw %xmm3, %xmm1
+; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v16i16:
 ; AVX1:       # %bb.0:
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm2, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm3
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
-; AVX1-NEXT:    vpsrlw $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpaddw %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpsrlw $1, %xmm1, %xmm4
-; AVX1-NEXT:    vpaddw %xmm3, %xmm4, %xmm3
-; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm0
-; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
-; AVX1-NEXT:    vpaddw %xmm1, %xmm2, %xmm1
-; AVX1-NEXT:    vpaddw %xmm0, %xmm3, %xmm0
-; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
+; AVX1-NEXT:    vpavgw %xmm2, %xmm3, %xmm2
+; AVX1-NEXT:    vpavgw %xmm0, %xmm1, %xmm0
+; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v16i16:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlw $1, %ymm0, %ymm2
-; AVX2-NEXT:    vpsrlw $1, %ymm1, %ymm3
-; AVX2-NEXT:    vpaddw %ymm2, %ymm3, %ymm2
-; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
-; AVX2-NEXT:    vpaddw %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpavgw %ymm0, %ymm1, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v16i16:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrlw $1, %ymm0, %ymm2
-; AVX512-NEXT:    vpsrlw $1, %ymm1, %ymm3
-; AVX512-NEXT:    vpaddw %ymm2, %ymm3, %ymm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} ymm0 = m32bcst & (ymm0 | ymm1)
-; AVX512-NEXT:    vpaddw %ymm0, %ymm2, %ymm0
+; AVX512-NEXT:    vpavgw %ymm0, %ymm1, %ymm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = lshr <16 x i16> %a, splat (i16 1)
   %b_shr_1 = lshr <16 x i16> %b, splat (i16 1)
@@ -802,80 +588,49 @@ define <8 x i32> @test_ext_v8i32(<8 x i32> %a0, <8 x i32> %a1) nounwind {
 }
 
 define <8 x i32> @test_lsb_v8i32(<8 x i32> %a, <8 x i32> %b) {
-; SSE2-LABEL: test_lsb_v8i32:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm4
-; SSE2-NEXT:    psrld $1, %xmm4
-; SSE2-NEXT:    movdqa %xmm1, %xmm5
-; SSE2-NEXT:    psrld $1, %xmm5
-; SSE2-NEXT:    movdqa {{.*#+}} xmm6 = [1,1,1,1]
-; SSE2-NEXT:    por %xmm2, %xmm0
-; SSE2-NEXT:    psrld $1, %xmm2
-; SSE2-NEXT:    paddd %xmm4, %xmm2
-; SSE2-NEXT:    por %xmm3, %xmm1
-; SSE2-NEXT:    psrld $1, %xmm3
-; SSE2-NEXT:    paddd %xmm5, %xmm3
-; SSE2-NEXT:    pand %xmm6, %xmm1
-; SSE2-NEXT:    paddd %xmm3, %xmm1
-; SSE2-NEXT:    pand %xmm6, %xmm0
-; SSE2-NEXT:    paddd %xmm2, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE4-LABEL: test_lsb_v8i32:
-; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm4
-; SSE4-NEXT:    psrld $1, %xmm4
-; SSE4-NEXT:    movdqa %xmm1, %xmm5
-; SSE4-NEXT:    psrld $1, %xmm5
-; SSE4-NEXT:    pmovsxbd {{.*#+}} xmm6 = [1,1,1,1]
-; SSE4-NEXT:    por %xmm2, %xmm0
-; SSE4-NEXT:    psrld $1, %xmm2
-; SSE4-NEXT:    paddd %xmm4, %xmm2
-; SSE4-NEXT:    por %xmm3, %xmm1
-; SSE4-NEXT:    psrld $1, %xmm3
-; SSE4-NEXT:    paddd %xmm5, %xmm3
-; SSE4-NEXT:    pand %xmm6, %xmm1
-; SSE4-NEXT:    paddd %xmm3, %xmm1
-; SSE4-NEXT:    pand %xmm6, %xmm0
-; SSE4-NEXT:    paddd %xmm2, %xmm0
-; SSE4-NEXT:    retq
+; SSE-LABEL: test_lsb_v8i32:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movdqa %xmm2, %xmm4
+; SSE-NEXT:    por %xmm0, %xmm4
+; SSE-NEXT:    pxor %xmm0, %xmm2
+; SSE-NEXT:    psrld $1, %xmm2
+; SSE-NEXT:    psubd %xmm2, %xmm4
+; SSE-NEXT:    movdqa %xmm3, %xmm2
+; SSE-NEXT:    por %xmm1, %xmm2
+; SSE-NEXT:    pxor %xmm1, %xmm3
+; SSE-NEXT:    psrld $1, %xmm3
+; SSE-NEXT:    psubd %xmm3, %xmm2
+; SSE-NEXT:    movdqa %xmm4, %xmm0
+; SSE-NEXT:    movdqa %xmm2, %xmm1
+; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v8i32:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpsrld $1, %xmm2, %xmm2
-; AVX1-NEXT:    vpsrld $1, %xmm0, %xmm3
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
-; AVX1-NEXT:    vpsrld $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpaddd %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpsrld $1, %xmm1, %xmm4
-; AVX1-NEXT:    vpaddd %xmm3, %xmm4, %xmm3
-; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm0
-; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
+; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm3
+; AVX1-NEXT:    vxorps %ymm0, %ymm1, %ymm0
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
-; AVX1-NEXT:    vpaddd %xmm1, %xmm2, %xmm1
-; AVX1-NEXT:    vpaddd %xmm0, %xmm3, %xmm0
+; AVX1-NEXT:    vpsrld $1, %xmm1, %xmm1
+; AVX1-NEXT:    vpsubd %xmm1, %xmm3, %xmm1
+; AVX1-NEXT:    vpsrld $1, %xmm0, %xmm0
+; AVX1-NEXT:    vpsubd %xmm0, %xmm2, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v8i32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrld $1, %ymm0, %ymm2
-; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm3 = [1,1,1,1,1,1,1,1]
-; AVX2-NEXT:    vpsrld $1, %ymm1, %ymm4
-; AVX2-NEXT:    vpaddd %ymm2, %ymm4, %ymm2
-; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpand %ymm3, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddd %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm2
+; AVX2-NEXT:    vpxor %ymm0, %ymm1, %ymm0
+; AVX2-NEXT:    vpsrld $1, %ymm0, %ymm0
+; AVX2-NEXT:    vpsubd %ymm0, %ymm2, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v8i32:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrld $1, %ymm0, %ymm2
-; AVX512-NEXT:    vpsrld $1, %ymm1, %ymm3
-; AVX512-NEXT:    vpaddd %ymm2, %ymm3, %ymm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} ymm0 = m32bcst & (ymm0 | ymm1)
-; AVX512-NEXT:    vpaddd %ymm0, %ymm2, %ymm0
+; AVX512-NEXT:    vpor %ymm0, %ymm1, %ymm2
+; AVX512-NEXT:    vpxor %ymm0, %ymm1, %ymm0
+; AVX512-NEXT:    vpsrld $1, %ymm0, %ymm0
+; AVX512-NEXT:    vpsubd %ymm0, %ymm2, %ymm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = lshr <8 x i32> %a, splat (i32 1)
   %b_shr_1 = lshr <8 x i32> %b, splat (i32 1)
@@ -993,80 +748,49 @@ define <4 x i64> @test_ext_v4i64(<4 x i64> %a0, <4 x i64> %a1) nounwind {
 }
 
 define <4 x i64> @test_lsb_v4i64(<4 x i64> %a, <4 x i64> %b) {
-; SSE2-LABEL: test_lsb_v4i64:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm4
-; SSE2-NEXT:    psrlq $1, %xmm4
-; SSE2-NEXT:    movdqa %xmm1, %xmm5
-; SSE2-NEXT:    psrlq $1, %xmm5
-; SSE2-NEXT:    movdqa {{.*#+}} xmm6 = [1,1]
-; SSE2-NEXT:    por %xmm2, %xmm0
-; SSE2-NEXT:    psrlq $1, %xmm2
-; SSE2-NEXT:    paddq %xmm4, %xmm2
-; SSE2-NEXT:    por %xmm3, %xmm1
-; SSE2-NEXT:    psrlq $1, %xmm3
-; SSE2-NEXT:    paddq %xmm5, %xmm3
-; SSE2-NEXT:    pand %xmm6, %xmm1
-; SSE2-NEXT:    paddq %xmm3, %xmm1
-; SSE2-NEXT:    pand %xmm6, %xmm0
-; SSE2-NEXT:    paddq %xmm2, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE4-LABEL: test_lsb_v4i64:
-; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm4
-; SSE4-NEXT:    psrlq $1, %xmm4
-; SSE4-NEXT:    movdqa %xmm1, %xmm5
-; SSE4-NEXT:    psrlq $1, %xmm5
-; SSE4-NEXT:    pmovsxbq {{.*#+}} xmm6 = [1,1]
-; SSE4-NEXT:    por %xmm2, %xmm0
-; SSE4-NEXT:    psrlq $1, %xmm2
-; SSE4-NEXT:    paddq %xmm4, %xmm2
-; SSE4-NEXT:    por %xmm3, %xmm1
-; SSE4-NEXT:    psrlq $1, %xmm3
-; SSE4-NEXT:    paddq %xmm5, %xmm3
-; SSE4-NEXT:    pand %xmm6, %xmm1
-; SSE4-NEXT:    paddq %xmm3, %xmm1
-; SSE4-NEXT:    pand %xmm6, %xmm0
-; SSE4-NEXT:    paddq %xmm2, %xmm0
-; SSE4-NEXT:    retq
+; SSE-LABEL: test_lsb_v4i64:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movdqa %xmm2, %xmm4
+; SSE-NEXT:    por %xmm0, %xmm4
+; SSE-NEXT:    pxor %xmm0, %xmm2
+; SSE-NEXT:    psrlq $1, %xmm2
+; SSE-NEXT:    psubq %xmm2, %xmm4
+; SSE-NEXT:    movdqa %xmm3, %xmm2
+; SSE-NEXT:    por %xmm1, %xmm2
+; SSE-NEXT:    pxor %xmm1, %xmm3
+; SSE-NEXT:    psrlq $1, %xmm3
+; SSE-NEXT:    psubq %xmm3, %xmm2
+; SSE-NEXT:    movdqa %xmm4, %xmm0
+; SSE-NEXT:    movdqa %xmm2, %xmm1
+; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v4i64:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpsrlq $1, %xmm2, %xmm2
-; AVX1-NEXT:    vpsrlq $1, %xmm0, %xmm3
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
-; AVX1-NEXT:    vpsrlq $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpaddq %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpsrlq $1, %xmm1, %xmm4
-; AVX1-NEXT:    vpaddq %xmm3, %xmm4, %xmm3
-; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm0
-; AVX1-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
+; AVX1-NEXT:    vorps %ymm0, %ymm1, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm3
+; AVX1-NEXT:    vxorps %ymm0, %ymm1, %ymm0
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
-; AVX1-NEXT:    vpaddq %xmm1, %xmm2, %xmm1
-; AVX1-NEXT:    vpaddq %xmm0, %xmm3, %xmm0
+; AVX1-NEXT:    vpsrlq $1, %xmm1, %xmm1
+; AVX1-NEXT:    vpsubq %xmm1, %xmm3, %xmm1
+; AVX1-NEXT:    vpsrlq $1, %xmm0, %xmm0
+; AVX1-NEXT:    vpsubq %xmm0, %xmm2, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v4i64:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlq $1, %ymm0, %ymm2
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm3 = [1,1,1,1]
-; AVX2-NEXT:    vpsrlq $1, %ymm1, %ymm4
-; AVX2-NEXT:    vpaddq %ymm2, %ymm4, %ymm2
-; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpand %ymm3, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddq %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpor %ymm0, %ymm1, %ymm2
+; AVX2-NEXT:    vpxor %ymm0, %ymm1, %ymm0
+; AVX2-NEXT:    vpsrlq $1, %ymm0, %ymm0
+; AVX2-NEXT:    vpsubq %ymm0, %ymm2, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v4i64:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrlq $1, %ymm0, %ymm2
-; AVX512-NEXT:    vpsrlq $1, %ymm1, %ymm3
-; AVX512-NEXT:    vpaddq %ymm2, %ymm3, %ymm2
-; AVX512-NEXT:    vpternlogq {{.*#+}} ymm0 = m64bcst & (ymm0 | ymm1)
-; AVX512-NEXT:    vpaddq %ymm0, %ymm2, %ymm0
+; AVX512-NEXT:    vpor %ymm0, %ymm1, %ymm2
+; AVX512-NEXT:    vpxor %ymm0, %ymm1, %ymm0
+; AVX512-NEXT:    vpsrlq $1, %ymm0, %ymm0
+; AVX512-NEXT:    vpsubq %ymm0, %ymm2, %ymm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = lshr <4 x i64> %a, splat (i64 1)
   %b_shr_1 = lshr <4 x i64> %b, splat (i64 1)
@@ -1166,120 +890,35 @@ define <64 x i8> @test_ext_v64i8(<64 x i8> %a0, <64 x i8> %a1) nounwind {
 define <64 x i8> @test_lsb_v64i8(<64 x i8> %a, <64 x i8> %b) {
 ; SSE-LABEL: test_lsb_v64i8:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movdqa %xmm0, %xmm13
-; SSE-NEXT:    psrlw $1, %xmm13
-; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; SSE-NEXT:    pand %xmm8, %xmm13
-; SSE-NEXT:    movdqa %xmm1, %xmm12
-; SSE-NEXT:    psrlw $1, %xmm12
-; SSE-NEXT:    pand %xmm8, %xmm12
-; SSE-NEXT:    movdqa %xmm2, %xmm11
-; SSE-NEXT:    psrlw $1, %xmm11
-; SSE-NEXT:    pand %xmm8, %xmm11
-; SSE-NEXT:    movdqa %xmm3, %xmm10
-; SSE-NEXT:    psrlw $1, %xmm10
-; SSE-NEXT:    pand %xmm8, %xmm10
-; SSE-NEXT:    movdqa {{.*#+}} xmm9 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; SSE-NEXT:    por %xmm4, %xmm0
-; SSE-NEXT:    psrlw $1, %xmm4
-; SSE-NEXT:    pand %xmm8, %xmm4
-; SSE-NEXT:    paddb %xmm13, %xmm4
-; SSE-NEXT:    por %xmm5, %xmm1
-; SSE-NEXT:    psrlw $1, %xmm5
-; SSE-NEXT:    pand %xmm8, %xmm5
-; SSE-NEXT:    paddb %xmm12, %xmm5
-; SSE-NEXT:    por %xmm6, %xmm2
-; SSE-NEXT:    psrlw $1, %xmm6
-; SSE-NEXT:    pand %xmm8, %xmm6
-; SSE-NEXT:    paddb %xmm11, %xmm6
-; SSE-NEXT:    por %xmm7, %xmm3
-; SSE-NEXT:    psrlw $1, %xmm7
-; SSE-NEXT:    pand %xmm8, %xmm7
-; SSE-NEXT:    paddb %xmm10, %xmm7
-; SSE-NEXT:    pand %xmm9, %xmm3
-; SSE-NEXT:    paddb %xmm7, %xmm3
-; SSE-NEXT:    pand %xmm9, %xmm2
-; SSE-NEXT:    paddb %xmm6, %xmm2
-; SSE-NEXT:    pand %xmm9, %xmm1
-; SSE-NEXT:    paddb %xmm5, %xmm1
-; SSE-NEXT:    pand %xmm9, %xmm0
-; SSE-NEXT:    paddb %xmm4, %xmm0
+; SSE-NEXT:    pavgb %xmm4, %xmm0
+; SSE-NEXT:    pavgb %xmm5, %xmm1
+; SSE-NEXT:    pavgb %xmm6, %xmm2
+; SSE-NEXT:    pavgb %xmm7, %xmm3
 ; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v64i8:
 ; AVX1:       # %bb.0:
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm4
-; AVX1-NEXT:    vpsrlw $1, %xmm4, %xmm4
-; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm5 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX1-NEXT:    vpand %xmm5, %xmm4, %xmm4
-; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm6
-; AVX1-NEXT:    vpand %xmm5, %xmm6, %xmm6
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm7
-; AVX1-NEXT:    vpsrlw $1, %xmm7, %xmm7
-; AVX1-NEXT:    vpand %xmm5, %xmm7, %xmm7
-; AVX1-NEXT:    vpsrlw $1, %xmm1, %xmm8
-; AVX1-NEXT:    vpand %xmm5, %xmm8, %xmm8
-; AVX1-NEXT:    vbroadcastss {{.*#+}} ymm9 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm10
-; AVX1-NEXT:    vpsrlw $1, %xmm10, %xmm10
-; AVX1-NEXT:    vpand %xmm5, %xmm10, %xmm10
-; AVX1-NEXT:    vpaddb %xmm4, %xmm10, %xmm4
-; AVX1-NEXT:    vpsrlw $1, %xmm2, %xmm10
-; AVX1-NEXT:    vpand %xmm5, %xmm10, %xmm10
-; AVX1-NEXT:    vpaddb %xmm6, %xmm10, %xmm6
-; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm10
-; AVX1-NEXT:    vpsrlw $1, %xmm10, %xmm10
-; AVX1-NEXT:    vpand %xmm5, %xmm10, %xmm10
-; AVX1-NEXT:    vpaddb %xmm7, %xmm10, %xmm7
-; AVX1-NEXT:    vpsrlw $1, %xmm3, %xmm10
-; AVX1-NEXT:    vpand %xmm5, %xmm10, %xmm5
-; AVX1-NEXT:    vpaddb %xmm5, %xmm8, %xmm5
-; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm0
-; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm1
-; AVX1-NEXT:    vandps %ymm1, %ymm9, %ymm1
-; AVX1-NEXT:    vandps %ymm0, %ymm9, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpaddb %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpaddb %xmm0, %xmm6, %xmm0
-; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm5
+; AVX1-NEXT:    vpavgb %xmm4, %xmm5, %xmm4
+; AVX1-NEXT:    vpavgb %xmm0, %xmm2, %xmm0
+; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm0, %ymm0
 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
-; AVX1-NEXT:    vpaddb %xmm2, %xmm7, %xmm2
-; AVX1-NEXT:    vpaddb %xmm1, %xmm5, %xmm1
+; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm4
+; AVX1-NEXT:    vpavgb %xmm2, %xmm4, %xmm2
+; AVX1-NEXT:    vpavgb %xmm1, %xmm3, %xmm1
 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v64i8:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlw $1, %ymm0, %ymm4
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm5 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX2-NEXT:    vpand %ymm5, %ymm4, %ymm4
-; AVX2-NEXT:    vpsrlw $1, %ymm1, %ymm6
-; AVX2-NEXT:    vpand %ymm5, %ymm6, %ymm6
-; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm7 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; AVX2-NEXT:    vpsrlw $1, %ymm2, %ymm8
-; AVX2-NEXT:    vpand %ymm5, %ymm8, %ymm8
-; AVX2-NEXT:    vpaddb %ymm4, %ymm8, %ymm4
-; AVX2-NEXT:    vpsrlw $1, %ymm3, %ymm8
-; AVX2-NEXT:    vpand %ymm5, %ymm8, %ymm5
-; AVX2-NEXT:    vpaddb %ymm6, %ymm5, %ymm5
-; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm0
-; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm1
-; AVX2-NEXT:    vpand %ymm7, %ymm1, %ymm1
-; AVX2-NEXT:    vpaddb %ymm1, %ymm5, %ymm1
-; AVX2-NEXT:    vpand %ymm7, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddb %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpavgb %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpavgb %ymm1, %ymm3, %ymm1
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v64i8:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrlw $1, %zmm0, %zmm2
-; AVX512-NEXT:    vpbroadcastd {{.*#+}} zmm3 = [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127]
-; AVX512-NEXT:    vpandq %zmm3, %zmm2, %zmm2
-; AVX512-NEXT:    vpsrlw $1, %zmm1, %zmm4
-; AVX512-NEXT:    vpandq %zmm3, %zmm4, %zmm3
-; AVX512-NEXT:    vpaddb %zmm2, %zmm3, %zmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} zmm0 = m32bcst & (zmm0 | zmm1)
-; AVX512-NEXT:    vpaddb %zmm0, %zmm2, %zmm0
+; AVX512-NEXT:    vpavgb %zmm0, %zmm1, %zmm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = lshr <64 x i8> %a, splat (i8 1)
   %b_shr_1 = lshr <64 x i8> %b, splat (i8 1)
@@ -1373,129 +1012,37 @@ define <32 x i16> @test_ext_v32i16(<32 x i16> %a0, <32 x i16> %a1) nounwind {
 }
 
 define <32 x i16> @test_lsb_v32i16(<32 x i16> %a, <32 x i16> %b) {
-; SSE2-LABEL: test_lsb_v32i16:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm11
-; SSE2-NEXT:    psrlw $1, %xmm11
-; SSE2-NEXT:    movdqa %xmm1, %xmm12
-; SSE2-NEXT:    psrlw $1, %xmm12
-; SSE2-NEXT:    movdqa %xmm2, %xmm10
-; SSE2-NEXT:    psrlw $1, %xmm10
-; SSE2-NEXT:    movdqa %xmm3, %xmm9
-; SSE2-NEXT:    psrlw $1, %xmm9
-; SSE2-NEXT:    movdqa {{.*#+}} xmm8 = [1,1,1,1,1,1,1,1]
-; SSE2-NEXT:    por %xmm4, %xmm0
-; SSE2-NEXT:    psrlw $1, %xmm4
-; SSE2-NEXT:    paddw %xmm11, %xmm4
-; SSE2-NEXT:    por %xmm5, %xmm1
-; SSE2-NEXT:    psrlw $1, %xmm5
-; SSE2-NEXT:    paddw %xmm12, %xmm5
-; SSE2-NEXT:    por %xmm6, %xmm2
-; SSE2-NEXT:    psrlw $1, %xmm6
-; SSE2-NEXT:    paddw %xmm10, %xmm6
-; SSE2-NEXT:    por %xmm7, %xmm3
-; SSE2-NEXT:    psrlw $1, %xmm7
-; SSE2-NEXT:    paddw %xmm9, %xmm7
-; SSE2-NEXT:    pand %xmm8, %xmm3
-; SSE2-NEXT:    paddw %xmm7, %xmm3
-; SSE2-NEXT:    pand %xmm8, %xmm2
-; SSE2-NEXT:    paddw %xmm6, %xmm2
-; SSE2-NEXT:    pand %xmm8, %xmm1
-; SSE2-NEXT:    paddw %xmm5, %xmm1
-; SSE2-NEXT:    pand %xmm8, %xmm0
-; SSE2-NEXT:    paddw %xmm4, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE4-LABEL: test_lsb_v32i16:
-; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm11
-; SSE4-NEXT:    psrlw $1, %xmm11
-; SSE4-NEXT:    movdqa %xmm1, %xmm12
-; SSE4-NEXT:    psrlw $1, %xmm12
-; SSE4-NEXT:    movdqa %xmm2, %xmm10
-; SSE4-NEXT:    psrlw $1, %xmm10
-; SSE4-NEXT:    movdqa %xmm3, %xmm9
-; SSE4-NEXT:    psrlw $1, %xmm9
-; SSE4-NEXT:    pmovsxbw {{.*#+}} xmm8 = [1,1,1,1,1,1,1,1]
-; SSE4-NEXT:    por %xmm4, %xmm0
-; SSE4-NEXT:    psrlw $1, %xmm4
-; SSE4-NEXT:    paddw %xmm11, %xmm4
-; SSE4-NEXT:    por %xmm5, %xmm1
-; SSE4-NEXT:    psrlw $1, %xmm5
-; SSE4-NEXT:    paddw %xmm12, %xmm5
-; SSE4-NEXT:    por %xmm6, %xmm2
-; SSE4-NEXT:    psrlw $1, %xmm6
-; SSE4-NEXT:    paddw %xmm10, %xmm6
-; SSE4-NEXT:    por %xmm7, %xmm3
-; SSE4-NEXT:    psrlw $1, %xmm7
-; SSE4-NEXT:    paddw %xmm9, %xmm7
-; SSE4-NEXT:    pand %xmm8, %xmm3
-; SSE4-NEXT:    paddw %xmm7, %xmm3
-; SSE4-NEXT:    pand %xmm8, %xmm2
-; SSE4-NEXT:    paddw %xmm6, %xmm2
-; SSE4-NEXT:    pand %xmm8, %xmm1
-; SSE4-NEXT:    paddw %xmm5, %xmm1
-; SSE4-NEXT:    pand %xmm8, %xmm0
-; SSE4-NEXT:    paddw %xmm4, %xmm0
-; SSE4-NEXT:    retq
+; SSE-LABEL: test_lsb_v32i16:
+; SSE:       # %bb.0:
+; SSE-NEXT:    pavgw %xmm4, %xmm0
+; SSE-NEXT:    pavgw %xmm5, %xmm1
+; SSE-NEXT:    pavgw %xmm6, %xmm2
+; SSE-NEXT:    pavgw %xmm7, %xmm3
+; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v32i16:
 ; AVX1:       # %bb.0:
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm4
-; AVX1-NEXT:    vpsrlw $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm6
-; AVX1-NEXT:    vpsrlw $1, %xmm6, %xmm6
-; AVX1-NEXT:    vpsrlw $1, %xmm1, %xmm7
-; AVX1-NEXT:    vbroadcastss {{.*#+}} ymm8 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm9
-; AVX1-NEXT:    vpsrlw $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpaddw %xmm4, %xmm9, %xmm4
-; AVX1-NEXT:    vpsrlw $1, %xmm2, %xmm9
-; AVX1-NEXT:    vpaddw %xmm5, %xmm9, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm9
-; AVX1-NEXT:    vpsrlw $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpaddw %xmm6, %xmm9, %xmm6
-; AVX1-NEXT:    vpsrlw $1, %xmm3, %xmm9
-; AVX1-NEXT:    vpaddw %xmm7, %xmm9, %xmm7
-; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm0
-; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm1
-; AVX1-NEXT:    vandps %ymm1, %ymm8, %ymm1
-; AVX1-NEXT:    vandps %ymm0, %ymm8, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpaddw %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpaddw %xmm0, %xmm5, %xmm0
-; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm5
+; AVX1-NEXT:    vpavgw %xmm4, %xmm5, %xmm4
+; AVX1-NEXT:    vpavgw %xmm0, %xmm2, %xmm0
+; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm0, %ymm0
 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
-; AVX1-NEXT:    vpaddw %xmm2, %xmm6, %xmm2
-; AVX1-NEXT:    vpaddw %xmm1, %xmm7, %xmm1
+; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm4
+; AVX1-NEXT:    vpavgw %xmm2, %xmm4, %xmm2
+; AVX1-NEXT:    vpavgw %xmm1, %xmm3, %xmm1
 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v32i16:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlw $1, %ymm0, %ymm4
-; AVX2-NEXT:    vpsrlw $1, %ymm1, %ymm5
-; AVX2-NEXT:    vpbroadcastw {{.*#+}} ymm6 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
-; AVX2-NEXT:    vpsrlw $1, %ymm2, %ymm7
-; AVX2-NEXT:    vpaddw %ymm4, %ymm7, %ymm4
-; AVX2-NEXT:    vpsrlw $1, %ymm3, %ymm7
-; AVX2-NEXT:    vpaddw %ymm5, %ymm7, %ymm5
-; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm0
-; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm1, %ymm1
-; AVX2-NEXT:    vpaddw %ymm1, %ymm5, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddw %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpavgw %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpavgw %ymm1, %ymm3, %ymm1
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v32i16:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrlw $1, %zmm0, %zmm2
-; AVX512-NEXT:    vpsrlw $1, %zmm1, %zmm3
-; AVX512-NEXT:    vpaddw %zmm2, %zmm3, %zmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} zmm0 = m32bcst & (zmm0 | zmm1)
-; AVX512-NEXT:    vpaddw %zmm0, %zmm2, %zmm0
+; AVX512-NEXT:    vpavgw %zmm0, %zmm1, %zmm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = lshr <32 x i16> %a, splat (i16 1)
   %b_shr_1 = lshr <32 x i16> %b, splat (i16 1)
@@ -1663,129 +1210,74 @@ define <16 x i32> @test_ext_v16i32(<16 x i32> %a0, <16 x i32> %a1) nounwind {
 }
 
 define <16 x i32> @test_lsb_v16i32(<16 x i32> %a, <16 x i32> %b) {
-; SSE2-LABEL: test_lsb_v16i32:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm11
-; SSE2-NEXT:    psrld $1, %xmm11
-; SSE2-NEXT:    movdqa %xmm1, %xmm12
-; SSE2-NEXT:    psrld $1, %xmm12
-; SSE2-NEXT:    movdqa %xmm2, %xmm10
-; SSE2-NEXT:    psrld $1, %xmm10
-; SSE2-NEXT:    movdqa %xmm3, %xmm9
-; SSE2-NEXT:    psrld $1, %xmm9
-; SSE2-NEXT:    movdqa {{.*#+}} xmm8 = [1,1,1,1]
-; SSE2-NEXT:    por %xmm4, %xmm0
-; SSE2-NEXT:    psrld $1, %xmm4
-; SSE2-NEXT:    paddd %xmm11, %xmm4
-; SSE2-NEXT:    por %xmm5, %xmm1
-; SSE2-NEXT:    psrld $1, %xmm5
-; SSE2-NEXT:    paddd %xmm12, %xmm5
-; SSE2-NEXT:    por %xmm6, %xmm2
-; SSE2-NEXT:    psrld $1, %xmm6
-; SSE2-NEXT:    paddd %xmm10, %xmm6
-; SSE2-NEXT:    por %xmm7, %xmm3
-; SSE2-NEXT:    psrld $1, %xmm7
-; SSE2-NEXT:    paddd %xmm9, %xmm7
-; SSE2-NEXT:    pand %xmm8, %xmm3
-; SSE2-NEXT:    paddd %xmm7, %xmm3
-; SSE2-NEXT:    pand %xmm8, %xmm2
-; SSE2-NEXT:    paddd %xmm6, %xmm2
-; SSE2-NEXT:    pand %xmm8, %xmm1
-; SSE2-NEXT:    paddd %xmm5, %xmm1
-; SSE2-NEXT:    pand %xmm8, %xmm0
-; SSE2-NEXT:    paddd %xmm4, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE4-LABEL: test_lsb_v16i32:
-; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm11
-; SSE4-NEXT:    psrld $1, %xmm11
-; SSE4-NEXT:    movdqa %xmm1, %xmm12
-; SSE4-NEXT:    psrld $1, %xmm12
-; SSE4-NEXT:    movdqa %xmm2, %xmm10
-; SSE4-NEXT:    psrld $1, %xmm10
-; SSE4-NEXT:    movdqa %xmm3, %xmm9
-; SSE4-NEXT:    psrld $1, %xmm9
-; SSE4-NEXT:    pmovsxbd {{.*#+}} xmm8 = [1,1,1,1]
-; SSE4-NEXT:    por %xmm4, %xmm0
-; SSE4-NEXT:    psrld $1, %xmm4
-; SSE4-NEXT:    paddd %xmm11, %xmm4
-; SSE4-NEXT:    por %xmm5, %xmm1
-; SSE4-NEXT:    psrld $1, %xmm5
-; SSE4-NEXT:    paddd %xmm12, %xmm5
-; SSE4-NEXT:    por %xmm6, %xmm2
-; SSE4-NEXT:    psrld $1, %xmm6
-; SSE4-NEXT:    paddd %xmm10, %xmm6
-; SSE4-NEXT:    por %xmm7, %xmm3
-; SSE4-NEXT:    psrld $1, %xmm7
-; SSE4-NEXT:    paddd %xmm9, %xmm7
-; SSE4-NEXT:    pand %xmm8, %xmm3
-; SSE4-NEXT:    paddd %xmm7, %xmm3
-; SSE4-NEXT:    pand %xmm8, %xmm2
-; SSE4-NEXT:    paddd %xmm6, %xmm2
-; SSE4-NEXT:    pand %xmm8, %xmm1
-; SSE4-NEXT:    paddd %xmm5, %xmm1
-; SSE4-NEXT:    pand %xmm8, %xmm0
-; SSE4-NEXT:    paddd %xmm4, %xmm0
-; SSE4-NEXT:    retq
+; SSE-LABEL: test_lsb_v16i32:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movdqa %xmm4, %xmm8
+; SSE-NEXT:    por %xmm0, %xmm8
+; SSE-NEXT:    pxor %xmm0, %xmm4
+; SSE-NEXT:    psrld $1, %xmm4
+; SSE-NEXT:    psubd %xmm4, %xmm8
+; SSE-NEXT:    movdqa %xmm5, %xmm4
+; SSE-NEXT:    por %xmm1, %xmm4
+; SSE-NEXT:    pxor %xmm1, %xmm5
+; SSE-NEXT:    psrld $1, %xmm5
+; SSE-NEXT:    psubd %xmm5, %xmm4
+; SSE-NEXT:    movdqa %xmm6, %xmm5
+; SSE-NEXT:    por %xmm2, %xmm5
+; SSE-NEXT:    pxor %xmm2, %xmm6
+; SSE-NEXT:    psrld $1, %xmm6
+; SSE-NEXT:    psubd %xmm6, %xmm5
+; SSE-NEXT:    movdqa %xmm7, %xmm6
+; SSE-NEXT:    por %xmm3, %xmm6
+; SSE-NEXT:    pxor %xmm3, %xmm7
+; SSE-NEXT:    psrld $1, %xmm7
+; SSE-NEXT:    psubd %xmm7, %xmm6
+; SSE-NEXT:    movdqa %xmm8, %xmm0
+; SSE-NEXT:    movdqa %xmm4, %xmm1
+; SSE-NEXT:    movdqa %xmm5, %xmm2
+; SSE-NEXT:    movdqa %xmm6, %xmm3
+; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v16i32:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm4
-; AVX1-NEXT:    vpsrld $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpsrld $1, %xmm0, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm6
-; AVX1-NEXT:    vpsrld $1, %xmm6, %xmm6
-; AVX1-NEXT:    vpsrld $1, %xmm1, %xmm7
-; AVX1-NEXT:    vbroadcastss {{.*#+}} ymm8 = [1,1,1,1,1,1,1,1]
-; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm9
-; AVX1-NEXT:    vpsrld $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpaddd %xmm4, %xmm9, %xmm4
-; AVX1-NEXT:    vpsrld $1, %xmm2, %xmm9
-; AVX1-NEXT:    vpaddd %xmm5, %xmm9, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm9
-; AVX1-NEXT:    vpsrld $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpaddd %xmm6, %xmm9, %xmm6
-; AVX1-NEXT:    vpsrld $1, %xmm3, %xmm9
-; AVX1-NEXT:    vpaddd %xmm7, %xmm9, %xmm7
-; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm0
-; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm1
-; AVX1-NEXT:    vandps %ymm1, %ymm8, %ymm1
-; AVX1-NEXT:    vandps %ymm0, %ymm8, %ymm0
+; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm4
+; AVX1-NEXT:    vextractf128 $1, %ymm4, %xmm5
+; AVX1-NEXT:    vxorps %ymm0, %ymm2, %ymm0
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpaddd %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpaddd %xmm0, %xmm5, %xmm0
+; AVX1-NEXT:    vpsrld $1, %xmm2, %xmm2
+; AVX1-NEXT:    vpsubd %xmm2, %xmm5, %xmm2
+; AVX1-NEXT:    vpsrld $1, %xmm0, %xmm0
+; AVX1-NEXT:    vpsubd %xmm0, %xmm4, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
-; AVX1-NEXT:    vpaddd %xmm2, %xmm6, %xmm2
-; AVX1-NEXT:    vpaddd %xmm1, %xmm7, %xmm1
-; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
+; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
+; AVX1-NEXT:    vxorps %ymm1, %ymm3, %ymm1
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
+; AVX1-NEXT:    vpsrld $1, %xmm3, %xmm3
+; AVX1-NEXT:    vpsubd %xmm3, %xmm4, %xmm3
+; AVX1-NEXT:    vpsrld $1, %xmm1, %xmm1
+; AVX1-NEXT:    vpsubd %xmm1, %xmm2, %xmm1
+; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm1, %ymm1
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v16i32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrld $1, %ymm0, %ymm4
-; AVX2-NEXT:    vpsrld $1, %ymm1, %ymm5
-; AVX2-NEXT:    vpbroadcastd {{.*#+}} ymm6 = [1,1,1,1,1,1,1,1]
-; AVX2-NEXT:    vpsrld $1, %ymm2, %ymm7
-; AVX2-NEXT:    vpaddd %ymm4, %ymm7, %ymm4
-; AVX2-NEXT:    vpsrld $1, %ymm3, %ymm7
-; AVX2-NEXT:    vpaddd %ymm5, %ymm7, %ymm5
-; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm0
-; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm1, %ymm1
-; AVX2-NEXT:    vpaddd %ymm1, %ymm5, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddd %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm4
+; AVX2-NEXT:    vpxor %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpsrld $1, %ymm0, %ymm0
+; AVX2-NEXT:    vpsubd %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm2
+; AVX2-NEXT:    vpxor %ymm1, %ymm3, %ymm1
+; AVX2-NEXT:    vpsrld $1, %ymm1, %ymm1
+; AVX2-NEXT:    vpsubd %ymm1, %ymm2, %ymm1
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v16i32:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrld $1, %zmm0, %zmm2
-; AVX512-NEXT:    vpsrld $1, %zmm1, %zmm3
-; AVX512-NEXT:    vpaddd %zmm2, %zmm3, %zmm2
-; AVX512-NEXT:    vpternlogd {{.*#+}} zmm0 = m32bcst & (zmm0 | zmm1)
-; AVX512-NEXT:    vpaddd %zmm0, %zmm2, %zmm0
+; AVX512-NEXT:    vpord %zmm0, %zmm1, %zmm2
+; AVX512-NEXT:    vpxord %zmm0, %zmm1, %zmm0
+; AVX512-NEXT:    vpsrld $1, %zmm0, %zmm0
+; AVX512-NEXT:    vpsubd %zmm0, %zmm2, %zmm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = lshr <16 x i32> %a, splat (i32 1)
   %b_shr_1 = lshr <16 x i32> %b, splat (i32 1)
@@ -1953,129 +1445,74 @@ define <8 x i64> @test_ext_v8i64(<8 x i64> %a0, <8 x i64> %a1) nounwind {
 }
 
 define <8 x i64> @test_lsb_v8i64(<8 x i64> %a, <8 x i64> %b) {
-; SSE2-LABEL: test_lsb_v8i64:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm11
-; SSE2-NEXT:    psrlq $1, %xmm11
-; SSE2-NEXT:    movdqa %xmm1, %xmm12
-; SSE2-NEXT:    psrlq $1, %xmm12
-; SSE2-NEXT:    movdqa %xmm2, %xmm10
-; SSE2-NEXT:    psrlq $1, %xmm10
-; SSE2-NEXT:    movdqa %xmm3, %xmm9
-; SSE2-NEXT:    psrlq $1, %xmm9
-; SSE2-NEXT:    movdqa {{.*#+}} xmm8 = [1,1]
-; SSE2-NEXT:    por %xmm4, %xmm0
-; SSE2-NEXT:    psrlq $1, %xmm4
-; SSE2-NEXT:    paddq %xmm11, %xmm4
-; SSE2-NEXT:    por %xmm5, %xmm1
-; SSE2-NEXT:    psrlq $1, %xmm5
-; SSE2-NEXT:    paddq %xmm12, %xmm5
-; SSE2-NEXT:    por %xmm6, %xmm2
-; SSE2-NEXT:    psrlq $1, %xmm6
-; SSE2-NEXT:    paddq %xmm10, %xmm6
-; SSE2-NEXT:    por %xmm7, %xmm3
-; SSE2-NEXT:    psrlq $1, %xmm7
-; SSE2-NEXT:    paddq %xmm9, %xmm7
-; SSE2-NEXT:    pand %xmm8, %xmm3
-; SSE2-NEXT:    paddq %xmm7, %xmm3
-; SSE2-NEXT:    pand %xmm8, %xmm2
-; SSE2-NEXT:    paddq %xmm6, %xmm2
-; SSE2-NEXT:    pand %xmm8, %xmm1
-; SSE2-NEXT:    paddq %xmm5, %xmm1
-; SSE2-NEXT:    pand %xmm8, %xmm0
-; SSE2-NEXT:    paddq %xmm4, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE4-LABEL: test_lsb_v8i64:
-; SSE4:       # %bb.0:
-; SSE4-NEXT:    movdqa %xmm0, %xmm11
-; SSE4-NEXT:    psrlq $1, %xmm11
-; SSE4-NEXT:    movdqa %xmm1, %xmm12
-; SSE4-NEXT:    psrlq $1, %xmm12
-; SSE4-NEXT:    movdqa %xmm2, %xmm10
-; SSE4-NEXT:    psrlq $1, %xmm10
-; SSE4-NEXT:    movdqa %xmm3, %xmm9
-; SSE4-NEXT:    psrlq $1, %xmm9
-; SSE4-NEXT:    pmovsxbq {{.*#+}} xmm8 = [1,1]
-; SSE4-NEXT:    por %xmm4, %xmm0
-; SSE4-NEXT:    psrlq $1, %xmm4
-; SSE4-NEXT:    paddq %xmm11, %xmm4
-; SSE4-NEXT:    por %xmm5, %xmm1
-; SSE4-NEXT:    psrlq $1, %xmm5
-; SSE4-NEXT:    paddq %xmm12, %xmm5
-; SSE4-NEXT:    por %xmm6, %xmm2
-; SSE4-NEXT:    psrlq $1, %xmm6
-; SSE4-NEXT:    paddq %xmm10, %xmm6
-; SSE4-NEXT:    por %xmm7, %xmm3
-; SSE4-NEXT:    psrlq $1, %xmm7
-; SSE4-NEXT:    paddq %xmm9, %xmm7
-; SSE4-NEXT:    pand %xmm8, %xmm3
-; SSE4-NEXT:    paddq %xmm7, %xmm3
-; SSE4-NEXT:    pand %xmm8, %xmm2
-; SSE4-NEXT:    paddq %xmm6, %xmm2
-; SSE4-NEXT:    pand %xmm8, %xmm1
-; SSE4-NEXT:    paddq %xmm5, %xmm1
-; SSE4-NEXT:    pand %xmm8, %xmm0
-; SSE4-NEXT:    paddq %xmm4, %xmm0
-; SSE4-NEXT:    retq
+; SSE-LABEL: test_lsb_v8i64:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movdqa %xmm4, %xmm8
+; SSE-NEXT:    por %xmm0, %xmm8
+; SSE-NEXT:    pxor %xmm0, %xmm4
+; SSE-NEXT:    psrlq $1, %xmm4
+; SSE-NEXT:    psubq %xmm4, %xmm8
+; SSE-NEXT:    movdqa %xmm5, %xmm4
+; SSE-NEXT:    por %xmm1, %xmm4
+; SSE-NEXT:    pxor %xmm1, %xmm5
+; SSE-NEXT:    psrlq $1, %xmm5
+; SSE-NEXT:    psubq %xmm5, %xmm4
+; SSE-NEXT:    movdqa %xmm6, %xmm5
+; SSE-NEXT:    por %xmm2, %xmm5
+; SSE-NEXT:    pxor %xmm2, %xmm6
+; SSE-NEXT:    psrlq $1, %xmm6
+; SSE-NEXT:    psubq %xmm6, %xmm5
+; SSE-NEXT:    movdqa %xmm7, %xmm6
+; SSE-NEXT:    por %xmm3, %xmm6
+; SSE-NEXT:    pxor %xmm3, %xmm7
+; SSE-NEXT:    psrlq $1, %xmm7
+; SSE-NEXT:    psubq %xmm7, %xmm6
+; SSE-NEXT:    movdqa %xmm8, %xmm0
+; SSE-NEXT:    movdqa %xmm4, %xmm1
+; SSE-NEXT:    movdqa %xmm5, %xmm2
+; SSE-NEXT:    movdqa %xmm6, %xmm3
+; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: test_lsb_v8i64:
 ; AVX1:       # %bb.0:
-; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm4
-; AVX1-NEXT:    vpsrlq $1, %xmm4, %xmm4
-; AVX1-NEXT:    vpsrlq $1, %xmm0, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm6
-; AVX1-NEXT:    vpsrlq $1, %xmm6, %xmm6
-; AVX1-NEXT:    vpsrlq $1, %xmm1, %xmm7
-; AVX1-NEXT:    vbroadcastsd {{.*#+}} ymm8 = [1,1,1,1]
-; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm9
-; AVX1-NEXT:    vpsrlq $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpaddq %xmm4, %xmm9, %xmm4
-; AVX1-NEXT:    vpsrlq $1, %xmm2, %xmm9
-; AVX1-NEXT:    vpaddq %xmm5, %xmm9, %xmm5
-; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm9
-; AVX1-NEXT:    vpsrlq $1, %xmm9, %xmm9
-; AVX1-NEXT:    vpaddq %xmm6, %xmm9, %xmm6
-; AVX1-NEXT:    vpsrlq $1, %xmm3, %xmm9
-; AVX1-NEXT:    vpaddq %xmm7, %xmm9, %xmm7
-; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm0
-; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm1
-; AVX1-NEXT:    vandps %ymm1, %ymm8, %ymm1
-; AVX1-NEXT:    vandps %ymm0, %ymm8, %ymm0
+; AVX1-NEXT:    vorps %ymm0, %ymm2, %ymm4
+; AVX1-NEXT:    vextractf128 $1, %ymm4, %xmm5
+; AVX1-NEXT:    vxorps %ymm0, %ymm2, %ymm0
 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; AVX1-NEXT:    vpaddq %xmm2, %xmm4, %xmm2
-; AVX1-NEXT:    vpaddq %xmm0, %xmm5, %xmm0
+; AVX1-NEXT:    vpsrlq $1, %xmm2, %xmm2
+; AVX1-NEXT:    vpsubq %xmm2, %xmm5, %xmm2
+; AVX1-NEXT:    vpsrlq $1, %xmm0, %xmm0
+; AVX1-NEXT:    vpsubq %xmm0, %xmm4, %xmm0
 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
-; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
-; AVX1-NEXT:    vpaddq %xmm2, %xmm6, %xmm2
-; AVX1-NEXT:    vpaddq %xmm1, %xmm7, %xmm1
-; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
+; AVX1-NEXT:    vorps %ymm1, %ymm3, %ymm2
+; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
+; AVX1-NEXT:    vxorps %ymm1, %ymm3, %ymm1
+; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
+; AVX1-NEXT:    vpsrlq $1, %xmm3, %xmm3
+; AVX1-NEXT:    vpsubq %xmm3, %xmm4, %xmm3
+; AVX1-NEXT:    vpsrlq $1, %xmm1, %xmm1
+; AVX1-NEXT:    vpsubq %xmm1, %xmm2, %xmm1
+; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm1, %ymm1
 ; AVX1-NEXT:    retq
 ;
 ; AVX2-LABEL: test_lsb_v8i64:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vpsrlq $1, %ymm0, %ymm4
-; AVX2-NEXT:    vpsrlq $1, %ymm1, %ymm5
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm6 = [1,1,1,1]
-; AVX2-NEXT:    vpsrlq $1, %ymm2, %ymm7
-; AVX2-NEXT:    vpaddq %ymm4, %ymm7, %ymm4
-; AVX2-NEXT:    vpsrlq $1, %ymm3, %ymm7
-; AVX2-NEXT:    vpaddq %ymm5, %ymm7, %ymm5
-; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm0
-; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm1, %ymm1
-; AVX2-NEXT:    vpaddq %ymm1, %ymm5, %ymm1
-; AVX2-NEXT:    vpand %ymm6, %ymm0, %ymm0
-; AVX2-NEXT:    vpaddq %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpor %ymm0, %ymm2, %ymm4
+; AVX2-NEXT:    vpxor %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vpsrlq $1, %ymm0, %ymm0
+; AVX2-NEXT:    vpsubq %ymm0, %ymm4, %ymm0
+; AVX2-NEXT:    vpor %ymm1, %ymm3, %ymm2
+; AVX2-NEXT:    vpxor %ymm1, %ymm3, %ymm1
+; AVX2-NEXT:    vpsrlq $1, %ymm1, %ymm1
+; AVX2-NEXT:    vpsubq %ymm1, %ymm2, %ymm1
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_lsb_v8i64:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpsrlq $1, %zmm0, %zmm2
-; AVX512-NEXT:    vpsrlq $1, %zmm1, %zmm3
-; AVX512-NEXT:    vpaddq %zmm2, %zmm3, %zmm2
-; AVX512-NEXT:    vpternlogq {{.*#+}} zmm0 = m64bcst & (zmm0 | zmm1)
-; AVX512-NEXT:    vpaddq %zmm0, %zmm2, %zmm0
+; AVX512-NEXT:    vporq %zmm0, %zmm1, %zmm2
+; AVX512-NEXT:    vpxorq %zmm0, %zmm1, %zmm0
+; AVX512-NEXT:    vpsrlq $1, %zmm0, %zmm0
+; AVX512-NEXT:    vpsubq %zmm0, %zmm2, %zmm0
 ; AVX512-NEXT:    retq
   %a_shr_1 = lshr <8 x i64> %a, splat (i64 1)
   %b_shr_1 = lshr <8 x i64> %b, splat (i64 1)
@@ -2086,3 +1523,6 @@ define <8 x i64> @test_lsb_v8i64(<8 x i64> %a, <8 x i64> %b) {
   ret <8 x i64> %sum1
 }
 
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; SSE2: {{.*}}
+; SSE4: {{.*}}



More information about the llvm-commits mailing list