[llvm-branch-commits] [llvm] [X86] Combine mask_beforefirst to (x - 1) & ~x in GPR (PR #232262)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Oct 15 03:29:30 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Luke Lau (lukel97)

<details>
<summary>Changes</summary>

glibc and libc use this pattern in strcpy etc. to set the bits before the lowest set bit. It works correctly for x=0 too, returning an all ones mask.

Because SSE/AVX/AVX2 promote vNi1 types, do this as a DAG combine before type legalization.

We need to restrict it to power of 2 types otherwise we hit a latent crash in combineToExtendBoolVectorInReg.

---

Patch is 21.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/232262.diff


2 Files Affected:

- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+23) 
- (modified) llvm/test/CodeGen/X86/mask-beforefirst.ll (+126-212) 


``````````diff
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index ad44c3c55dc89..9a78ab459326b 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2805,6 +2805,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
                        ISD::INSERT_SUBVECTOR,
                        ISD::EXTRACT_SUBVECTOR,
                        ISD::BITCAST,
+                       ISD::MASK_BEFOREFIRST,
                        ISD::VSELECT,
                        ISD::SELECT,
                        ISD::SHL,
@@ -47180,6 +47181,26 @@ static SDValue combineBitcastToBoolVector(EVT VT, SDValue V, const SDLoc &DL,
   return SDValue();
 }
 
