[llvm] [X86] Compute `CTLZ` using fp math for `v4i32` on SSE2 targets (PR #190930)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 27 05:08:58 PDT 2026


https://github.com/def3r updated https://github.com/llvm/llvm-project/pull/190930

>From b69ebc5290dd9da3685013027a1eafde12ad1f3f Mon Sep 17 00:00:00 2001
From: Ayaan Khan <ayaanandayaan2 at gmail.com>
Date: Wed, 8 Apr 2026 10:02:44 +0530
Subject: [PATCH 1/6] [X86] Compute `CTLZ` using fp math for `v4i32` on SSE2
 targets

Co-authored-by: NishiB137 <cs23btech11041 at iith.ac.in>
Co-authored-by: VindhyaP312 <cs23btech11044 at iith.ac.in>
---
 llvm/include/llvm/CodeGen/TargetLowering.h    |   5 +
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |  59 +++++
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  16 ++
 llvm/test/CodeGen/X86/combine-srl.ll          |  62 ++---
 .../CodeGen/X86/expand-vp-int-intrinsics.ll   |  62 ++---
 llvm/test/CodeGen/X86/vec_ctbits.ll           |  62 ++---
 llvm/test/CodeGen/X86/vector-lzcnt-128.ll     | 244 +++++++-----------
 llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll  |  60 ++---
 8 files changed, 276 insertions(+), 294 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 283b0f811dc2f6..968ec0f753b0f2 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -5846,6 +5846,11 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
   /// \returns The expansion result or SDValue() if it fails.
   SDValue expandCTLZ(SDNode *N, SelectionDAG &DAG) const;
 
+  /// Expands a CTLZ node into a sequence of floating point operations.
+  /// \param N Node to expand
+  /// \returns The expansion result or SDValue() if it fails.
+  SDValue expandCTLZWithFP(SDNode *N, SelectionDAG &DAG) const;
+
   /// Expand CTLS (count leading sign bits) nodes.
   /// CTLS(x) = CTLZ(OR(SHL(XOR(x, SRA(x, BW-1)), 1), 1))
   /// \param N Node to expand
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 868171e45be86e..10f459b5ff3784 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -11047,6 +11047,65 @@ SDValue TargetLowering::expandCTLZ(SDNode *Node, SelectionDAG &DAG) const {
   return DAG.getNode(ISD::CTPOP, dl, VT, Op);
 }
 
+SDValue TargetLowering::expandCTLZWithFP(SDNode *Node,
+                                         SelectionDAG &DAG) const {
+  // pseudocode :
+  // if (x == 0) return 32;
+  // f64 f = (f64)x;
+  // u64 i = bitcast<u64>(f);
+  // u32 ilog2 = (u32)(i >> 52) - 1023;
+  // return 31 - ilog2;
+
+  SDLoc dl(Node);
+  EVT VT = Node->getValueType(0);
+  SDValue Op = Node->getOperand(0);
+
+  assert(VT.isVector() && "This expansion is intended for vectors");
+  EVT EltVT = VT.getVectorElementType();
+  if (EltVT != MVT::i32) {
+    return SDValue();
+  }
+
+  EVT FloatVT = VT.changeVectorElementType(*DAG.getContext(), MVT::f64);
+  const fltSemantics &Sem = FloatVT.getVectorElementType().getFltSemantics();
+  unsigned BitWidth = EltVT.getSizeInBits();
+  unsigned MantissaBits = APFloat::semanticsPrecision(Sem);
+  unsigned ExponentBias = APFloat::semanticsMaxExponent(Sem);
+
+  unsigned NumElts = VT.getVectorNumElements();
+  SmallVector<SDValue, 4> FloatElts;
+  for (unsigned i = 0; i < NumElts; i++) {
+    SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op,
+                              DAG.getIntPtrConstant(i, dl));
+    SDValue FElt = DAG.getNode(ISD::UINT_TO_FP, dl, MVT::f64, Elt);
+    FloatElts.push_back(FElt);
+  }
+  SDValue Float = DAG.getBuildVector(FloatVT, dl, FloatElts);
+
+  EVT FloatBitsVT = FloatVT.changeVectorElementTypeToInteger();
+  SDValue FloatBits = DAG.getNode(ISD::BITCAST, dl, FloatBitsVT, Float);
+  SDValue Exp = DAG.getNode(
+      ISD::SRL, dl, FloatBitsVT, FloatBits,
+      DAG.getShiftAmountConstant(MantissaBits - 1, FloatBitsVT, dl));
+  SDValue ExpTrunc = DAG.getNode(ISD::TRUNCATE, dl, VT, Exp);
+  SDValue NonZeroRes = DAG.getNode(
+      ISD::SUB, dl, VT, DAG.getConstant(BitWidth - 1 + ExponentBias, dl, VT),
+      ExpTrunc);
+
+  // Skip Op == 0 case for CTLZ_ZERO_UNDEF
+  if (Node->getOpcode() == ISD::CTLZ_ZERO_UNDEF) {
+    return NonZeroRes;
+  }
+
+  // This Handles the Op == 0 case
+  EVT CmpVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+  SDValue Zero = DAG.getConstant(0, dl, VT);
+  SDValue IsZero = DAG.getSetCC(dl, CmpVT, Op, Zero, ISD::SETEQ);
+
+  return DAG.getNode(ISD::VSELECT, dl, VT, IsZero,
+                     DAG.getConstant(BitWidth, dl, VT), NonZeroRes);
+}
+
 SDValue TargetLowering::expandCTLS(SDNode *Node, SelectionDAG &DAG) const {
   SDLoc dl(Node);
   EVT VT = Node->getValueType(0);
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index e2f3b5f3cd3d5e..471b688edb2280 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -28,6 +28,7 @@
 #include "llvm/Analysis/BlockFrequencyInfo.h"
 #include "llvm/Analysis/ProfileSummaryInfo.h"
 #include "llvm/Analysis/VectorUtils.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
 #include "llvm/CodeGen/LivePhysRegs.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
@@ -1373,6 +1374,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setOperationAction(ISD::SUB,                MVT::i16, Custom);
     setOperationAction(ISD::SUB,                MVT::i32, Custom);
   }
+
   if (Subtarget.hasNDD()) {
     // Enable custom lowering for scalar USUBSAT to optimize usub.sat(X,1)
     // with cmp+adc when NDD is available.
@@ -1381,6 +1383,13 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setOperationAction(ISD::USUBSAT, MVT::i32, Custom);
     setOperationAction(ISD::USUBSAT, MVT::i64, Custom);
   }
