[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