+/// Compute MASK_BEFOREFIRST as (x - 1) & ~x in a GPR.
+static SDValue combineMaskBeforeFirst(SDNode *N, SelectionDAG &DAG,
+                                      TargetLowering::DAGCombinerInfo &DCI) {
+  EVT VT = N->getValueType(0);
+  if (!DCI.isBeforeLegalize() || !isPowerOf2_32(VT.getVectorNumElements()))
+    return SDValue();
+  assert(VT.getVectorElementType() == MVT::i1 && "Expected a mask vector");
+
+  SDLoc DL(N);
+  EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
+  // Do the arithmetic in at least 32 bits so that ANDN can be used.
+  EVT OpVT = IntVT.getSizeInBits() < 32 ? MVT::i32 : IntVT;
+  SDValue X =
+      DAG.getAnyExtOrTrunc(DAG.getBitcast(IntVT, N->getOperand(0)), DL, OpVT);
+  SDValue Dec =
+      DAG.getNode(ISD::SUB, DL, OpVT, X, DAG.getConstant(1, DL, OpVT));
+  SDValue Res = DAG.getNode(ISD::AND, DL, OpVT, DAG.getNOT(DL, X, OpVT), Dec);
+  return DAG.getBitcast(VT, DAG.getAnyExtOrTrunc(Res, DL, IntVT));
+}
+
 static SDValue combineBitcast(SDNode *N, SelectionDAG &DAG,
                               TargetLowering::DAGCombinerInfo &DCI,
                               const X86Subtarget &Subtarget) {
@@ -64116,6 +64137,8 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
   case ISD::SELECT:
   case X86ISD::BLENDV:      return combineSelect(N, DAG, DCI, Subtarget);
   case ISD::BITCAST:        return combineBitcast(N, DAG, DCI, Subtarget);
+  case ISD::MASK_BEFOREFIRST:
+    return combineMaskBeforeFirst(N, DAG, DCI);
   case X86ISD::CMOV:        return combineCMov(N, DAG, DCI, Subtarget);
   case X86ISD::CMP:         return combineCMP(N, DAG, DCI, Subtarget);
   case ISD::ADD:            return combineAdd(N, DAG, DCI, Subtarget);
diff --git a/llvm/test/CodeGen/X86/mask-beforefirst.ll b/llvm/test/CodeGen/X86/mask-beforefirst.ll
index e944d479f4d54..c5e8b1f8e1c90 100644
--- a/llvm/test/CodeGen/X86/mask-beforefirst.ll
+++ b/llvm/test/CodeGen/X86/mask-beforefirst.ll
@@ -9,89 +9,60 @@ define <16 x i8> @v16i1(<16 x i8> %a0, <16 x i8> %a1) {
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
 ; SSE2-NEXT:    pcmpgtb %xmm1, %xmm2
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[2,3,2,3]
-; SSE2-NEXT:    pmaxub %xmm2, %xmm3
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm3[1,1,1,1]
-; SSE2-NEXT:    pmaxub %xmm3, %xmm2
-; SSE2-NEXT:    movdqa %xmm2, %xmm3
-; SSE2-NEXT:    psrld $16, %xmm3
-; SSE2-NEXT:    pmaxub %xmm2, %xmm3
-; SSE2-NEXT:    movdqa %xmm3, %xmm2
-; SSE2-NEXT:    psrlw $8, %xmm2
-; SSE2-NEXT:    pmaxub %xmm3, %xmm2
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    movb $16, %cl
-; SSE2-NEXT:    subb %al, %cl
-; SSE2-NEXT:    movzbl %cl, %eax
+; SSE2-NEXT:    pmovmskb %xmm2, %eax
+; SSE2-NEXT:    leal -1(%rax), %ecx
+; SSE2-NEXT:    notl %eax
+; SSE2-NEXT:    andl %ecx, %eax
 ; SSE2-NEXT:    movd %eax, %xmm2
 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm2 = xmm2[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
-; SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[0,0,0,0,4,5,6,7]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,1,0,1]
-; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
-; SSE2-NEXT:    pmaxub %xmm3, %xmm2
+; SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[0,0,1,1,4,5,6,7]
+; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,0,1,1]
+; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; SSE2-NEXT:    pand %xmm3, %xmm2
 ; SSE2-NEXT:    pcmpeqb %xmm3, %xmm2
-; SSE2-NEXT:    pand %xmm2, %xmm1
-; SSE2-NEXT:    pandn %xmm0, %xmm2
-; SSE2-NEXT:    por %xmm1, %xmm2
-; SSE2-NEXT:    movdqa %xmm2, %xmm0
+; SSE2-NEXT:    pand %xmm2, %xmm0
+; SSE2-NEXT:    pandn %xmm1, %xmm2
+; SSE2-NEXT:    por %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE42-LABEL: v16i1:
 ; SSE42:       # %bb.0:
 ; SSE42-NEXT:    movdqa %xmm0, %xmm2
 ; SSE42-NEXT:    pcmpgtb %xmm1, %xmm0
-; SSE42-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE42-NEXT:    pcmpeqd %xmm3, %xmm3
-; SSE42-NEXT:    pxor %xmm0, %xmm3
-; SSE42-NEXT:    movdqa %xmm3, %xmm0
-; SSE42-NEXT:    psrlw $8, %xmm0
-; SSE42-NEXT:    pminub %xmm3, %xmm0
-; SSE42-NEXT:    phminposuw %xmm0, %xmm0
-; SSE42-NEXT:    movd %xmm0, %eax
-; SSE42-NEXT:    addb $17, %al
-; SSE42-NEXT:    movzbl %al, %eax
+; SSE42-NEXT:    pmovmskb %xmm0, %eax
+; SSE42-NEXT:    leal -1(%rax), %ecx
+; SSE42-NEXT:    notl %eax
+; SSE42-NEXT:    andl %ecx, %eax
 ; SSE42-NEXT:    movd %eax, %xmm0
-; SSE42-NEXT:    pxor %xmm3, %xmm3
-; SSE42-NEXT:    pshufb %xmm3, %xmm0
-; SSE42-NEXT:    movdqa {{.*#+}} xmm3 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
-; SSE42-NEXT:    pmaxub %xmm3, %xmm0
+; SSE42-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1]
+; SSE42-NEXT:    movdqa {{.*#+}} xmm3 = [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; SSE42-NEXT:    pand %xmm3, %xmm0
 ; SSE42-NEXT:    pcmpeqb %xmm3, %xmm0
-; SSE42-NEXT:    pblendvb %xmm0, %xmm1, %xmm2
-; SSE42-NEXT:    movdqa %xmm2, %xmm0
+; SSE42-NEXT:    pblendvb %xmm0, %xmm2, %xmm1
+; SSE42-NEXT:    movdqa %xmm1, %xmm0
 ; SSE42-NEXT:    retq
 ;
 ; AVX2-LABEL: v16i1:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vpcmpgtb %xmm1, %xmm0, %xmm2
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2, %xmm2
-; AVX2-NEXT:    vpcmpeqd %xmm3, %xmm3, %xmm3
-; AVX2-NEXT:    vpxor %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vpsrlw $8, %xmm2, %xmm3
-; AVX2-NEXT:    vpminub %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vphminposuw %xmm2, %xmm2
-; AVX2-NEXT:    vmovd %xmm2, %eax
-; AVX2-NEXT:    addb $17, %al
+; AVX2-NEXT:    vpmovmskb %xmm2, %eax
+; AVX2-NEXT:    leal -1(%rax), %ecx
+; AVX2-NEXT:    andnl %ecx, %eax, %eax
 ; AVX2-NEXT:    vmovd %eax, %xmm2
-; AVX2-NEXT:    vpbroadcastb %xmm2, %xmm2
-; AVX2-NEXT:    vmovdqa {{.*#+}} xmm3 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
-; AVX2-NEXT:    vpmaxub %xmm3, %xmm2, %xmm2
+; AVX2-NEXT:    vpshufb {{.*#+}} xmm2 = xmm2[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1]
+; AVX2-NEXT:    vpbroadcastq {{.*#+}} xmm3 = [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; AVX2-NEXT:    vpand %xmm3, %xmm2, %xmm2
 ; AVX2-NEXT:    vpcmpeqb %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vpblendvb %xmm2, %xmm0, %xmm1, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: v16i1:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpcmpgtb %xmm1, %xmm0, %k1
-; AVX512-NEXT:    vpcmpeqd %xmm2, %xmm2, %xmm2
-; AVX512-NEXT:    vmovdqu8 {{.*#+}} xmm2 {%k1} = [239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254]
-; AVX512-NEXT:    vpsrlw $8, %xmm2, %xmm3
-; AVX512-NEXT:    vpminub %xmm3, %xmm2, %xmm2
-; AVX512-NEXT:    vphminposuw %xmm2, %xmm2
-; AVX512-NEXT:    vmovd %xmm2, %eax
-; AVX512-NEXT:    addb $17, %al
-; AVX512-NEXT:    vpbroadcastb %eax, %xmm2
-; AVX512-NEXT:    vpcmpnleub {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2, %k1
+; AVX512-NEXT:    vpcmpgtb %xmm1, %xmm0, %k0
+; AVX512-NEXT:    kmovd %k0, %eax
+; AVX512-NEXT:    leal -1(%rax), %ecx
+; AVX512-NEXT:    andnl %ecx, %eax, %eax
+; AVX512-NEXT:    kmovd %eax, %k1
 ; AVX512-NEXT:    vpblendmb %xmm0, %xmm1, %xmm0 {%k1}
 ; AVX512-NEXT:    retq
   %m = icmp sgt <16 x i8> %a0, %a1
@@ -105,24 +76,17 @@ define <8 x i16> @v8i1(<8 x i16> %a0, <8 x i16> %a1) {
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
 ; SSE2-NEXT:    pcmpgtw %xmm1, %xmm2
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[2,3,2,3]
-; SSE2-NEXT:    psubusw %xmm2, %xmm3
-; SSE2-NEXT:    paddw %xmm2, %xmm3
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm3[1,1,1,1]
-; SSE2-NEXT:    psubusw %xmm3, %xmm2
-; SSE2-NEXT:    paddw %xmm3, %xmm2
-; SSE2-NEXT:    pextrw $1, %xmm2, %eax
-; SSE2-NEXT:    movd %xmm2, %ecx
-; SSE2-NEXT:    cmpw %ax, %cx
-; SSE2-NEXT:    cmoval %ecx, %eax
-; SSE2-NEXT:    movl $8, %ecx
-; SSE2-NEXT:    subl %eax, %ecx
-; SSE2-NEXT:    movd %ecx, %xmm2
+; SSE2-NEXT:    packsswb %xmm2, %xmm2
+; SSE2-NEXT:    pmovmskb %xmm2, %eax
+; SSE2-NEXT:    leal -1(%rax), %ecx
+; SSE2-NEXT:    notl %eax
+; SSE2-NEXT:    andl %ecx, %eax
+; SSE2-NEXT:    movd %eax, %xmm2
 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[0,0,0,0,4,5,6,7]
 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,1,0,1]
-; SSE2-NEXT:    pxor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    pcmpgtw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [1,2,4,8,16,32,64,128]
+; SSE2-NEXT:    pand %xmm3, %xmm2
+; SSE2-NEXT:    pcmpeqw %xmm3, %xmm2
 ; SSE2-NEXT:    pand %xmm2, %xmm0
 ; SSE2-NEXT:    pandn %xmm1, %xmm2
 ; SSE2-NEXT:    por %xmm2, %xmm0
@@ -132,51 +96,43 @@ define <8 x i16> @v8i1(<8 x i16> %a0, <8 x i16> %a1) {
 ; SSE42:       # %bb.0:
 ; SSE42-NEXT:    movdqa %xmm0, %xmm2
 ; SSE42-NEXT:    pcmpgtw %xmm1, %xmm0
-; SSE42-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE42-NEXT:    pcmpeqd %xmm3, %xmm3
-; SSE42-NEXT:    pxor %xmm0, %xmm3
-; SSE42-NEXT:    phminposuw %xmm3, %xmm0
-; SSE42-NEXT:    movd %xmm0, %eax
-; SSE42-NEXT:    addl $9, %eax
+; SSE42-NEXT:    packsswb %xmm0, %xmm0
+; SSE42-NEXT:    pmovmskb %xmm0, %eax
+; SSE42-NEXT:    leal -1(%rax), %ecx
+; SSE42-NEXT:    notl %eax
+; SSE42-NEXT:    andl %ecx, %eax
 ; SSE42-NEXT:    movd %eax, %xmm0
 ; SSE42-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,0,0,0,4,5,6,7]
 ; SSE42-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
-; SSE42-NEXT:    movdqa {{.*#+}} xmm3 = [0,1,2,3,4,5,6,7]
-; SSE42-NEXT:    pmaxuw %xmm3, %xmm0
+; SSE42-NEXT:    movdqa {{.*#+}} xmm3 = [1,2,4,8,16,32,64,128]
+; SSE42-NEXT:    pand %xmm3, %xmm0
 ; SSE42-NEXT:    pcmpeqw %xmm3, %xmm0
-; SSE42-NEXT:    pblendvb %xmm0, %xmm1, %xmm2
-; SSE42-NEXT:    movdqa %xmm2, %xmm0
+; SSE42-NEXT:    pblendvb %xmm0, %xmm2, %xmm1
+; SSE42-NEXT:    movdqa %xmm1, %xmm0
 ; SSE42-NEXT:    retq
 ;
 ; AVX2-LABEL: v8i1:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vpcmpgtw %xmm1, %xmm0, %xmm2
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2, %xmm2
-; AVX2-NEXT:    vpcmpeqd %xmm3, %xmm3, %xmm3
-; AVX2-NEXT:    vpxor %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vphminposuw %xmm2, %xmm2
-; AVX2-NEXT:    vmovd %xmm2, %eax
-; AVX2-NEXT:    addl $9, %eax
+; AVX2-NEXT:    vpacksswb %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vpmovmskb %xmm2, %eax
+; AVX2-NEXT:    leal -1(%rax), %ecx
+; AVX2-NEXT:    andnl %ecx, %eax, %eax
 ; AVX2-NEXT:    vmovd %eax, %xmm2
-; AVX2-NEXT:    vpbroadcastw %xmm2, %xmm2
-; AVX2-NEXT:    vmovdqa {{.*#+}} xmm3 = [0,1,2,3,4,5,6,7]
-; AVX2-NEXT:    vpmaxuw %xmm3, %xmm2, %xmm2
+; AVX2-NEXT:    vpbroadcastb %xmm2, %xmm2
+; AVX2-NEXT:    vmovdqa {{.*#+}} xmm3 = [1,2,4,8,16,32,64,128]
+; AVX2-NEXT:    vpand %xmm3, %xmm2, %xmm2
 ; AVX2-NEXT:    vpcmpeqw %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vpblendvb %xmm2, %xmm0, %xmm1, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: v8i1:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpcmpgtw %xmm1, %xmm0, %k1
-; AVX512-NEXT:    vpcmpeqd %xmm2, %xmm2, %xmm2
-; AVX512-NEXT:    vmovdqu8 {{.*#+}} xmm2 {%k1} = [247,248,249,250,251,252,253,254,u,u,u,u,u,u,u,u]
-; AVX512-NEXT:    vpsrlw $8, %xmm2, %xmm3
-; AVX512-NEXT:    vpminub %xmm3, %xmm2, %xmm2
-; AVX512-NEXT:    vphminposuw %xmm2, %xmm2
-; AVX512-NEXT:    vmovd %xmm2, %eax
-; AVX512-NEXT:    addb $9, %al
-; AVX512-NEXT:    vpbroadcastb %eax, %xmm2
-; AVX512-NEXT:    vpcmpnleub {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2, %k1
+; AVX512-NEXT:    vpcmpgtw %xmm1, %xmm0, %k0
+; AVX512-NEXT:    kmovd %k0, %eax
+; AVX512-NEXT:    leal -1(%rax), %ecx
+; AVX512-NEXT:    andnl %ecx, %eax, %eax
+; AVX512-NEXT:    kmovd %eax, %k1
 ; AVX512-NEXT:    vpblendmw %xmm0, %xmm1, %xmm0 {%k1}
 ; AVX512-NEXT:    retq
   %m = icmp sgt <8 x i16> %a0, %a1
@@ -190,28 +146,15 @@ define <4 x i32> @v4i1(<4 x i32> %a0, <4 x i32> %a1) {
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
 ; SSE2-NEXT:    pcmpgtd %xmm1, %xmm2
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [2147483648,2147483648,2147483648,2147483648]
-; SSE2-NEXT:    movdqa %xmm2, %xmm4
-; SSE2-NEXT:    por %xmm3, %xmm4
-; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm2[2,3,2,3]
-; SSE2-NEXT:    movdqa %xmm5, %xmm6
-; SSE2-NEXT:    por %xmm3, %xmm6
-; SSE2-NEXT:    pcmpgtd %xmm6, %xmm4
-; SSE2-NEXT:    pand %xmm4, %xmm2
-; SSE2-NEXT:    pandn %xmm5, %xmm4
-; SSE2-NEXT:    por %xmm2, %xmm4
-; SSE2-NEXT:    movd %xmm4, %eax
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm4[1,1,1,1]
-; SSE2-NEXT:    movd %xmm2, %ecx
-; SSE2-NEXT:    cmpl %ecx, %eax
-; SSE2-NEXT:    cmoval %eax, %ecx
-; SSE2-NEXT:    movl $4, %eax
-; SSE2-NEXT:    subl %ecx, %eax
+; SSE2-NEXT:    movmskps %xmm2, %eax
+; SSE2-NEXT:    leal -1(%rax), %ecx
+; SSE2-NEXT:    notl %eax
+; SSE2-NEXT:    andl %ecx, %eax
 ; SSE2-NEXT:    movd %eax, %xmm2
 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,0,0,0]
-; SSE2-NEXT:    pxor %xmm3, %xmm2
-; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [1,2,4,8]
+; SSE2-NEXT:    pand %xmm3, %xmm2
+; SSE2-NEXT:    pcmpeqd %xmm3, %xmm2
 ; SSE2-NEXT:    pand %xmm2, %xmm0
 ; SSE2-NEXT:    pandn %xmm1, %xmm2
 ; SSE2-NEXT:    por %xmm2, %xmm0
@@ -221,52 +164,40 @@ define <4 x i32> @v4i1(<4 x i32> %a0, <4 x i32> %a1) {
 ; SSE42:       # %bb.0:
 ; SSE42-NEXT:    movdqa %xmm0, %xmm2
 ; SSE42-NEXT:    pcmpgtd %xmm1, %xmm0
-; SSE42-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE42-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[2,3,2,3]
-; SSE42-NEXT:    pmaxud %xmm0, %xmm3
-; SSE42-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[1,1,1,1]
-; SSE42-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[0,0,0,0]
-; SSE42-NEXT:    pmaxud %xmm0, %xmm3
-; SSE42-NEXT:    movdqa {{.*#+}} xmm0 = [4,4,4,4]
-; SSE42-NEXT:    psubd %xmm3, %xmm0
-; SSE42-NEXT:    movdqa {{.*#+}} xmm3 = [0,1,2,3]
-; SSE42-NEXT:    pmaxud %xmm3, %xmm0
+; SSE42-NEXT:    movmskps %xmm0, %eax
+; SSE42-NEXT:    leal -1(%rax), %ecx
+; SSE42-NEXT:    notl %eax
+; SSE42-NEXT:    andl %ecx, %eax
+; SSE42-NEXT:    movd %eax, %xmm0
+; SSE42-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,0,0,0]
+; SSE42-NEXT:    movdqa {{.*#+}} xmm3 = [1,2,4,8]
+; SSE42-NEXT:    pand %xmm3, %xmm0
 ; SSE42-NEXT:    pcmpeqd %xmm3, %xmm0
-; SSE42-NEXT:    blendvps %xmm0, %xmm1, %xmm2
-; SSE42-NEXT:    movaps %xmm2, %xmm0
+; SSE42-NEXT:    blendvps %xmm0, %xmm2, %xmm1
+; SSE42-NEXT:    movaps %xmm1, %xmm0
 ; SSE42-NEXT:    retq
 ;
 ; AVX2-LABEL: v4i1:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vpcmpgtd %xmm1, %xmm0, %xmm2
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2, %xmm2
-; AVX2-NEXT:    vpshufd {{.*#+}} xmm3 = xmm2[2,3,2,3]
-; AVX2-NEXT:    vpmaxud %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vpshufd {{.*#+}} xmm3 = xmm2[1,1,1,1]
-; AVX2-NEXT:    vpmaxud %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vmovd %xmm2, %eax
-; AVX2-NEXT:    movl $4, %ecx
-; AVX2-NEXT:    subl %eax, %ecx
-; AVX2-NEXT:    vmovd %ecx, %xmm2
+; AVX2-NEXT:    vmovmskps %xmm2, %eax
+; AVX2-NEXT:    leal -1(%rax), %ecx
+; AVX2-NEXT:    andnl %ecx, %eax, %eax
+; AVX2-NEXT:    vmovd %eax, %xmm2
 ; AVX2-NEXT:    vpbroadcastd %xmm2, %xmm2
-; AVX2-NEXT:    vmovdqa {{.*#+}} xmm3 = [0,1,2,3]
-; AVX2-NEXT:    vpmaxud %xmm3, %xmm2, %xmm2
+; AVX2-NEXT:    vmovdqa {{.*#+}} xmm3 = [1,2,4,8]
+; AVX2-NEXT:    vpand %xmm3, %xmm2, %xmm2
 ; AVX2-NEXT:    vpcmpeqd %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vblendvps %xmm2, %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vblendvps %xmm2, %xmm0, %xmm1, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: v4i1:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vpcmpgtd %xmm1, %xmm0, %k1
-; AVX512-NEXT:    vpcmpeqd %xmm2, %xmm2, %xmm2
-; AVX512-NEXT:    vmovdqu8 {{.*#+}} xmm2 {%k1} = [251,252,253,254,u,u,u,u,u,u,u,u,u,u,u,u]
-; AVX512-NEXT:    vpsrlw $8, %xmm2, %xmm3
-; AVX512-NEXT:    vpminub %xmm3, %xmm2, %xmm2
-; AVX512-NEXT:    vphminposuw %xmm2, %xmm2
-; AVX512-NEXT:    vmovd %xmm2, %eax
-; AVX512-NEXT:    addb $5, %al
-; AVX512-NEXT:    vpbroadcastb %eax, %xmm2
-; AVX512-NEXT:    vpcmpnleub {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2, %k1
+; AVX512-NEXT:    vpcmpgtd %xmm1, %xmm0, %k0
+; AVX512-NEXT:    kmovd %k0, %eax
+; AVX512-NEXT:    leal -1(%rax), %ecx
+; AVX512-NEXT:    andnl %ecx, %eax, %eax
+; AVX512-NEXT:    kmovd %eax, %k1
 ; AVX512-NEXT:    vpblendmd %xmm0, %xmm1, %xmm0 {%k1}
 ; AVX512-NEXT:    retq
   %m = icmp sgt <4 x i32> %a0, %a1
@@ -290,44 +221,35 @@ define <2 x i64> @v2i1(<2 x i64> %a0, <2 x i64> %a1) {
 ; SSE2-NEXT:    pand %xmm5, %xmm2
 ; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[1,1,3,3]
 ; SSE2-NEXT:    por %xmm2, %xmm3
-; SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3
-; SSE2-NEXT:    movd %xmm3, %eax
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm3[2,3,2,3]
-; SSE2-NEXT:    movd %xmm2, %ecx
-; SSE2-NEXT:    cmpq %rcx, %rax
-; SSE2-NEXT:    cmovaq %rax, %rcx
-; SSE2-NEXT:    movl $2, %eax
-; SSE2-NEXT:    subq %rcx, %rax
-; SSE2-NEXT:    movq %rax, %xmm2
+; SSE2-NEXT:    movmskpd %xmm3, %eax
+; SSE2-NEXT:    leal -1(%rax), %ecx
+; SSE2-NEXT:    notl %eax
+; SSE2-NEXT:    andl %ecx, %eax
+; SSE2-NEXT:    movd %eax, %xmm2
 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,1,0,1]
-; SSE2-NEXT:    pxor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
-; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3
-; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm2[0,0,2,2]
-; SSE2-NEXT:    pand %xmm4, %xmm3
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
-; SSE2-NEXT:    por %xmm3, %xmm2
-; SSE2-NEXT:    pand %xmm2, %xmm0
-; SSE2-NEXT:    pandn %xmm1, %xmm2
-; SSE2-NEXT:    por %xmm2, %xmm0
+; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [1,2]
+; SSE2-NEXT:    pand %xmm3, %xmm2
+; SSE2-NEXT:    pcmpeqd %xmm3, %xmm2
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[1,0,3,2]
+; SSE2-NEXT:    pand %xmm2, %xmm3
+; SSE2-NEXT:    pand %xmm3, %xmm0
+; SSE2-NEXT:    pandn %xmm1, %xmm3
+; SSE2-NEXT:    por %xmm3, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE42-LABEL: v2i1:
 ; SSE42:       # %bb.0:
 ; SSE42-NEXT:    movdqa %xmm0, %xmm2
 ; SSE42-NEXT:    pcmpgtq %xmm1, %xmm0
-; SSE42-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE42-NEXT:    pextrq $1, %xmm0, %rax
-; SSE42-NEXT:    movd %xmm0, %ecx
-; SSE42-NEXT:    cmpq %rax, %rcx
-; SSE42-NEXT:    cmovaq %rcx, %rax
-; SSE42-NEXT:    movl $2, %ecx
-; SSE42-NEXT:    subq %rax, %rcx
-; SSE42-NEXT:    movq %rcx, %xmm0
+; SSE42-NEXT:    movmskpd %xmm0, %eax
+; SSE42-NEXT:    leal -1(%rax), %ecx
+; SSE42-NEXT:    notl %eax
+; SSE42-NEXT:    andl %ecx, %eax
+; SSE42-NEXT:    movd %eax, %xmm0
 ; SSE42-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
-; SSE42-NEXT:    pxor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE42-NEXT:    pcmpgtq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE42-NEXT:    movdqa {{.*#+}} xmm3 = [1,2]
+; SSE42-NEXT:    pand %xmm3, %xmm0
+; SSE42-NEXT:    pcmpeqq %xmm3, %xmm0
 ; SSE42-NEXT:    blendvpd %xmm0, %xmm2, %xmm1
 ; SSE42-NEXT:    movapd %xmm1, %xmm0
 ; SSE42-NEXT:    retq
@@ -335,32 +257,24 @@ define <2 x i64> @v2i1(<2 x i64> %a0, <2 x i64> %a1) {
 ; AVX2-LABEL: v2i1:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vpcmpgtq %xmm1, %xmm0, %xmm2
-; AVX2-NEXT:    vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2, %xmm2
-; AVX2-NEXT:    vpextrq $1, %xmm2, %rax
-; AVX2-NEXT:    vmovd %xmm2, %ecx
-; AVX2-NEXT:    cmpq %rax, %rcx
-; AVX2-NEXT:    cmovaq %rcx, %rax
-; AVX2-NEXT:    movl $2, %ecx
-; AVX2-NEXT:    subq %rax, %rcx
-; AVX2-NEXT:    vmovq %rcx, %xmm2
-; AVX2-NEXT:    vpbroadcastq %xmm2, %xmm2
-; AVX2-NEXT:    vpxor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2, %xmm2
-; AVX2-NEXT:    vpcmpgtq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2, %xmm2
+; AVX2-NEXT:    vmovmskpd %xmm2, %eax
+; AVX2-NEXT:    leal -1(%rax), %ecx
+; AVX2-NEXT:    andnl %ecx, %eax, %eax
+; AVX2-NEXT:    vmovd %eax, %xmm2
+; AVX2-NEXT:    vpbroadcastd %xmm2, %xmm2
+; AVX2-NEXT:    vmovdqa {{.*#...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/232262


More information about the llvm-branch-commits mailing list