+
+  if (!Subtarget.useSoftFloat() && Subtarget.hasSSE2() &&
+      !Subtarget.hasSSSE3()) {
+    setOperationAction(ISD::CTLZ, MVT::v4i32, Custom);
+    setOperationAction(ISD::CTLZ_ZERO_POISON, MVT::v4i32, Custom);
+  }
+
   if (!Subtarget.useSoftFloat() && Subtarget.hasSSE41()) {
     for (MVT RoundedTy : {MVT::f32, MVT::f64, MVT::v4f32, MVT::v2f64}) {
       setOperationAction(ISD::FFLOOR,            RoundedTy,  Legal);
@@ -29723,6 +29732,13 @@ static SDValue LowerVectorCTLZ(SDValue Op, const SDLoc &DL,
   if (VT.is512BitVector() && !Subtarget.hasBWI())
     return splitVectorIntUnary(Op, DAG, DL);
 
+  if (VT == MVT::v4i32 && Subtarget.hasSSE2() && !Subtarget.hasSSSE3()) {
+    const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+    SDValue New = TLI.expandCTLZWithFP(Op.getNode(), DAG);
+    if (New)
+      return New;
+  }
+
   assert(Subtarget.hasSSSE3() && "Expected SSSE3 support for PSHUFB");
   return LowerVectorCTLZInRegLUT(Op, DL, Subtarget, DAG);
 }
diff --git a/llvm/test/CodeGen/X86/combine-srl.ll b/llvm/test/CodeGen/X86/combine-srl.ll
index 7bc90534dcc6e0..40dee81d87a3cb 100644
--- a/llvm/test/CodeGen/X86/combine-srl.ll
+++ b/llvm/test/CodeGen/X86/combine-srl.ll
@@ -426,44 +426,34 @@ define <4 x i32> @combine_vec_lshr_lzcnt_bit1(<4 x i32> %x) {
 ; SSE2-LABEL: combine_vec_lshr_lzcnt_bit1:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
+; SSE2-NEXT:    movd %xmm1, %eax
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    cvtsi2sd %eax, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; SSE2-NEXT:    movd %xmm2, %eax
+; SSE2-NEXT:    xorps %xmm2, %xmm2
+; SSE2-NEXT:    cvtsi2sd %eax, %xmm2
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE2-NEXT:    psrlq $52, %xmm2
+; SSE2-NEXT:    movd %xmm0, %eax
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    cvtsi2sd %eax, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,1,1]
+; SSE2-NEXT:    movd %xmm3, %eax
+; SSE2-NEXT:    xorps %xmm3, %xmm3
+; SSE2-NEXT:    cvtsi2sd %eax, %xmm3
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
+; SSE2-NEXT:    psrlq $52, %xmm1
+; SSE2-NEXT:    packssdw %xmm2, %xmm1
+; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
+; SSE2-NEXT:    psubd %xmm1, %xmm2
+; SSE2-NEXT:    pxor %xmm1, %xmm1
+; SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $1, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $2, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $4, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $8, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $16, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    pcmpeqd %xmm1, %xmm1
-; SSE2-NEXT:    pxor %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrlw $1, %xmm1
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    psubb %xmm1, %xmm0
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    psrlw $2, %xmm0
-; SSE2-NEXT:    pand %xmm1, %xmm0
-; SSE2-NEXT:    paddb %xmm2, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrlw $4, %xmm1
-; SSE2-NEXT:    paddb %xmm1, %xmm0
+; SSE2-NEXT:    pandn %xmm2, %xmm1
 ; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    pxor %xmm1, %xmm1
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE2-NEXT:    psadbw %xmm1, %xmm2
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE2-NEXT:    psadbw %xmm1, %xmm0
-; SSE2-NEXT:    packuswb %xmm2, %xmm0
+; SSE2-NEXT:    por %xmm1, %xmm0
 ; SSE2-NEXT:    psrld $5, %xmm0
 ; SSE2-NEXT:    retq
 ;
diff --git a/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll b/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll
index 455815d8b93ff7..833ea166c1b097 100644
--- a/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll
@@ -1282,44 +1282,34 @@ define <4 x i32> @vp_ctlz_v4i32(<4 x i32> %va, <4 x i1> %m, i32 zeroext %evl) {
 ;
 ; SSE-LABEL: vp_ctlz_v4i32:
 ; SSE:       # %bb.0:
+; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
+; SSE-NEXT:    movd %xmm1, %eax
+; SSE-NEXT:    xorps %xmm1, %xmm1
+; SSE-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; SSE-NEXT:    movd %xmm2, %eax
+; SSE-NEXT:    xorps %xmm2, %xmm2
+; SSE-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE-NEXT:    psrlq $52, %xmm2
+; SSE-NEXT:    movd %xmm0, %eax
+; SSE-NEXT:    xorps %xmm1, %xmm1
+; SSE-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,1,1]
+; SSE-NEXT:    movd %xmm3, %eax
+; SSE-NEXT:    xorps %xmm3, %xmm3
+; SSE-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
+; SSE-NEXT:    psrlq $52, %xmm1
+; SSE-NEXT:    packssdw %xmm2, %xmm1
+; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
+; SSE-NEXT:    psubd %xmm1, %xmm2
+; SSE-NEXT:    pxor %xmm1, %xmm1
+; SSE-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE-NEXT:    movdqa %xmm0, %xmm1
-; SSE-NEXT:    psrld $1, %xmm1
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    movdqa %xmm0, %xmm1
-; SSE-NEXT:    psrld $2, %xmm1
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    movdqa %xmm0, %xmm1
-; SSE-NEXT:    psrld $4, %xmm1
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    movdqa %xmm0, %xmm1
-; SSE-NEXT:    psrld $8, %xmm1
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    movdqa %xmm0, %xmm1
-; SSE-NEXT:    psrld $16, %xmm1
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
-; SSE-NEXT:    pxor %xmm1, %xmm0
-; SSE-NEXT:    movdqa %xmm0, %xmm1
-; SSE-NEXT:    psrlw $1, %xmm1
-; SSE-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE-NEXT:    psubb %xmm1, %xmm0
-; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
-; SSE-NEXT:    movdqa %xmm0, %xmm2
-; SSE-NEXT:    pand %xmm1, %xmm2
-; SSE-NEXT:    psrlw $2, %xmm0
-; SSE-NEXT:    pand %xmm1, %xmm0
-; SSE-NEXT:    paddb %xmm2, %xmm0
-; SSE-NEXT:    movdqa %xmm0, %xmm1
-; SSE-NEXT:    psrlw $4, %xmm1
-; SSE-NEXT:    paddb %xmm1, %xmm0
+; SSE-NEXT:    pandn %xmm2, %xmm1
 ; SSE-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    pxor %xmm1, %xmm1
-; SSE-NEXT:    movdqa %xmm0, %xmm2
-; SSE-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE-NEXT:    psadbw %xmm1, %xmm2
-; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE-NEXT:    psadbw %xmm1, %xmm0
-; SSE-NEXT:    packuswb %xmm2, %xmm0
+; SSE-NEXT:    por %xmm1, %xmm0
 ; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: vp_ctlz_v4i32:
diff --git a/llvm/test/CodeGen/X86/vec_ctbits.ll b/llvm/test/CodeGen/X86/vec_ctbits.ll
index 370f88d644b573..0666e6316885e5 100644
--- a/llvm/test/CodeGen/X86/vec_ctbits.ll
+++ b/llvm/test/CodeGen/X86/vec_ctbits.ll
@@ -140,44 +140,34 @@ define <2 x i32> @promtz(<2 x i32> %a) nounwind {
 define <2 x i32> @promlz(<2 x i32> %a) nounwind {
 ; CHECK-LABEL: promlz:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
+; CHECK-NEXT:    movd %xmm1, %eax
+; CHECK-NEXT:    xorps %xmm1, %xmm1
+; CHECK-NEXT:    cvtsi2sd %rax, %xmm1
+; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; CHECK-NEXT:    movd %xmm2, %eax
+; CHECK-NEXT:    xorps %xmm2, %xmm2
+; CHECK-NEXT:    cvtsi2sd %rax, %xmm2
+; CHECK-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; CHECK-NEXT:    psrlq $52, %xmm2
+; CHECK-NEXT:    movd %xmm0, %eax
+; CHECK-NEXT:    xorps %xmm1, %xmm1
+; CHECK-NEXT:    cvtsi2sd %rax, %xmm1
+; CHECK-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,1,1]
+; CHECK-NEXT:    movd %xmm3, %eax
+; CHECK-NEXT:    xorps %xmm3, %xmm3
+; CHECK-NEXT:    cvtsi2sd %rax, %xmm3
+; CHECK-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
+; CHECK-NEXT:    psrlq $52, %xmm1
+; CHECK-NEXT:    packssdw %xmm2, %xmm1
+; CHECK-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
+; CHECK-NEXT:    psubd %xmm1, %xmm2
+; CHECK-NEXT:    pxor %xmm1, %xmm1
+; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
 ; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrld $1, %xmm1
-; CHECK-NEXT:    por %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrld $2, %xmm1
-; CHECK-NEXT:    por %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrld $4, %xmm1
-; CHECK-NEXT:    por %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrld $8, %xmm1
-; CHECK-NEXT:    por %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrld $16, %xmm1
-; CHECK-NEXT:    por %xmm1, %xmm0
-; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
-; CHECK-NEXT:    pxor %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrlw $1, %xmm1
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; CHECK-NEXT:    psubb %xmm1, %xmm0
-; CHECK-NEXT:    movdqa {{.*#+}} xmm1 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
-; CHECK-NEXT:    movdqa %xmm0, %xmm2
-; CHECK-NEXT:    pand %xmm1, %xmm2
-; CHECK-NEXT:    psrlw $2, %xmm0
-; CHECK-NEXT:    pand %xmm1, %xmm0
-; CHECK-NEXT:    paddb %xmm2, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrlw $4, %xmm1
-; CHECK-NEXT:    paddb %xmm1, %xmm0
+; CHECK-NEXT:    pandn %xmm2, %xmm1
 ; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; CHECK-NEXT:    pxor %xmm1, %xmm1
-; CHECK-NEXT:    movdqa %xmm0, %xmm2
-; CHECK-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; CHECK-NEXT:    psadbw %xmm1, %xmm2
-; CHECK-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; CHECK-NEXT:    psadbw %xmm1, %xmm0
-; CHECK-NEXT:    packuswb %xmm2, %xmm0
+; CHECK-NEXT:    por %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %c = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %a, i1 false)
   ret <2 x i32> %c
diff --git a/llvm/test/CodeGen/X86/vector-lzcnt-128.ll b/llvm/test/CodeGen/X86/vector-lzcnt-128.ll
index cfb5fac2fd7aa8..380e8ca9e26c1f 100644
--- a/llvm/test/CodeGen/X86/vector-lzcnt-128.ll
+++ b/llvm/test/CodeGen/X86/vector-lzcnt-128.ll
@@ -572,86 +572,66 @@ define <2 x i64> @testv2i64u(<2 x i64> %in) nounwind {
 define <4 x i32> @testv4i32(<4 x i32> %in) nounwind {
 ; SSE2-LABEL: testv4i32:
 ; SSE2:       # %bb.0:
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
+; SSE2-NEXT:    movd %xmm1, %eax
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; SSE2-NEXT:    movd %xmm2, %eax
+; SSE2-NEXT:    xorps %xmm2, %xmm2
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE2-NEXT:    psrlq $52, %xmm2
+; SSE2-NEXT:    movd %xmm0, %eax
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,1,1]
+; SSE2-NEXT:    movd %xmm3, %eax
+; SSE2-NEXT:    xorps %xmm3, %xmm3
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
+; SSE2-NEXT:    psrlq $52, %xmm1
+; SSE2-NEXT:    packssdw %xmm2, %xmm1
+; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
+; SSE2-NEXT:    psubd %xmm1, %xmm2
+; SSE2-NEXT:    pxor %xmm1, %xmm1
+; SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $1, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $2, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $4, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $8, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $16, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    pcmpeqd %xmm1, %xmm1
-; SSE2-NEXT:    pxor %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrlw $1, %xmm1
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    psubb %xmm1, %xmm0
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    psrlw $2, %xmm0
-; SSE2-NEXT:    pand %xmm1, %xmm0
-; SSE2-NEXT:    paddb %xmm2, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrlw $4, %xmm1
-; SSE2-NEXT:    paddb %xmm1, %xmm0
+; SSE2-NEXT:    pandn %xmm2, %xmm1
 ; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    pxor %xmm1, %xmm1
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE2-NEXT:    psadbw %xmm1, %xmm2
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE2-NEXT:    psadbw %xmm1, %xmm0
-; SSE2-NEXT:    packuswb %xmm2, %xmm0
+; SSE2-NEXT:    por %xmm1, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE3-LABEL: testv4i32:
 ; SSE3:       # %bb.0:
+; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
+; SSE3-NEXT:    movd %xmm1, %eax
+; SSE3-NEXT:    xorps %xmm1, %xmm1
+; SSE3-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; SSE3-NEXT:    movd %xmm2, %eax
+; SSE3-NEXT:    xorps %xmm2, %xmm2
+; SSE3-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE3-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE3-NEXT:    psrlq $52, %xmm2
+; SSE3-NEXT:    movd %xmm0, %eax
+; SSE3-NEXT:    xorps %xmm1, %xmm1
+; SSE3-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE3-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,1,1]
+; SSE3-NEXT:    movd %xmm3, %eax
+; SSE3-NEXT:    xorps %xmm3, %xmm3
+; SSE3-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE3-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
+; SSE3-NEXT:    psrlq $52, %xmm1
+; SSE3-NEXT:    packssdw %xmm2, %xmm1
+; SSE3-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
+; SSE3-NEXT:    psubd %xmm1, %xmm2
+; SSE3-NEXT:    pxor %xmm1, %xmm1
+; SSE3-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrld $1, %xmm1
-; SSE3-NEXT:    por %xmm1, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrld $2, %xmm1
-; SSE3-NEXT:    por %xmm1, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrld $4, %xmm1
-; SSE3-NEXT:    por %xmm1, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrld $8, %xmm1
-; SSE3-NEXT:    por %xmm1, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrld $16, %xmm1
-; SSE3-NEXT:    por %xmm1, %xmm0
-; SSE3-NEXT:    pcmpeqd %xmm1, %xmm1
-; SSE3-NEXT:    pxor %xmm1, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrlw $1, %xmm1
-; SSE3-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE3-NEXT:    psubb %xmm1, %xmm0
-; SSE3-NEXT:    movdqa {{.*#+}} xmm1 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
-; SSE3-NEXT:    movdqa %xmm0, %xmm2
-; SSE3-NEXT:    pand %xmm1, %xmm2
-; SSE3-NEXT:    psrlw $2, %xmm0
-; SSE3-NEXT:    pand %xmm1, %xmm0
-; SSE3-NEXT:    paddb %xmm2, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrlw $4, %xmm1
-; SSE3-NEXT:    paddb %xmm1, %xmm0
+; SSE3-NEXT:    pandn %xmm2, %xmm1
 ; SSE3-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE3-NEXT:    pxor %xmm1, %xmm1
-; SSE3-NEXT:    movdqa %xmm0, %xmm2
-; SSE3-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE3-NEXT:    psadbw %xmm1, %xmm2
-; SSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE3-NEXT:    psadbw %xmm1, %xmm0
-; SSE3-NEXT:    packuswb %xmm2, %xmm0
+; SSE3-NEXT:    por %xmm1, %xmm0
 ; SSE3-NEXT:    retq
 ;
 ; SSSE3-LABEL: testv4i32:
@@ -821,86 +801,54 @@ define <4 x i32> @testv4i32(<4 x i32> %in) nounwind {
 define <4 x i32> @testv4i32u(<4 x i32> %in) nounwind {
 ; SSE2-LABEL: testv4i32u:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $1, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $2, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $4, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $8, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrld $16, %xmm1
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    pcmpeqd %xmm1, %xmm1
-; SSE2-NEXT:    pxor %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrlw $1, %xmm1
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    psubb %xmm1, %xmm0
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    psrlw $2, %xmm0
-; SSE2-NEXT:    pand %xmm1, %xmm0
-; SSE2-NEXT:    paddb %xmm2, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    psrlw $4, %xmm1
-; SSE2-NEXT:    paddb %xmm1, %xmm0
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    pxor %xmm1, %xmm1
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE2-NEXT:    psadbw %xmm1, %xmm2
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE2-NEXT:    psadbw %xmm1, %xmm0
-; SSE2-NEXT:    packuswb %xmm2, %xmm0
+; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
+; SSE2-NEXT:    movd %xmm1, %eax
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; SSE2-NEXT:    movd %xmm2, %eax
+; SSE2-NEXT:    xorps %xmm2, %xmm2
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE2-NEXT:    psrlq $52, %xmm2
+; SSE2-NEXT:    movd %xmm0, %eax
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; SSE2-NEXT:    movd %xmm0, %eax
+; SSE2-NEXT:    xorps %xmm0, %xmm0
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm0
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm0[0]
+; SSE2-NEXT:    psrlq $52, %xmm1
+; SSE2-NEXT:    packssdw %xmm2, %xmm1
+; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [1054,1054,1054,1054]
+; SSE2-NEXT:    psubd %xmm1, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE3-LABEL: testv4i32u:
 ; SSE3:       # %bb.0:
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrld $1, %xmm1
-; SSE3-NEXT:    por %xmm1, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrld $2, %xmm1
-; SSE3-NEXT:    por %xmm1, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrld $4, %xmm1
-; SSE3-NEXT:    por %xmm1, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrld $8, %xmm1
-; SSE3-NEXT:    por %xmm1, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrld $16, %xmm1
-; SSE3-NEXT:    por %xmm1, %xmm0
-; SSE3-NEXT:    pcmpeqd %xmm1, %xmm1
-; SSE3-NEXT:    pxor %xmm1, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrlw $1, %xmm1
-; SSE3-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE3-NEXT:    psubb %xmm1, %xmm0
-; SSE3-NEXT:    movdqa {{.*#+}} xmm1 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
-; SSE3-NEXT:    movdqa %xmm0, %xmm2
-; SSE3-NEXT:    pand %xmm1, %xmm2
-; SSE3-NEXT:    psrlw $2, %xmm0
-; SSE3-NEXT:    pand %xmm1, %xmm0
-; SSE3-NEXT:    paddb %xmm2, %xmm0
-; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    psrlw $4, %xmm1
-; SSE3-NEXT:    paddb %xmm1, %xmm0
-; SSE3-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE3-NEXT:    pxor %xmm1, %xmm1
-; SSE3-NEXT:    movdqa %xmm0, %xmm2
-; SSE3-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE3-NEXT:    psadbw %xmm1, %xmm2
-; SSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE3-NEXT:    psadbw %xmm1, %xmm0
-; SSE3-NEXT:    packuswb %xmm2, %xmm0
+; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
+; SSE3-NEXT:    movd %xmm1, %eax
+; SSE3-NEXT:    xorps %xmm1, %xmm1
+; SSE3-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; SSE3-NEXT:    movd %xmm2, %eax
+; SSE3-NEXT:    xorps %xmm2, %xmm2
+; SSE3-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE3-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE3-NEXT:    psrlq $52, %xmm2
+; SSE3-NEXT:    movd %xmm0, %eax
+; SSE3-NEXT:    xorps %xmm1, %xmm1
+; SSE3-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; SSE3-NEXT:    movd %xmm0, %eax
+; SSE3-NEXT:    xorps %xmm0, %xmm0
+; SSE3-NEXT:    cvtsi2sd %rax, %xmm0
+; SSE3-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm0[0]
+; SSE3-NEXT:    psrlq $52, %xmm1
+; SSE3-NEXT:    packssdw %xmm2, %xmm1
+; SSE3-NEXT:    movdqa {{.*#+}} xmm0 = [1054,1054,1054,1054]
+; SSE3-NEXT:    psubd %xmm1, %xmm0
 ; SSE3-NEXT:    retq
 ;
 ; SSSE3-LABEL: testv4i32u:
diff --git a/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll b/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll
index a1b277efde6ffd..f70f7e204c86a8 100644
--- a/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll
+++ b/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll
@@ -6,44 +6,28 @@ declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1 immarg)
 define <2 x i32> @illegal_ctlz(<2 x i32> %v1) {
 ; CHECK-LABEL: illegal_ctlz:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrld $1, %xmm1
-; CHECK-NEXT:    por %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrld $2, %xmm1
-; CHECK-NEXT:    por %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrld $4, %xmm1
-; CHECK-NEXT:    por %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrld $8, %xmm1
-; CHECK-NEXT:    por %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrld $16, %xmm1
-; CHECK-NEXT:    por %xmm1, %xmm0
-; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
-; CHECK-NEXT:    pxor %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrlw $1, %xmm1
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; CHECK-NEXT:    psubb %xmm1, %xmm0
-; CHECK-NEXT:    movdqa {{.*#+}} xmm1 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
-; CHECK-NEXT:    movdqa %xmm0, %xmm2
-; CHECK-NEXT:    pand %xmm1, %xmm2
-; CHECK-NEXT:    psrlw $2, %xmm0
-; CHECK-NEXT:    pand %xmm1, %xmm0
-; CHECK-NEXT:    paddb %xmm2, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    psrlw $4, %xmm1
-; CHECK-NEXT:    paddb %xmm1, %xmm0
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; CHECK-NEXT:    pxor %xmm1, %xmm1
-; CHECK-NEXT:    movdqa %xmm0, %xmm2
-; CHECK-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; CHECK-NEXT:    psadbw %xmm1, %xmm2
-; CHECK-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; CHECK-NEXT:    psadbw %xmm1, %xmm0
-; CHECK-NEXT:    packuswb %xmm2, %xmm0
+; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
+; CHECK-NEXT:    movd %xmm1, %eax
+; CHECK-NEXT:    xorps %xmm1, %xmm1
+; CHECK-NEXT:    cvtsi2sd %rax, %xmm1
+; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; CHECK-NEXT:    movd %xmm2, %eax
+; CHECK-NEXT:    xorps %xmm2, %xmm2
+; CHECK-NEXT:    cvtsi2sd %rax, %xmm2
+; CHECK-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; CHECK-NEXT:    psrlq $52, %xmm2
+; CHECK-NEXT:    movd %xmm0, %eax
+; CHECK-NEXT:    xorps %xmm1, %xmm1
+; CHECK-NEXT:    cvtsi2sd %rax, %xmm1
+; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
+; CHECK-NEXT:    movd %xmm0, %eax
+; CHECK-NEXT:    xorps %xmm0, %xmm0
+; CHECK-NEXT:    cvtsi2sd %rax, %xmm0
+; CHECK-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm0[0]
+; CHECK-NEXT:    psrlq $52, %xmm1
+; CHECK-NEXT:    packssdw %xmm2, %xmm1
+; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [1054,1054,1054,1054]
+; CHECK-NEXT:    psubd %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %v2 = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %v1, i1 true)
   ret <2 x i32> %v2

>From f2679b99d61c92893d90a55eacb70f813cbbb7b2 Mon Sep 17 00:00:00 2001
From: Ayaan Khan <ayaanandayaan2 at gmail.com>
Date: Thu, 9 Apr 2026 01:19:48 +0530
Subject: [PATCH 2/6] Apply suggestions

---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |  47 +++---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  17 +--
 llvm/test/CodeGen/X86/combine-srl.ll          |  36 ++---
 .../CodeGen/X86/expand-vp-int-intrinsics.ll   |  34 ++---
 llvm/test/CodeGen/X86/vec_ctbits.ll           |  34 ++---
 llvm/test/CodeGen/X86/vector-lzcnt-128.ll     | 138 +++++++-----------
 llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll  |  35 ++---
 7 files changed, 135 insertions(+), 206 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 10f459b5ff3784..b29d02f79ff6cd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -11060,42 +11060,37 @@ SDValue TargetLowering::expandCTLZWithFP(SDNode *Node,
   EVT VT = Node->getValueType(0);
   SDValue Op = Node->getOperand(0);
 
-  assert(VT.isVector() && "This expansion is intended for vectors");
   EVT EltVT = VT.getVectorElementType();
-  if (EltVT != MVT::i32) {
+  if (EltVT != MVT::i32)
     return SDValue();
-  }
 
-  EVT FloatVT = VT.changeVectorElementType(*DAG.getContext(), MVT::f64);
-  const fltSemantics &Sem = FloatVT.getVectorElementType().getFltSemantics();
+  EVT HalfVT = VT.getHalfNumVectorElementsVT(*DAG.getContext());
+  EVT HalfFloatVT = HalfVT.changeVectorElementType(*DAG.getContext(), MVT::f64);
+  EVT HalfFloatBitsVT = HalfFloatVT.changeVectorElementTypeToInteger();
+
+  const fltSemantics &Sem = HalfFloatVT.getVectorElementType().getFltSemantics();
   unsigned BitWidth = EltVT.getSizeInBits();
   unsigned MantissaBits = APFloat::semanticsPrecision(Sem);
   unsigned ExponentBias = APFloat::semanticsMaxExponent(Sem);
 
-  unsigned NumElts = VT.getVectorNumElements();
-  SmallVector<SDValue, 4> FloatElts;
-  for (unsigned i = 0; i < NumElts; i++) {
-    SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op,
-                              DAG.getIntPtrConstant(i, dl));
-    SDValue FElt = DAG.getNode(ISD::UINT_TO_FP, dl, MVT::f64, Elt);
-    FloatElts.push_back(FElt);
-  }
-  SDValue Float = DAG.getBuildVector(FloatVT, dl, FloatElts);
-
-  EVT FloatBitsVT = FloatVT.changeVectorElementTypeToInteger();
-  SDValue FloatBits = DAG.getNode(ISD::BITCAST, dl, FloatBitsVT, Float);
-  SDValue Exp = DAG.getNode(
-      ISD::SRL, dl, FloatBitsVT, FloatBits,
-      DAG.getShiftAmountConstant(MantissaBits - 1, FloatBitsVT, dl));
-  SDValue ExpTrunc = DAG.getNode(ISD::TRUNCATE, dl, VT, Exp);
-  SDValue NonZeroRes = DAG.getNode(
-      ISD::SUB, dl, VT, DAG.getConstant(BitWidth - 1 + ExponentBias, dl, VT),
-      ExpTrunc);
+  auto ComputeExp = [&](SDValue Half) {
+    SDValue Float = DAG.getNode(ISD::UINT_TO_FP, dl, HalfFloatVT, Half);
+    SDValue Bits = DAG.getBitcast(HalfFloatBitsVT, Float);
+    SDValue Exp = DAG.getNode(ISD::SRL, dl, HalfFloatBitsVT, Bits,
+        DAG.getShiftAmountConstant(MantissaBits - 1, HalfFloatBitsVT, dl));
+    return DAG.getNode(ISD::TRUNCATE, dl, HalfVT, Exp);
+  };
+
+  SDValue ExpTruncLo = ComputeExp(DAG.getExtractSubvector(dl, HalfVT, Op, 0));
+  SDValue ExpTruncHi = ComputeExp(
+      DAG.getExtractSubvector(dl, HalfVT, Op, VT.getVectorNumElements() / 2));
+  SDValue Exp = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, ExpTruncLo, ExpTruncHi);
+  SDValue NonZeroRes = DAG.getNode(ISD::SUB, dl, VT,
+      DAG.getConstant(BitWidth - 1 + ExponentBias, dl, VT), Exp);
 
   // Skip Op == 0 case for CTLZ_ZERO_UNDEF
-  if (Node->getOpcode() == ISD::CTLZ_ZERO_UNDEF) {
+  if (Node->getOpcode() == ISD::CTLZ_ZERO_UNDEF)
     return NonZeroRes;
-  }
 
   // This Handles the Op == 0 case
   EVT CmpVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 471b688edb2280..9bb76b3f25a7ec 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -1341,6 +1341,11 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setOperationAction(ISD::STRICT_FSUB,        MVT::v2f64, Legal);
     setOperationAction(ISD::STRICT_FMUL,        MVT::v2f64, Legal);
     setOperationAction(ISD::STRICT_FDIV,        MVT::v2f64, Legal);
+
+    if (!Subtarget.hasSSSE3()) {
+      setOperationAction(ISD::CTLZ, MVT::v4i32, Custom);
+      setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::v4i32, Custom);
+    }
   }
 
   if (!Subtarget.useSoftFloat() && Subtarget.hasGFNI()) {
@@ -1375,15 +1380,6 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setOperationAction(ISD::SUB,                MVT::i32, Custom);
   }
 
-  if (Subtarget.hasNDD()) {
-    // Enable custom lowering for scalar USUBSAT to optimize usub.sat(X,1)
-    // with cmp+adc when NDD is available.
-    setOperationAction(ISD::USUBSAT, MVT::i8, Custom);
-    setOperationAction(ISD::USUBSAT, MVT::i16, Custom);
-    setOperationAction(ISD::USUBSAT, MVT::i32, Custom);
-    setOperationAction(ISD::USUBSAT, MVT::i64, Custom);
-  }
-
   if (!Subtarget.useSoftFloat() && Subtarget.hasSSE2() &&
       !Subtarget.hasSSSE3()) {
     setOperationAction(ISD::CTLZ, MVT::v4i32, Custom);
@@ -29734,8 +29730,7 @@ static SDValue LowerVectorCTLZ(SDValue Op, const SDLoc &DL,
 
   if (VT == MVT::v4i32 && Subtarget.hasSSE2() && !Subtarget.hasSSSE3()) {
     const TargetLowering &TLI = DAG.getTargetLoweringInfo();
-    SDValue New = TLI.expandCTLZWithFP(Op.getNode(), DAG);
-    if (New)
+    if (SDValue New = TLI.expandCTLZWithFP(Op.getNode(), DAG))
       return New;
   }
 
diff --git a/llvm/test/CodeGen/X86/combine-srl.ll b/llvm/test/CodeGen/X86/combine-srl.ll
index 40dee81d87a3cb..ec560050828618 100644
--- a/llvm/test/CodeGen/X86/combine-srl.ll
+++ b/llvm/test/CodeGen/X86/combine-srl.ll
@@ -425,30 +425,22 @@ define <4 x i32> @combine_vec_lshr_lzcnt_bit0(<4 x i32> %x) {
 define <4 x i32> @combine_vec_lshr_lzcnt_bit1(<4 x i32> %x) {
 ; SSE2-LABEL: combine_vec_lshr_lzcnt_bit1:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
-; SSE2-NEXT:    movd %xmm1, %eax
-; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    cvtsi2sd %eax, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    cvtsi2sd %eax, %xmm2
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE2-NEXT:    andpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    xorpd %xmm1, %xmm1
+; SSE2-NEXT:    movapd %xmm0, %xmm2
+; SSE2-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
+; SSE2-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    orpd %xmm3, %xmm2
+; SSE2-NEXT:    subpd %xmm3, %xmm2
 ; SSE2-NEXT:    psrlq $52, %xmm2
-; SSE2-NEXT:    movd %xmm0, %eax
-; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    cvtsi2sd %eax, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,1,1]
-; SSE2-NEXT:    movd %xmm3, %eax
-; SSE2-NEXT:    xorps %xmm3, %xmm3
-; SSE2-NEXT:    cvtsi2sd %eax, %xmm3
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
-; SSE2-NEXT:    psrlq $52, %xmm1
-; SSE2-NEXT:    packssdw %xmm2, %xmm1
+; SSE2-NEXT:    movapd %xmm0, %xmm4
+; SSE2-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
+; SSE2-NEXT:    orpd %xmm3, %xmm4
+; SSE2-NEXT:    subpd %xmm3, %xmm4
+; SSE2-NEXT:    psrlq $52, %xmm4
+; SSE2-NEXT:    packssdw %xmm2, %xmm4
 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
-; SSE2-NEXT:    psubd %xmm1, %xmm2
-; SSE2-NEXT:    pxor %xmm1, %xmm1
+; SSE2-NEXT:    psubd %xmm4, %xmm2
 ; SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
 ; SSE2-NEXT:    pandn %xmm2, %xmm1
diff --git a/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll b/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll
index 833ea166c1b097..5070b20095108c 100644
--- a/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll
@@ -1282,29 +1282,21 @@ define <4 x i32> @vp_ctlz_v4i32(<4 x i32> %va, <4 x i1> %m, i32 zeroext %evl) {
 ;
 ; SSE-LABEL: vp_ctlz_v4i32:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
-; SSE-NEXT:    movd %xmm1, %eax
-; SSE-NEXT:    xorps %xmm1, %xmm1
-; SSE-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
-; SSE-NEXT:    movd %xmm2, %eax
-; SSE-NEXT:    xorps %xmm2, %xmm2
-; SSE-NEXT:    cvtsi2sd %rax, %xmm2
-; SSE-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE-NEXT:    xorpd %xmm1, %xmm1
+; SSE-NEXT:    movapd %xmm0, %xmm2
+; SSE-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
+; SSE-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE-NEXT:    orpd %xmm3, %xmm2
+; SSE-NEXT:    subpd %xmm3, %xmm2
 ; SSE-NEXT:    psrlq $52, %xmm2
-; SSE-NEXT:    movd %xmm0, %eax
-; SSE-NEXT:    xorps %xmm1, %xmm1
-; SSE-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,1,1]
-; SSE-NEXT:    movd %xmm3, %eax
-; SSE-NEXT:    xorps %xmm3, %xmm3
-; SSE-NEXT:    cvtsi2sd %rax, %xmm3
-; SSE-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
-; SSE-NEXT:    psrlq $52, %xmm1
-; SSE-NEXT:    packssdw %xmm2, %xmm1
+; SSE-NEXT:    movapd %xmm0, %xmm4
+; SSE-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
+; SSE-NEXT:    orpd %xmm3, %xmm4
+; SSE-NEXT:    subpd %xmm3, %xmm4
+; SSE-NEXT:    psrlq $52, %xmm4
+; SSE-NEXT:    packssdw %xmm2, %xmm4
 ; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
-; SSE-NEXT:    psubd %xmm1, %xmm2
-; SSE-NEXT:    pxor %xmm1, %xmm1
+; SSE-NEXT:    psubd %xmm4, %xmm2
 ; SSE-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE-NEXT:    movdqa %xmm0, %xmm1
 ; SSE-NEXT:    pandn %xmm2, %xmm1
diff --git a/llvm/test/CodeGen/X86/vec_ctbits.ll b/llvm/test/CodeGen/X86/vec_ctbits.ll
index 0666e6316885e5..22c2577ff1b6b7 100644
--- a/llvm/test/CodeGen/X86/vec_ctbits.ll
+++ b/llvm/test/CodeGen/X86/vec_ctbits.ll
@@ -140,29 +140,21 @@ define <2 x i32> @promtz(<2 x i32> %a) nounwind {
 define <2 x i32> @promlz(<2 x i32> %a) nounwind {
 ; CHECK-LABEL: promlz:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
-; CHECK-NEXT:    movd %xmm1, %eax
-; CHECK-NEXT:    xorps %xmm1, %xmm1
-; CHECK-NEXT:    cvtsi2sd %rax, %xmm1
-; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
-; CHECK-NEXT:    movd %xmm2, %eax
-; CHECK-NEXT:    xorps %xmm2, %xmm2
-; CHECK-NEXT:    cvtsi2sd %rax, %xmm2
-; CHECK-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; CHECK-NEXT:    xorpd %xmm1, %xmm1
+; CHECK-NEXT:    movapd %xmm0, %xmm2
+; CHECK-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
+; CHECK-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
+; CHECK-NEXT:    orpd %xmm3, %xmm2
+; CHECK-NEXT:    subpd %xmm3, %xmm2
 ; CHECK-NEXT:    psrlq $52, %xmm2
-; CHECK-NEXT:    movd %xmm0, %eax
-; CHECK-NEXT:    xorps %xmm1, %xmm1
-; CHECK-NEXT:    cvtsi2sd %rax, %xmm1
-; CHECK-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,1,1]
-; CHECK-NEXT:    movd %xmm3, %eax
-; CHECK-NEXT:    xorps %xmm3, %xmm3
-; CHECK-NEXT:    cvtsi2sd %rax, %xmm3
-; CHECK-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
-; CHECK-NEXT:    psrlq $52, %xmm1
-; CHECK-NEXT:    packssdw %xmm2, %xmm1
+; CHECK-NEXT:    movapd %xmm0, %xmm4
+; CHECK-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
+; CHECK-NEXT:    orpd %xmm3, %xmm4
+; CHECK-NEXT:    subpd %xmm3, %xmm4
+; CHECK-NEXT:    psrlq $52, %xmm4
+; CHECK-NEXT:    packssdw %xmm2, %xmm4
 ; CHECK-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
-; CHECK-NEXT:    psubd %xmm1, %xmm2
-; CHECK-NEXT:    pxor %xmm1, %xmm1
+; CHECK-NEXT:    psubd %xmm4, %xmm2
 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
 ; CHECK-NEXT:    movdqa %xmm0, %xmm1
 ; CHECK-NEXT:    pandn %xmm2, %xmm1
diff --git a/llvm/test/CodeGen/X86/vector-lzcnt-128.ll b/llvm/test/CodeGen/X86/vector-lzcnt-128.ll
index 380e8ca9e26c1f..13b7bee8474e1a 100644
--- a/llvm/test/CodeGen/X86/vector-lzcnt-128.ll
+++ b/llvm/test/CodeGen/X86/vector-lzcnt-128.ll
@@ -572,29 +572,21 @@ define <2 x i64> @testv2i64u(<2 x i64> %in) nounwind {
 define <4 x i32> @testv4i32(<4 x i32> %in) nounwind {
 ; SSE2-LABEL: testv4i32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
-; SSE2-NEXT:    movd %xmm1, %eax
-; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE2-NEXT:    xorpd %xmm1, %xmm1
+; SSE2-NEXT:    movapd %xmm0, %xmm2
+; SSE2-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
+; SSE2-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    orpd %xmm3, %xmm2
+; SSE2-NEXT:    subpd %xmm3, %xmm2
 ; SSE2-NEXT:    psrlq $52, %xmm2
-; SSE2-NEXT:    movd %xmm0, %eax
-; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,1,1]
-; SSE2-NEXT:    movd %xmm3, %eax
-; SSE2-NEXT:    xorps %xmm3, %xmm3
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
-; SSE2-NEXT:    psrlq $52, %xmm1
-; SSE2-NEXT:    packssdw %xmm2, %xmm1
+; SSE2-NEXT:    movapd %xmm0, %xmm4
+; SSE2-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
+; SSE2-NEXT:    orpd %xmm3, %xmm4
+; SSE2-NEXT:    subpd %xmm3, %xmm4
+; SSE2-NEXT:    psrlq $52, %xmm4
+; SSE2-NEXT:    packssdw %xmm2, %xmm4
 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
-; SSE2-NEXT:    psubd %xmm1, %xmm2
-; SSE2-NEXT:    pxor %xmm1, %xmm1
+; SSE2-NEXT:    psubd %xmm4, %xmm2
 ; SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
 ; SSE2-NEXT:    pandn %xmm2, %xmm1
@@ -604,29 +596,21 @@ define <4 x i32> @testv4i32(<4 x i32> %in) nounwind {
 ;
 ; SSE3-LABEL: testv4i32:
 ; SSE3:       # %bb.0:
-; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
-; SSE3-NEXT:    movd %xmm1, %eax
-; SSE3-NEXT:    xorps %xmm1, %xmm1
-; SSE3-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
-; SSE3-NEXT:    movd %xmm2, %eax
-; SSE3-NEXT:    xorps %xmm2, %xmm2
-; SSE3-NEXT:    cvtsi2sd %rax, %xmm2
-; SSE3-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE3-NEXT:    xorpd %xmm1, %xmm1
+; SSE3-NEXT:    movapd %xmm0, %xmm2
+; SSE3-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
+; SSE3-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE3-NEXT:    orpd %xmm3, %xmm2
+; SSE3-NEXT:    subpd %xmm3, %xmm2
 ; SSE3-NEXT:    psrlq $52, %xmm2
-; SSE3-NEXT:    movd %xmm0, %eax
-; SSE3-NEXT:    xorps %xmm1, %xmm1
-; SSE3-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE3-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,1,1]
-; SSE3-NEXT:    movd %xmm3, %eax
-; SSE3-NEXT:    xorps %xmm3, %xmm3
-; SSE3-NEXT:    cvtsi2sd %rax, %xmm3
-; SSE3-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm3[0]
-; SSE3-NEXT:    psrlq $52, %xmm1
-; SSE3-NEXT:    packssdw %xmm2, %xmm1
+; SSE3-NEXT:    movapd %xmm0, %xmm4
+; SSE3-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
+; SSE3-NEXT:    orpd %xmm3, %xmm4
+; SSE3-NEXT:    subpd %xmm3, %xmm4
+; SSE3-NEXT:    psrlq $52, %xmm4
+; SSE3-NEXT:    packssdw %xmm2, %xmm4
 ; SSE3-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
-; SSE3-NEXT:    psubd %xmm1, %xmm2
-; SSE3-NEXT:    pxor %xmm1, %xmm1
+; SSE3-NEXT:    psubd %xmm4, %xmm2
 ; SSE3-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE3-NEXT:    movdqa %xmm0, %xmm1
 ; SSE3-NEXT:    pandn %xmm2, %xmm1
@@ -801,54 +785,40 @@ define <4 x i32> @testv4i32(<4 x i32> %in) nounwind {
 define <4 x i32> @testv4i32u(<4 x i32> %in) nounwind {
 ; SSE2-LABEL: testv4i32u:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
-; SSE2-NEXT:    movd %xmm1, %eax
-; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE2-NEXT:    xorpd %xmm1, %xmm1
+; SSE2-NEXT:    movapd %xmm0, %xmm2
+; SSE2-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
+; SSE2-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    orpd %xmm3, %xmm2
+; SSE2-NEXT:    subpd %xmm3, %xmm2
 ; SSE2-NEXT:    psrlq $52, %xmm2
-; SSE2-NEXT:    movd %xmm0, %eax
-; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    movd %xmm0, %eax
-; SSE2-NEXT:    xorps %xmm0, %xmm0
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm0
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; SSE2-NEXT:    psrlq $52, %xmm1
-; SSE2-NEXT:    packssdw %xmm2, %xmm1
-; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [1054,1054,1054,1054]
-; SSE2-NEXT:    psubd %xmm1, %xmm0
+; SSE2-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
+; SSE2-NEXT:    orpd %xmm3, %xmm0
+; SSE2-NEXT:    subpd %xmm3, %xmm0
+; SSE2-NEXT:    psrlq $52, %xmm0
+; SSE2-NEXT:    packssdw %xmm2, %xmm0
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [1054,1054,1054,1054]
+; SSE2-NEXT:    psubd %xmm0, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE3-LABEL: testv4i32u:
 ; SSE3:       # %bb.0:
-; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
-; SSE3-NEXT:    movd %xmm1, %eax
-; SSE3-NEXT:    xorps %xmm1, %xmm1
-; SSE3-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
-; SSE3-NEXT:    movd %xmm2, %eax
-; SSE3-NEXT:    xorps %xmm2, %xmm2
-; SSE3-NEXT:    cvtsi2sd %rax, %xmm2
-; SSE3-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; SSE3-NEXT:    xorpd %xmm1, %xmm1
+; SSE3-NEXT:    movapd %xmm0, %xmm2
+; SSE3-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
+; SSE3-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE3-NEXT:    orpd %xmm3, %xmm2
+; SSE3-NEXT:    subpd %xmm3, %xmm2
 ; SSE3-NEXT:    psrlq $52, %xmm2
-; SSE3-NEXT:    movd %xmm0, %eax
-; SSE3-NEXT:    xorps %xmm1, %xmm1
-; SSE3-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE3-NEXT:    movd %xmm0, %eax
-; SSE3-NEXT:    xorps %xmm0, %xmm0
-; SSE3-NEXT:    cvtsi2sd %rax, %xmm0
-; SSE3-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; SSE3-NEXT:    psrlq $52, %xmm1
-; SSE3-NEXT:    packssdw %xmm2, %xmm1
-; SSE3-NEXT:    movdqa {{.*#+}} xmm0 = [1054,1054,1054,1054]
-; SSE3-NEXT:    psubd %xmm1, %xmm0
+; SSE3-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
+; SSE3-NEXT:    orpd %xmm3, %xmm0
+; SSE3-NEXT:    subpd %xmm3, %xmm0
+; SSE3-NEXT:    psrlq $52, %xmm0
+; SSE3-NEXT:    packssdw %xmm2, %xmm0
+; SSE3-NEXT:    movdqa {{.*#+}} xmm1 = [1054,1054,1054,1054]
+; SSE3-NEXT:    psubd %xmm0, %xmm1
+; SSE3-NEXT:    movdqa %xmm1, %xmm0
 ; SSE3-NEXT:    retq
 ;
 ; SSSE3-LABEL: testv4i32u:
diff --git a/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll b/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll
index f70f7e204c86a8..ad8a60cb95f077 100644
--- a/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll
+++ b/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll
@@ -6,28 +6,21 @@ declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1 immarg)
 define <2 x i32> @illegal_ctlz(<2 x i32> %v1) {
 ; CHECK-LABEL: illegal_ctlz:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
-; CHECK-NEXT:    movd %xmm1, %eax
-; CHECK-NEXT:    xorps %xmm1, %xmm1
-; CHECK-NEXT:    cvtsi2sd %rax, %xmm1
-; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
-; CHECK-NEXT:    movd %xmm2, %eax
-; CHECK-NEXT:    xorps %xmm2, %xmm2
-; CHECK-NEXT:    cvtsi2sd %rax, %xmm2
-; CHECK-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
+; CHECK-NEXT:    xorpd %xmm1, %xmm1
+; CHECK-NEXT:    movapd %xmm0, %xmm2
+; CHECK-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
+; CHECK-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
+; CHECK-NEXT:    orpd %xmm3, %xmm2
+; CHECK-NEXT:    subpd %xmm3, %xmm2
 ; CHECK-NEXT:    psrlq $52, %xmm2
-; CHECK-NEXT:    movd %xmm0, %eax
-; CHECK-NEXT:    xorps %xmm1, %xmm1
-; CHECK-NEXT:    cvtsi2sd %rax, %xmm1
-; CHECK-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; CHECK-NEXT:    movd %xmm0, %eax
-; CHECK-NEXT:    xorps %xmm0, %xmm0
-; CHECK-NEXT:    cvtsi2sd %rax, %xmm0
-; CHECK-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; CHECK-NEXT:    psrlq $52, %xmm1
-; CHECK-NEXT:    packssdw %xmm2, %xmm1
-; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [1054,1054,1054,1054]
-; CHECK-NEXT:    psubd %xmm1, %xmm0
+; CHECK-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
+; CHECK-NEXT:    orpd %xmm3, %xmm0
+; CHECK-NEXT:    subpd %xmm3, %xmm0
+; CHECK-NEXT:    psrlq $52, %xmm0
+; CHECK-NEXT:    packssdw %xmm2, %xmm0
+; CHECK-NEXT:    movdqa {{.*#+}} xmm1 = [1054,1054,1054,1054]
+; CHECK-NEXT:    psubd %xmm0, %xmm1
+; CHECK-NEXT:    movdqa %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %v2 = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %v1, i1 true)
   ret <2 x i32> %v2

>From ded9929fda1a72399c9e72d6beec6d21ab95a76b Mon Sep 17 00:00:00 2001
From: Ayaan Khan <ayaanandayaan2 at gmail.com>
Date: Thu, 30 Apr 2026 19:27:35 +0530
Subject: [PATCH 3/6] fix format

---
 llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index b29d02f79ff6cd..e8dabda17412d9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -11068,7 +11068,8 @@ SDValue TargetLowering::expandCTLZWithFP(SDNode *Node,
   EVT HalfFloatVT = HalfVT.changeVectorElementType(*DAG.getContext(), MVT::f64);
   EVT HalfFloatBitsVT = HalfFloatVT.changeVectorElementTypeToInteger();
 
-  const fltSemantics &Sem = HalfFloatVT.getVectorElementType().getFltSemantics();
+  const fltSemantics &Sem =
+      HalfFloatVT.getVectorElementType().getFltSemantics();
   unsigned BitWidth = EltVT.getSizeInBits();
   unsigned MantissaBits = APFloat::semanticsPrecision(Sem);
   unsigned ExponentBias = APFloat::semanticsMaxExponent(Sem);
@@ -11076,7 +11077,8 @@ SDValue TargetLowering::expandCTLZWithFP(SDNode *Node,
   auto ComputeExp = [&](SDValue Half) {
     SDValue Float = DAG.getNode(ISD::UINT_TO_FP, dl, HalfFloatVT, Half);
     SDValue Bits = DAG.getBitcast(HalfFloatBitsVT, Float);
-    SDValue Exp = DAG.getNode(ISD::SRL, dl, HalfFloatBitsVT, Bits,
+    SDValue Exp = DAG.getNode(
+        ISD::SRL, dl, HalfFloatBitsVT, Bits,
         DAG.getShiftAmountConstant(MantissaBits - 1, HalfFloatBitsVT, dl));
     return DAG.getNode(ISD::TRUNCATE, dl, HalfVT, Exp);
   };
@@ -11084,9 +11086,11 @@ SDValue TargetLowering::expandCTLZWithFP(SDNode *Node,
   SDValue ExpTruncLo = ComputeExp(DAG.getExtractSubvector(dl, HalfVT, Op, 0));
   SDValue ExpTruncHi = ComputeExp(
       DAG.getExtractSubvector(dl, HalfVT, Op, VT.getVectorNumElements() / 2));
-  SDValue Exp = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, ExpTruncLo, ExpTruncHi);
-  SDValue NonZeroRes = DAG.getNode(ISD::SUB, dl, VT,
-      DAG.getConstant(BitWidth - 1 + ExponentBias, dl, VT), Exp);
+  SDValue Exp =
+      DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, ExpTruncLo, ExpTruncHi);
+  SDValue NonZeroRes =
+      DAG.getNode(ISD::SUB, dl, VT,
+                  DAG.getConstant(BitWidth - 1 + ExponentBias, dl, VT), Exp);
 
   // Skip Op == 0 case for CTLZ_ZERO_UNDEF
   if (Node->getOpcode() == ISD::CTLZ_ZERO_UNDEF)

>From 507ae93a25369768bed85b41716a329d73678616 Mon Sep 17 00:00:00 2001
From: Ayaan Khan <ayaanandayaan2 at gmail.com>
Date: Tue, 19 May 2026 20:48:32 +0530
Subject: [PATCH 4/6] new impl

---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |  61 ++++------
 llvm/lib/Target/X86/X86ISelLowering.cpp       |   2 +-
 llvm/test/CodeGen/X86/combine-srl.ll          |  30 ++---
 .../CodeGen/X86/expand-vp-int-intrinsics.ll   |  29 ++---
 llvm/test/CodeGen/X86/vec_ctbits.ll           |  31 ++---
 llvm/test/CodeGen/X86/vector-lzcnt-128.ll     | 110 +++++++-----------
 llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll  |  26 ++---
 7 files changed, 107 insertions(+), 182 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index e8dabda17412d9..8e369f5d5c05d5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -11050,11 +11050,12 @@ SDValue TargetLowering::expandCTLZ(SDNode *Node, SelectionDAG &DAG) const {
 SDValue TargetLowering::expandCTLZWithFP(SDNode *Node,
                                          SelectionDAG &DAG) const {
   // pseudocode :
-  // if (x == 0) return 32;
-  // f64 f = (f64)x;
-  // u64 i = bitcast<u64>(f);
-  // u32 ilog2 = (u32)(i >> 52) - 1023;
-  // return 31 - ilog2;
+  // v = v & ~(v >> 8)
+  // v = (f32)v
+  // v = bitcast<i32>(v)
+  // v = v >> 23
+  // v = 158 - v
+  // v = min(v, 32)
 
   SDLoc dl(Node);
   EVT VT = Node->getValueType(0);
@@ -11064,45 +11065,29 @@ SDValue TargetLowering::expandCTLZWithFP(SDNode *Node,
   if (EltVT != MVT::i32)
     return SDValue();
 
-  EVT HalfVT = VT.getHalfNumVectorElementsVT(*DAG.getContext());
-  EVT HalfFloatVT = HalfVT.changeVectorElementType(*DAG.getContext(), MVT::f64);
-  EVT HalfFloatBitsVT = HalfFloatVT.changeVectorElementTypeToInteger();
-
-  const fltSemantics &Sem =
-      HalfFloatVT.getVectorElementType().getFltSemantics();
+  EVT FloatVT = VT.changeVectorElementType(*DAG.getContext(), MVT::f32);
+  const fltSemantics &Sem = FloatVT.getVectorElementType().getFltSemantics();
   unsigned BitWidth = EltVT.getSizeInBits();
   unsigned MantissaBits = APFloat::semanticsPrecision(Sem);
   unsigned ExponentBias = APFloat::semanticsMaxExponent(Sem);
 
-  auto ComputeExp = [&](SDValue Half) {
-    SDValue Float = DAG.getNode(ISD::UINT_TO_FP, dl, HalfFloatVT, Half);
-    SDValue Bits = DAG.getBitcast(HalfFloatBitsVT, Float);
-    SDValue Exp = DAG.getNode(
-        ISD::SRL, dl, HalfFloatBitsVT, Bits,
-        DAG.getShiftAmountConstant(MantissaBits - 1, HalfFloatBitsVT, dl));
-    return DAG.getNode(ISD::TRUNCATE, dl, HalfVT, Exp);
-  };
+  // v = v & ~(v >> 8)
+  SDValue ShiftOp =
+      DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getShiftAmountConstant(8, VT, dl));
+  SDValue Tmp = DAG.getNode(ISD::AND, dl, VT, Op, DAG.getNOT(dl, ShiftOp, VT));
 
-  SDValue ExpTruncLo = ComputeExp(DAG.getExtractSubvector(dl, HalfVT, Op, 0));
-  SDValue ExpTruncHi = ComputeExp(
-      DAG.getExtractSubvector(dl, HalfVT, Op, VT.getVectorNumElements() / 2));
-  SDValue Exp =
-      DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, ExpTruncLo, ExpTruncHi);
-  SDValue NonZeroRes =
-      DAG.getNode(ISD::SUB, dl, VT,
-                  DAG.getConstant(BitWidth - 1 + ExponentBias, dl, VT), Exp);
-
-  // Skip Op == 0 case for CTLZ_ZERO_UNDEF
-  if (Node->getOpcode() == ISD::CTLZ_ZERO_UNDEF)
-    return NonZeroRes;
-
-  // This Handles the Op == 0 case
-  EVT CmpVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
-  SDValue Zero = DAG.getConstant(0, dl, VT);
-  SDValue IsZero = DAG.getSetCC(dl, CmpVT, Op, Zero, ISD::SETEQ);
+  SDValue Float = DAG.getNode(ISD::SINT_TO_FP, dl, FloatVT, Tmp);
+  SDValue Int = DAG.getNode(ISD::BITCAST, dl, VT, Float);
+
+  SDValue ShiftExp =
+      DAG.getNode(ISD::SRL, dl, VT, Int,
+                  DAG.getShiftAmountConstant(MantissaBits - 1, VT, dl));
+  SDValue UndoBias = DAG.getNode(
+      ISD::USUBSAT, dl, VT,
+      DAG.getConstant(BitWidth - 1 + ExponentBias, dl, VT), ShiftExp);
 
-  return DAG.getNode(ISD::VSELECT, dl, VT, IsZero,
-                     DAG.getConstant(BitWidth, dl, VT), NonZeroRes);
+  return DAG.getNode(ISD::SMIN, dl, VT, UndoBias,
+                     DAG.getConstant(BitWidth, dl, VT));
 }
 
 SDValue TargetLowering::expandCTLS(SDNode *Node, SelectionDAG &DAG) const {
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 9bb76b3f25a7ec..cc28c34951fd87 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -1344,7 +1344,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
 
     if (!Subtarget.hasSSSE3()) {
       setOperationAction(ISD::CTLZ, MVT::v4i32, Custom);
-      setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::v4i32, Custom);
+      setOperationAction(ISD::CTLZ_ZERO_POISON, MVT::v4i32, Custom);
     }
   }
 
diff --git a/llvm/test/CodeGen/X86/combine-srl.ll b/llvm/test/CodeGen/X86/combine-srl.ll
index ec560050828618..e3763a676bd6f5 100644
--- a/llvm/test/CodeGen/X86/combine-srl.ll
+++ b/llvm/test/CodeGen/X86/combine-srl.ll
@@ -425,27 +425,15 @@ define <4 x i32> @combine_vec_lshr_lzcnt_bit0(<4 x i32> %x) {
 define <4 x i32> @combine_vec_lshr_lzcnt_bit1(<4 x i32> %x) {
 ; SSE2-LABEL: combine_vec_lshr_lzcnt_bit1:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    andpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    xorpd %xmm1, %xmm1
-; SSE2-NEXT:    movapd %xmm0, %xmm2
-; SSE2-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE2-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
-; SSE2-NEXT:    orpd %xmm3, %xmm2
-; SSE2-NEXT:    subpd %xmm3, %xmm2
-; SSE2-NEXT:    psrlq $52, %xmm2
-; SSE2-NEXT:    movapd %xmm0, %xmm4
-; SSE2-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; SSE2-NEXT:    orpd %xmm3, %xmm4
-; SSE2-NEXT:    subpd %xmm3, %xmm4
-; SSE2-NEXT:    psrlq $52, %xmm4
-; SSE2-NEXT:    packssdw %xmm2, %xmm4
-; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
-; SSE2-NEXT:    psubd %xmm4, %xmm2
-; SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
-; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    pandn %xmm2, %xmm1
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    por %xmm1, %xmm0
+; SSE2-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    cvtdq2ps %xmm0, %xmm1
+; SSE2-NEXT:    psrld $23, %xmm1
+; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [158,158,158,158]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    psubd %xmm1, %xmm2
+; SSE2-NEXT:    pcmpgtd %xmm1, %xmm0
+; SSE2-NEXT:    pand %xmm2, %xmm0
+; SSE2-NEXT:    pminsw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; SSE2-NEXT:    psrld $5, %xmm0
 ; SSE2-NEXT:    retq
 ;
diff --git a/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll b/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll
index 5070b20095108c..9ae17ff50ab5c3 100644
--- a/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/expand-vp-int-intrinsics.ll
@@ -1282,26 +1282,17 @@ define <4 x i32> @vp_ctlz_v4i32(<4 x i32> %va, <4 x i1> %m, i32 zeroext %evl) {
 ;
 ; SSE-LABEL: vp_ctlz_v4i32:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    xorpd %xmm1, %xmm1
-; SSE-NEXT:    movapd %xmm0, %xmm2
-; SSE-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
-; SSE-NEXT:    orpd %xmm3, %xmm2
-; SSE-NEXT:    subpd %xmm3, %xmm2
-; SSE-NEXT:    psrlq $52, %xmm2
-; SSE-NEXT:    movapd %xmm0, %xmm4
-; SSE-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; SSE-NEXT:    orpd %xmm3, %xmm4
-; SSE-NEXT:    subpd %xmm3, %xmm4
-; SSE-NEXT:    psrlq $52, %xmm4
-; SSE-NEXT:    packssdw %xmm2, %xmm4
-; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
-; SSE-NEXT:    psubd %xmm4, %xmm2
-; SSE-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE-NEXT:    movdqa %xmm0, %xmm1
-; SSE-NEXT:    pandn %xmm2, %xmm1
-; SSE-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    por %xmm1, %xmm0
+; SSE-NEXT:    psrld $8, %xmm1
+; SSE-NEXT:    pandn %xmm0, %xmm1
+; SSE-NEXT:    cvtdq2ps %xmm1, %xmm1
+; SSE-NEXT:    psrld $23, %xmm1
+; SSE-NEXT:    movdqa {{.*#+}} xmm0 = [158,158,158,158]
+; SSE-NEXT:    movdqa %xmm0, %xmm2
+; SSE-NEXT:    psubd %xmm1, %xmm2
+; SSE-NEXT:    pcmpgtd %xmm1, %xmm0
+; SSE-NEXT:    pand %xmm2, %xmm0
+; SSE-NEXT:    pminsw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; SSE-NEXT:    retq
 ;
 ; AVX1-LABEL: vp_ctlz_v4i32:
diff --git a/llvm/test/CodeGen/X86/vec_ctbits.ll b/llvm/test/CodeGen/X86/vec_ctbits.ll
index 22c2577ff1b6b7..e4bd81d14c059a 100644
--- a/llvm/test/CodeGen/X86/vec_ctbits.ll
+++ b/llvm/test/CodeGen/X86/vec_ctbits.ll
@@ -140,26 +140,17 @@ define <2 x i32> @promtz(<2 x i32> %a) nounwind {
 define <2 x i32> @promlz(<2 x i32> %a) nounwind {
 ; CHECK-LABEL: promlz:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    movapd %xmm0, %xmm2
-; CHECK-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; CHECK-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
-; CHECK-NEXT:    orpd %xmm3, %xmm2
-; CHECK-NEXT:    subpd %xmm3, %xmm2
-; CHECK-NEXT:    psrlq $52, %xmm2
-; CHECK-NEXT:    movapd %xmm0, %xmm4
-; CHECK-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; CHECK-NEXT:    orpd %xmm3, %xmm4
-; CHECK-NEXT:    subpd %xmm3, %xmm4
-; CHECK-NEXT:    psrlq $52, %xmm4
-; CHECK-NEXT:    packssdw %xmm2, %xmm4
-; CHECK-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
-; CHECK-NEXT:    psubd %xmm4, %xmm2
-; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    pandn %xmm2, %xmm1
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; CHECK-NEXT:    por %xmm1, %xmm0
+; CHECK-NEXT:    movdqa %xmm0, %xmm1
+; CHECK-NEXT:    psrld $8, %xmm1
+; CHECK-NEXT:    pandn %xmm0, %xmm1
+; CHECK-NEXT:    cvtdq2ps %xmm1, %xmm1
+; CHECK-NEXT:    psrld $23, %xmm1
+; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [158,158,158,158]
+; CHECK-NEXT:    movdqa %xmm0, %xmm2
+; CHECK-NEXT:    psubd %xmm1, %xmm2
+; CHECK-NEXT:    pcmpgtd %xmm1, %xmm0
+; CHECK-NEXT:    pand %xmm2, %xmm0
+; CHECK-NEXT:    pminsw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    retq
   %c = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %a, i1 false)
   ret <2 x i32> %c
diff --git a/llvm/test/CodeGen/X86/vector-lzcnt-128.ll b/llvm/test/CodeGen/X86/vector-lzcnt-128.ll
index 13b7bee8474e1a..f34d6da0bdb212 100644
--- a/llvm/test/CodeGen/X86/vector-lzcnt-128.ll
+++ b/llvm/test/CodeGen/X86/vector-lzcnt-128.ll
@@ -572,50 +572,32 @@ define <2 x i64> @testv2i64u(<2 x i64> %in) nounwind {
 define <4 x i32> @testv4i32(<4 x i32> %in) nounwind {
 ; SSE2-LABEL: testv4i32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    xorpd %xmm1, %xmm1
-; SSE2-NEXT:    movapd %xmm0, %xmm2
-; SSE2-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE2-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
-; SSE2-NEXT:    orpd %xmm3, %xmm2
-; SSE2-NEXT:    subpd %xmm3, %xmm2
-; SSE2-NEXT:    psrlq $52, %xmm2
-; SSE2-NEXT:    movapd %xmm0, %xmm4
-; SSE2-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; SSE2-NEXT:    orpd %xmm3, %xmm4
-; SSE2-NEXT:    subpd %xmm3, %xmm4
-; SSE2-NEXT:    psrlq $52, %xmm4
-; SSE2-NEXT:    packssdw %xmm2, %xmm4
-; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
-; SSE2-NEXT:    psubd %xmm4, %xmm2
-; SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
-; SSE2-NEXT:    pandn %xmm2, %xmm1
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    por %xmm1, %xmm0
+; SSE2-NEXT:    psrld $8, %xmm1
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    cvtdq2ps %xmm1, %xmm1
+; SSE2-NEXT:    psrld $23, %xmm1
+; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [158,158,158,158]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    psubd %xmm1, %xmm2
+; SSE2-NEXT:    pcmpgtd %xmm1, %xmm0
+; SSE2-NEXT:    pand %xmm2, %xmm0
+; SSE2-NEXT:    pminsw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE3-LABEL: testv4i32:
 ; SSE3:       # %bb.0:
-; SSE3-NEXT:    xorpd %xmm1, %xmm1
-; SSE3-NEXT:    movapd %xmm0, %xmm2
-; SSE3-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE3-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
-; SSE3-NEXT:    orpd %xmm3, %xmm2
-; SSE3-NEXT:    subpd %xmm3, %xmm2
-; SSE3-NEXT:    psrlq $52, %xmm2
-; SSE3-NEXT:    movapd %xmm0, %xmm4
-; SSE3-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; SSE3-NEXT:    orpd %xmm3, %xmm4
-; SSE3-NEXT:    subpd %xmm3, %xmm4
-; SSE3-NEXT:    psrlq $52, %xmm4
-; SSE3-NEXT:    packssdw %xmm2, %xmm4
-; SSE3-NEXT:    movdqa {{.*#+}} xmm2 = [1054,1054,1054,1054]
-; SSE3-NEXT:    psubd %xmm4, %xmm2
-; SSE3-NEXT:    pcmpeqd %xmm1, %xmm0
 ; SSE3-NEXT:    movdqa %xmm0, %xmm1
-; SSE3-NEXT:    pandn %xmm2, %xmm1
-; SSE3-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE3-NEXT:    por %xmm1, %xmm0
+; SSE3-NEXT:    psrld $8, %xmm1
+; SSE3-NEXT:    pandn %xmm0, %xmm1
+; SSE3-NEXT:    cvtdq2ps %xmm1, %xmm1
+; SSE3-NEXT:    psrld $23, %xmm1
+; SSE3-NEXT:    movdqa {{.*#+}} xmm0 = [158,158,158,158]
+; SSE3-NEXT:    movdqa %xmm0, %xmm2
+; SSE3-NEXT:    psubd %xmm1, %xmm2
+; SSE3-NEXT:    pcmpgtd %xmm1, %xmm0
+; SSE3-NEXT:    pand %xmm2, %xmm0
+; SSE3-NEXT:    pminsw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; SSE3-NEXT:    retq
 ;
 ; SSSE3-LABEL: testv4i32:
@@ -785,40 +767,32 @@ define <4 x i32> @testv4i32(<4 x i32> %in) nounwind {
 define <4 x i32> @testv4i32u(<4 x i32> %in) nounwind {
 ; SSE2-LABEL: testv4i32u:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    xorpd %xmm1, %xmm1
-; SSE2-NEXT:    movapd %xmm0, %xmm2
-; SSE2-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE2-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
-; SSE2-NEXT:    orpd %xmm3, %xmm2
-; SSE2-NEXT:    subpd %xmm3, %xmm2
-; SSE2-NEXT:    psrlq $52, %xmm2
-; SSE2-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE2-NEXT:    orpd %xmm3, %xmm0
-; SSE2-NEXT:    subpd %xmm3, %xmm0
-; SSE2-NEXT:    psrlq $52, %xmm0
-; SSE2-NEXT:    packssdw %xmm2, %xmm0
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [1054,1054,1054,1054]
-; SSE2-NEXT:    psubd %xmm0, %xmm1
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:    movdqa %xmm0, %xmm1
+; SSE2-NEXT:    psrld $8, %xmm1
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    cvtdq2ps %xmm1, %xmm1
+; SSE2-NEXT:    psrld $23, %xmm1
+; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [158,158,158,158]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    psubd %xmm1, %xmm2
+; SSE2-NEXT:    pcmpgtd %xmm1, %xmm0
+; SSE2-NEXT:    pand %xmm2, %xmm0
+; SSE2-NEXT:    pminsw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE3-LABEL: testv4i32u:
 ; SSE3:       # %bb.0:
-; SSE3-NEXT:    xorpd %xmm1, %xmm1
-; SSE3-NEXT:    movapd %xmm0, %xmm2
-; SSE3-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; SSE3-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
-; SSE3-NEXT:    orpd %xmm3, %xmm2
-; SSE3-NEXT:    subpd %xmm3, %xmm2
-; SSE3-NEXT:    psrlq $52, %xmm2
-; SSE3-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE3-NEXT:    orpd %xmm3, %xmm0
-; SSE3-NEXT:    subpd %xmm3, %xmm0
-; SSE3-NEXT:    psrlq $52, %xmm0
-; SSE3-NEXT:    packssdw %xmm2, %xmm0
-; SSE3-NEXT:    movdqa {{.*#+}} xmm1 = [1054,1054,1054,1054]
-; SSE3-NEXT:    psubd %xmm0, %xmm1
-; SSE3-NEXT:    movdqa %xmm1, %xmm0
+; SSE3-NEXT:    movdqa %xmm0, %xmm1
+; SSE3-NEXT:    psrld $8, %xmm1
+; SSE3-NEXT:    pandn %xmm0, %xmm1
+; SSE3-NEXT:    cvtdq2ps %xmm1, %xmm1
+; SSE3-NEXT:    psrld $23, %xmm1
+; SSE3-NEXT:    movdqa {{.*#+}} xmm0 = [158,158,158,158]
+; SSE3-NEXT:    movdqa %xmm0, %xmm2
+; SSE3-NEXT:    psubd %xmm1, %xmm2
+; SSE3-NEXT:    pcmpgtd %xmm1, %xmm0
+; SSE3-NEXT:    pand %xmm2, %xmm0
+; SSE3-NEXT:    pminsw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; SSE3-NEXT:    retq
 ;
 ; SSSE3-LABEL: testv4i32u:
diff --git a/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll b/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll
index ad8a60cb95f077..473d8e82944826 100644
--- a/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll
+++ b/llvm/test/CodeGen/X86/vector-lzcnt-sub128.ll
@@ -6,21 +6,17 @@ declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1 immarg)
 define <2 x i32> @illegal_ctlz(<2 x i32> %v1) {
 ; CHECK-LABEL: illegal_ctlz:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    xorpd %xmm1, %xmm1
-; CHECK-NEXT:    movapd %xmm0, %xmm2
-; CHECK-NEXT:    unpckhps {{.*#+}} xmm2 = xmm2[2],xmm1[2],xmm2[3],xmm1[3]
-; CHECK-NEXT:    movapd {{.*#+}} xmm3 = [4.503599627370496E+15,4.503599627370496E+15]
-; CHECK-NEXT:    orpd %xmm3, %xmm2
-; CHECK-NEXT:    subpd %xmm3, %xmm2
-; CHECK-NEXT:    psrlq $52, %xmm2
-; CHECK-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; CHECK-NEXT:    orpd %xmm3, %xmm0
-; CHECK-NEXT:    subpd %xmm3, %xmm0
-; CHECK-NEXT:    psrlq $52, %xmm0
-; CHECK-NEXT:    packssdw %xmm2, %xmm0
-; CHECK-NEXT:    movdqa {{.*#+}} xmm1 = [1054,1054,1054,1054]
-; CHECK-NEXT:    psubd %xmm0, %xmm1
-; CHECK-NEXT:    movdqa %xmm1, %xmm0
+; CHECK-NEXT:    movdqa %xmm0, %xmm1
+; CHECK-NEXT:    psrld $8, %xmm1
+; CHECK-NEXT:    pandn %xmm0, %xmm1
+; CHECK-NEXT:    cvtdq2ps %xmm1, %xmm1
+; CHECK-NEXT:    psrld $23, %xmm1
+; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [158,158,158,158]
+; CHECK-NEXT:    movdqa %xmm0, %xmm2
+; CHECK-NEXT:    psubd %xmm1, %xmm2
+; CHECK-NEXT:    pcmpgtd %xmm1, %xmm0
+; CHECK-NEXT:    pand %xmm2, %xmm0
+; CHECK-NEXT:    pminsw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
 ; CHECK-NEXT:    retq
   %v2 = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %v1, i1 true)
   ret <2 x i32> %v2

>From cc3938d9d186d26a0808bf5f968855e127b93499 Mon Sep 17 00:00:00 2001
From: Ayaan Khan <ayaanandayaan2 at gmail.com>
Date: Thu, 25 Jun 2026 23:52:52 +0530
Subject: [PATCH 5/6] update test

---
 .../test/CodeGen/X86/arbitrary-fp-to-float.ll | 99 +++++++++----------
 1 file changed, 44 insertions(+), 55 deletions(-)

diff --git a/llvm/test/CodeGen/X86/arbitrary-fp-to-float.ll b/llvm/test/CodeGen/X86/arbitrary-fp-to-float.ll
index 73468b07496232..179b6212cfe4a9 100644
--- a/llvm/test/CodeGen/X86/arbitrary-fp-to-float.ll
+++ b/llvm/test/CodeGen/X86/arbitrary-fp-to-float.ll
@@ -571,75 +571,64 @@ define bfloat @from_f8e5m2_to_bf16() {
 define <4 x float> @fp4_to_f32_vec(<4 x i4> %x) {
 ; CHECK-LABEL: fp4_to_f32_vec:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movdqa %xmm0, %xmm1
-; CHECK-NEXT:    movdqa {{.*#+}} xmm2 = [1,1,1,1]
-; CHECK-NEXT:    pand %xmm2, %xmm0
-; CHECK-NEXT:    pcmpeqd %xmm3, %xmm3
-; CHECK-NEXT:    pxor %xmm0, %xmm3
-; CHECK-NEXT:    psubb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3
-; CHECK-NEXT:    movdqa {{.*#+}} xmm4 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
-; CHECK-NEXT:    movdqa %xmm3, %xmm5
-; CHECK-NEXT:    pand %xmm4, %xmm5
-; CHECK-NEXT:    psrlw $2, %xmm3
-; CHECK-NEXT:    pand %xmm4, %xmm3
-; CHECK-NEXT:    paddb %xmm5, %xmm3
-; CHECK-NEXT:    movdqa %xmm3, %xmm5
-; CHECK-NEXT:    psrlw $4, %xmm5
-; CHECK-NEXT:    paddb %xmm3, %xmm5
-; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm5
-; CHECK-NEXT:    pxor %xmm3, %xmm3
-; CHECK-NEXT:    movdqa %xmm5, %xmm4
-; CHECK-NEXT:    punpckhdq {{.*#+}} xmm4 = xmm4[2],xmm3[2],xmm4[3],xmm3[3]
-; CHECK-NEXT:    psadbw %xmm3, %xmm4
-; CHECK-NEXT:    punpckldq {{.*#+}} xmm5 = xmm5[0],xmm3[0],xmm5[1],xmm3[1]
-; CHECK-NEXT:    psadbw %xmm3, %xmm5
-; CHECK-NEXT:    packuswb %xmm4, %xmm5
-; CHECK-NEXT:    movdqa {{.*#+}} xmm4 = [31,31,31,31]
-; CHECK-NEXT:    psubd %xmm5, %xmm4
+; CHECK-NEXT:    movaps %xmm0, %xmm1
+; CHECK-NEXT:    movaps {{.*#+}} xmm2 = [1,1,1,1]
+; CHECK-NEXT:    andps %xmm2, %xmm0
+; CHECK-NEXT:    cvtdq2ps %xmm0, %xmm3
+; CHECK-NEXT:    psrld $23, %xmm3
+; CHECK-NEXT:    movdqa {{.*#+}} xmm4 = [158,158,158,158]
+; CHECK-NEXT:    movdqa %xmm4, %xmm5
+; CHECK-NEXT:    psubd %xmm3, %xmm5
+; CHECK-NEXT:    pcmpgtd %xmm3, %xmm4
+; CHECK-NEXT:    pand %xmm5, %xmm4
+; CHECK-NEXT:    pminsw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm4
+; CHECK-NEXT:    movdqa {{.*#+}} xmm3 = [31,31,31,31]
+; CHECK-NEXT:    psubd %xmm4, %xmm3
+; CHECK-NEXT:    pslld $23, %xmm3
+; CHECK-NEXT:    movdqa {{.*#+}} xmm5 = [1065353216,1065353216,1065353216,1065353216]
+; CHECK-NEXT:    paddd %xmm5, %xmm3
+; CHECK-NEXT:    cvttps2dq %xmm3, %xmm6
+; CHECK-NEXT:    xorps %xmm0, %xmm6
+; CHECK-NEXT:    movdqa {{.*#+}} xmm3 = [157,157,157,157]
+; CHECK-NEXT:    psubd %xmm4, %xmm3
+; CHECK-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm4
 ; CHECK-NEXT:    pslld $23, %xmm4
-; CHECK-NEXT:    movdqa {{.*#+}} xmm6 = [1065353216,1065353216,1065353216,1065353216]
-; CHECK-NEXT:    paddd %xmm6, %xmm4
-; CHECK-NEXT:    cvttps2dq %xmm4, %xmm7
-; CHECK-NEXT:    pxor %xmm0, %xmm7
-; CHECK-NEXT:    movdqa {{.*#+}} xmm4 = [157,157,157,157]
-; CHECK-NEXT:    psubd %xmm5, %xmm4
-; CHECK-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm5
-; CHECK-NEXT:    pslld $23, %xmm5
-; CHECK-NEXT:    paddd %xmm6, %xmm5
-; CHECK-NEXT:    cvttps2dq %xmm5, %xmm5
-; CHECK-NEXT:    pshufd {{.*#+}} xmm6 = xmm7[1,1,3,3]
-; CHECK-NEXT:    pmuludq %xmm5, %xmm7
-; CHECK-NEXT:    pshufd {{.*#+}} xmm7 = xmm7[0,2,2,3]
-; CHECK-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3]
-; CHECK-NEXT:    pmuludq %xmm6, %xmm5
-; CHECK-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[0,2,2,3]
-; CHECK-NEXT:    punpckldq {{.*#+}} xmm7 = xmm7[0],xmm5[0],xmm7[1],xmm5[1]
-; CHECK-NEXT:    pslld $23, %xmm4
-; CHECK-NEXT:    movdqa %xmm1, %xmm5
-; CHECK-NEXT:    psrld $3, %xmm5
-; CHECK-NEXT:    pslld $31, %xmm5
-; CHECK-NEXT:    por %xmm5, %xmm4
-; CHECK-NEXT:    por %xmm7, %xmm4
+; CHECK-NEXT:    paddd %xmm5, %xmm4
+; CHECK-NEXT:    cvttps2dq %xmm4, %xmm4
+; CHECK-NEXT:    pshufd {{.*#+}} xmm5 = xmm6[1,1,3,3]
+; CHECK-NEXT:    pmuludq %xmm4, %xmm6
+; CHECK-NEXT:    pshufd {{.*#+}} xmm6 = xmm6[0,2,2,3]
+; CHECK-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
+; CHECK-NEXT:    pmuludq %xmm5, %xmm4
+; CHECK-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
+; CHECK-NEXT:    punpckldq {{.*#+}} xmm6 = xmm6[0],xmm4[0],xmm6[1],xmm4[1]
+; CHECK-NEXT:    pslld $23, %xmm3
+; CHECK-NEXT:    movaps %xmm1, %xmm4
+; CHECK-NEXT:    psrld $3, %xmm4
+; CHECK-NEXT:    pslld $31, %xmm4
+; CHECK-NEXT:    por %xmm4, %xmm3
+; CHECK-NEXT:    por %xmm6, %xmm3
 ; CHECK-NEXT:    pcmpeqd %xmm0, %xmm2
 ; CHECK-NEXT:    psrld $1, %xmm1
 ; CHECK-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; CHECK-NEXT:    pxor %xmm5, %xmm5
 ; CHECK-NEXT:    movdqa %xmm1, %xmm6
-; CHECK-NEXT:    pcmpeqd %xmm3, %xmm6
+; CHECK-NEXT:    pcmpeqd %xmm5, %xmm6
 ; CHECK-NEXT:    pand %xmm6, %xmm2
-; CHECK-NEXT:    pand %xmm2, %xmm4
+; CHECK-NEXT:    pand %xmm2, %xmm3
 ; CHECK-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 # [126,126,126,126]
 ; CHECK-NEXT:    pslld $23, %xmm1
 ; CHECK-NEXT:    movdqa %xmm0, %xmm7
 ; CHECK-NEXT:    pslld $22, %xmm7
-; CHECK-NEXT:    por %xmm5, %xmm7
+; CHECK-NEXT:    por %xmm4, %xmm7
 ; CHECK-NEXT:    por %xmm1, %xmm7
 ; CHECK-NEXT:    pandn %xmm7, %xmm2
-; CHECK-NEXT:    por %xmm4, %xmm2
-; CHECK-NEXT:    pcmpeqd %xmm3, %xmm0
+; CHECK-NEXT:    por %xmm3, %xmm2
+; CHECK-NEXT:    pcmpeqd %xmm5, %xmm0
 ; CHECK-NEXT:    pand %xmm6, %xmm0
-; CHECK-NEXT:    pand %xmm0, %xmm5
+; CHECK-NEXT:    pand %xmm0, %xmm4
 ; CHECK-NEXT:    pandn %xmm2, %xmm0
-; CHECK-NEXT:    por %xmm5, %xmm0
+; CHECK-NEXT:    por %xmm4, %xmm0
 ; CHECK-NEXT:    retq
   %r = call <4 x float> @llvm.convert.from.arbitrary.fp.v4f32.v4i4(<4 x i4> %x, metadata !"Float4E2M1FN")
   ret <4 x float> %r

>From 381fb3356a0aa0d448b9040731faf3719004fe2d Mon Sep 17 00:00:00 2001
From: Ayaan Khan <ayaanandayaan2 at gmail.com>
Date: Fri, 26 Jun 2026 18:14:58 +0530
Subject: [PATCH 6/6] apply suggestions

---
 llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 8e369f5d5c05d5..5de923c10c9331 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -11061,13 +11061,13 @@ SDValue TargetLowering::expandCTLZWithFP(SDNode *Node,
   EVT VT = Node->getValueType(0);
   SDValue Op = Node->getOperand(0);
 
-  EVT EltVT = VT.getVectorElementType();
-  if (EltVT != MVT::i32)
+  EVT SVT = VT.getScalarType();
+  if (SVT != MVT::i32)
     return SDValue();
 
   EVT FloatVT = VT.changeVectorElementType(*DAG.getContext(), MVT::f32);
   const fltSemantics &Sem = FloatVT.getVectorElementType().getFltSemantics();
-  unsigned BitWidth = EltVT.getSizeInBits();
+  unsigned BitWidth = SVT.getSizeInBits();
   unsigned MantissaBits = APFloat::semanticsPrecision(Sem);
   unsigned ExponentBias = APFloat::semanticsMaxExponent(Sem);
 
@@ -11077,7 +11077,7 @@ SDValue TargetLowering::expandCTLZWithFP(SDNode *Node,
   SDValue Tmp = DAG.getNode(ISD::AND, dl, VT, Op, DAG.getNOT(dl, ShiftOp, VT));
 
   SDValue Float = DAG.getNode(ISD::SINT_TO_FP, dl, FloatVT, Tmp);
-  SDValue Int = DAG.getNode(ISD::BITCAST, dl, VT, Float);
+  SDValue Int = DAG.getBitcast(VT, Float);
 
   SDValue ShiftExp =
       DAG.getNode(ISD::SRL, dl, VT, Int,



More information about the llvm-commits mailing list