diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2024-11-20 17:46:46 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2024-11-21 10:35:56 +0000 |
commit | 600a83bf9ba2bee5ed1e9867e201f7707b1d8102 (patch) | |
tree | a62a60c06763a8f0c193cc671dbaef0ecb73e5f0 | |
parent | 97ac84846a724809d28e167651b81355696d0d0b (diff) | |
download | llvm-600a83bf9ba2bee5ed1e9867e201f7707b1d8102.zip llvm-600a83bf9ba2bee5ed1e9867e201f7707b1d8102.tar.gz llvm-600a83bf9ba2bee5ed1e9867e201f7707b1d8102.tar.bz2 |
[X86] IsNOT - match or(not(X),not(Y)) -> and(X,Y)
Fixes #116977
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 16 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/vector-compare-all_of.ll | 42 |
2 files changed, 27 insertions, 31 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index fea66e9..2b497f3 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5211,8 +5211,10 @@ static bool isConstantPowerOf2(SDValue V, unsigned EltSizeInBIts, // Match not(pcmpgt(C, X)) -> pcmpgt(X, C - 1). // Match not(extract_subvector(xor X, -1)) -> extract_subvector(X). // Match not(concat_vectors(xor X, -1, xor Y, -1)) -> concat_vectors(X, Y). +// Match or(not(X),not(Y)) -> and(X, Y). static SDValue IsNOT(SDValue V, SelectionDAG &DAG) { V = peekThroughBitcasts(V); + EVT VT = V.getValueType(); if (V.getOpcode() == ISD::XOR && (ISD::isBuildVectorAllOnes(V.getOperand(1).getNode()) || isAllOnesConstant(V.getOperand(1)))) @@ -5221,8 +5223,8 @@ static SDValue IsNOT(SDValue V, SelectionDAG &DAG) { (isNullConstant(V.getOperand(1)) || V.getOperand(0).hasOneUse())) { if (SDValue Not = IsNOT(V.getOperand(0), DAG)) { Not = DAG.getBitcast(V.getOperand(0).getValueType(), Not); - return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(Not), V.getValueType(), - Not, V.getOperand(1)); + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(Not), VT, Not, + V.getOperand(1)); } } if (V.getOpcode() == X86ISD::PCMPGT && @@ -5255,7 +5257,15 @@ static SDValue IsNOT(SDValue V, SelectionDAG &DAG) { if (!NotCat) return SDValue(); CatOp = DAG.getBitcast(CatOp.getValueType(), NotCat); } - return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(V), V.getValueType(), CatOps); + return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(V), VT, CatOps); + } + if (V.getOpcode() == ISD::OR && DAG.getTargetLoweringInfo().isTypeLegal(VT) && + V.getOperand(0).hasOneUse() && V.getOperand(1).hasOneUse()) { + // TODO: Handle cases with single NOT operand -> ANDNP + if (SDValue Op1 = IsNOT(V.getOperand(1), DAG)) + if (SDValue Op0 = IsNOT(V.getOperand(0), DAG)) + return DAG.getNode(ISD::AND, SDLoc(V), VT, DAG.getBitcast(VT, Op0), + DAG.getBitcast(VT, Op1)); } return SDValue(); } diff --git a/llvm/test/CodeGen/X86/vector-compare-all_of.ll b/llvm/test/CodeGen/X86/vector-compare-all_of.ll index deaf2d1..bf027a7 100644 --- a/llvm/test/CodeGen/X86/vector-compare-all_of.ll +++ b/llvm/test/CodeGen/X86/vector-compare-all_of.ll @@ -1599,55 +1599,41 @@ define i1 @PR116977(<32 x i8> %a, <32 x i8> %b, <32 x i8> %v) { ; SSE-LABEL: PR116977: ; SSE: # %bb.0: ; SSE-NEXT: pcmpeqb %xmm4, %xmm0 -; SSE-NEXT: pcmpeqd %xmm6, %xmm6 -; SSE-NEXT: pxor %xmm6, %xmm0 ; SSE-NEXT: pcmpeqb %xmm5, %xmm1 -; SSE-NEXT: pxor %xmm6, %xmm1 ; SSE-NEXT: pcmpeqb %xmm4, %xmm2 -; SSE-NEXT: pxor %xmm6, %xmm2 -; SSE-NEXT: por %xmm0, %xmm2 +; SSE-NEXT: pand %xmm0, %xmm2 ; SSE-NEXT: pcmpeqb %xmm5, %xmm3 -; SSE-NEXT: pxor %xmm6, %xmm3 -; SSE-NEXT: por %xmm1, %xmm3 -; SSE-NEXT: por %xmm2, %xmm3 +; SSE-NEXT: pand %xmm1, %xmm3 +; SSE-NEXT: pand %xmm2, %xmm3 ; SSE-NEXT: pmovmskb %xmm3, %eax -; SSE-NEXT: testl %eax, %eax +; SSE-NEXT: cmpl $65535, %eax # imm = 0xFFFF ; SSE-NEXT: sete %al ; SSE-NEXT: retq ; ; AVX1-LABEL: PR116977: ; AVX1: # %bb.0: ; AVX1-NEXT: vpcmpeqb %xmm0, %xmm2, %xmm3 -; AVX1-NEXT: vpcmpeqd %xmm4, %xmm4, %xmm4 -; AVX1-NEXT: vpxor %xmm4, %xmm3, %xmm3 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 -; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm5 -; AVX1-NEXT: vpcmpeqb %xmm0, %xmm5, %xmm0 -; AVX1-NEXT: vpxor %xmm4, %xmm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm4 +; AVX1-NEXT: vpcmpeqb %xmm0, %xmm4, %xmm0 ; AVX1-NEXT: vpcmpeqb %xmm1, %xmm2, %xmm2 -; AVX1-NEXT: vpxor %xmm4, %xmm2, %xmm2 -; AVX1-NEXT: vpor %xmm2, %xmm3, %xmm2 +; AVX1-NEXT: vpand %xmm2, %xmm3, %xmm2 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm1 -; AVX1-NEXT: vpcmpeqb %xmm1, %xmm5, %xmm1 -; AVX1-NEXT: vpxor %xmm4, %xmm1, %xmm1 -; AVX1-NEXT: vpor %xmm1, %xmm0, %xmm0 -; AVX1-NEXT: vpor %xmm0, %xmm2, %xmm0 +; AVX1-NEXT: vpcmpeqb %xmm1, %xmm4, %xmm1 +; AVX1-NEXT: vpand %xmm1, %xmm0, %xmm0 +; AVX1-NEXT: vpand %xmm0, %xmm2, %xmm0 ; AVX1-NEXT: vpmovmskb %xmm0, %eax -; AVX1-NEXT: testl %eax, %eax +; AVX1-NEXT: xorl $65535, %eax # imm = 0xFFFF ; AVX1-NEXT: sete %al ; AVX1-NEXT: vzeroupper ; AVX1-NEXT: retq ; ; AVX2-LABEL: PR116977: ; AVX2: # %bb.0: -; AVX2-NEXT: vpcmpeqb %ymm0, %ymm2, %ymm0 -; AVX2-NEXT: vpcmpeqd %ymm3, %ymm3, %ymm3 -; AVX2-NEXT: vpxor %ymm3, %ymm0, %ymm0 -; AVX2-NEXT: vpcmpeqb %ymm1, %ymm2, %ymm1 -; AVX2-NEXT: vpxor %ymm3, %ymm1, %ymm1 +; AVX2-NEXT: vpxor %ymm0, %ymm2, %ymm0 +; AVX2-NEXT: vpxor %ymm1, %ymm2, %ymm1 ; AVX2-NEXT: vpor %ymm1, %ymm0, %ymm0 -; AVX2-NEXT: vpmovmskb %ymm0, %eax -; AVX2-NEXT: testl %eax, %eax +; AVX2-NEXT: vptest %ymm0, %ymm0 ; AVX2-NEXT: sete %al ; AVX2-NEXT: vzeroupper ; AVX2-NEXT: retq |