From: Craig Topper Date: Thu, 1 Nov 2018 23:21:45 +0000 (+0000) Subject: [DAGCombiner] Make the isTruncateOf call from visitZERO_EXTEND work for vectors.... X-Git-Tag: llvmorg-8.0.0-rc1~5178 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e2483020f277d2efa46c79238b9b325aa9f2f684;p=platform%2Fupstream%2Fllvm.git [DAGCombiner] Make the isTruncateOf call from visitZERO_EXTEND work for vectors. Remove FIXME. I'm having trouble creating a test case for the ISD::TRUNCATE part of this that shows any codegen differences. But I was able to test the setcc path which is what the test changes here cover. llvm-svn: 345908 --- diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d0c898f..03145c5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -8696,27 +8696,25 @@ static bool isTruncateOf(SelectionDAG &DAG, SDValue N, SDValue &Op, return true; } - if (N->getOpcode() != ISD::SETCC || N->getValueType(0) != MVT::i1 || - cast(N->getOperand(2))->get() != ISD::SETNE) + if (N.getOpcode() != ISD::SETCC || + N.getValueType().getScalarType() != MVT::i1 || + cast(N.getOperand(2))->get() != ISD::SETNE) return false; SDValue Op0 = N->getOperand(0); SDValue Op1 = N->getOperand(1); assert(Op0.getValueType() == Op1.getValueType()); - if (isNullConstant(Op0)) + if (isNullConstantOrNullSplatConstant(Op0)) Op = Op1; - else if (isNullConstant(Op1)) + else if (isNullConstantOrNullSplatConstant(Op1)) Op = Op0; else return false; DAG.computeKnownBits(Op, Known); - if (!(Known.Zero | 1).isAllOnesValue()) - return false; - - return true; + return (Known.Zero | 1).isAllOnesValue(); } SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { @@ -8736,17 +8734,16 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { // fold (zext (truncate x)) -> (zext x) or // (zext (truncate x)) -> (truncate x) // This is valid when the truncated bits of x are already zero. - // FIXME: We should extend this to work for vectors too. SDValue Op; KnownBits Known; - if (!VT.isVector() && isTruncateOf(DAG, N0, Op, Known)) { + if (isTruncateOf(DAG, N0, Op, Known)) { APInt TruncatedBits = - (Op.getValueSizeInBits() == N0.getValueSizeInBits()) ? - APInt(Op.getValueSizeInBits(), 0) : - APInt::getBitsSet(Op.getValueSizeInBits(), - N0.getValueSizeInBits(), - std::min(Op.getValueSizeInBits(), - VT.getSizeInBits())); + (Op.getScalarValueSizeInBits() == N0.getScalarValueSizeInBits()) ? + APInt(Op.getScalarValueSizeInBits(), 0) : + APInt::getBitsSet(Op.getScalarValueSizeInBits(), + N0.getScalarValueSizeInBits(), + std::min(Op.getScalarValueSizeInBits(), + VT.getScalarSizeInBits())); if (TruncatedBits.isSubsetOf(Known.Zero)) return DAG.getZExtOrTrunc(Op, SDLoc(N), VT); } diff --git a/llvm/test/CodeGen/X86/vector-pcmp.ll b/llvm/test/CodeGen/X86/vector-pcmp.ll index 916c09a..683a565 100644 --- a/llvm/test/CodeGen/X86/vector-pcmp.ll +++ b/llvm/test/CodeGen/X86/vector-pcmp.ll @@ -444,56 +444,36 @@ define <2 x i64> @cmpgt_zext_v2i64(<2 x i64> %a, <2 x i64> %b) { define <8 x i32> @cmpne_knownzeros_zext_v8i16_v8i32(<8 x i16> %x) { ; SSE2-LABEL: cmpne_knownzeros_zext_v8i16_v8i32: ; SSE2: # %bb.0: -; SSE2-NEXT: psrlw $15, %xmm0 +; SSE2-NEXT: movdqa %xmm0, %xmm1 +; SSE2-NEXT: psrlw $15, %xmm1 ; SSE2-NEXT: pxor %xmm2, %xmm2 -; SSE2-NEXT: pcmpeqw %xmm0, %xmm2 -; SSE2-NEXT: pcmpeqd %xmm1, %xmm1 -; SSE2-NEXT: pxor %xmm2, %xmm1 ; SSE2-NEXT: movdqa %xmm1, %xmm0 -; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] -; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1] -; SSE2-NEXT: pand %xmm2, %xmm0 -; SSE2-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] -; SSE2-NEXT: pand %xmm2, %xmm1 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; SSE2-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7] ; SSE2-NEXT: retq ; ; SSE42-LABEL: cmpne_knownzeros_zext_v8i16_v8i32: ; SSE42: # %bb.0: ; SSE42-NEXT: psrlw $15, %xmm0 -; SSE42-NEXT: pxor %xmm2, %xmm2 -; SSE42-NEXT: pcmpeqw %xmm0, %xmm2 -; SSE42-NEXT: pcmpeqd %xmm1, %xmm1 -; SSE42-NEXT: pxor %xmm2, %xmm1 -; SSE42-NEXT: pmovzxwd {{.*#+}} xmm0 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero -; SSE42-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1] -; SSE42-NEXT: pand %xmm2, %xmm0 -; SSE42-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] -; SSE42-NEXT: pand %xmm2, %xmm1 +; SSE42-NEXT: pmovzxwd {{.*#+}} xmm2 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] +; SSE42-NEXT: pmovzxwd {{.*#+}} xmm1 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; SSE42-NEXT: movdqa %xmm2, %xmm0 ; SSE42-NEXT: retq ; ; AVX1-LABEL: cmpne_knownzeros_zext_v8i16_v8i32: ; AVX1: # %bb.0: ; AVX1-NEXT: vpsrlw $15, %xmm0, %xmm0 -; AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm1 -; AVX1-NEXT: vpcmpeqw %xmm1, %xmm0, %xmm0 -; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 -; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0 -; AVX1-NEXT: vpunpckhwd {{.*#+}} xmm1 = xmm0[4,4,5,5,6,6,7,7] +; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm1 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero +; AVX1-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1] ; AVX1-NEXT: vpmovzxwd {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero -; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 -; AVX1-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 +; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 ; AVX1-NEXT: retq ; ; AVX2-LABEL: cmpne_knownzeros_zext_v8i16_v8i32: ; AVX2: # %bb.0: ; AVX2-NEXT: vpsrlw $15, %xmm0, %xmm0 -; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 -; AVX2-NEXT: vpcmpeqw %xmm1, %xmm0, %xmm0 -; AVX2-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 -; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0 ; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero -; AVX2-NEXT: vpbroadcastd {{.*#+}} ymm1 = [1,1,1,1,1,1,1,1] -; AVX2-NEXT: vpand %ymm1, %ymm0, %ymm0 ; AVX2-NEXT: retq %a = lshr <8 x i16> %x, %b = icmp ne <8 x i16> %a, zeroinitializer @@ -504,14 +484,8 @@ define <8 x i32> @cmpne_knownzeros_zext_v8i16_v8i32(<8 x i16> %x) { define <8 x i32> @cmpne_knownzeros_zext_v8i32_v8i32(<8 x i32> %x) { ; SSE-LABEL: cmpne_knownzeros_zext_v8i32_v8i32: ; SSE: # %bb.0: -; SSE-NEXT: psrld $31, %xmm1 ; SSE-NEXT: psrld $31, %xmm0 -; SSE-NEXT: pxor %xmm2, %xmm2 -; SSE-NEXT: pcmpeqd %xmm2, %xmm0 -; SSE-NEXT: movdqa {{.*#+}} xmm3 = [1,1,1,1] -; SSE-NEXT: pandn %xmm3, %xmm0 -; SSE-NEXT: pcmpeqd %xmm2, %xmm1 -; SSE-NEXT: pandn %xmm3, %xmm1 +; SSE-NEXT: psrld $31, %xmm1 ; SSE-NEXT: retq ; ; AVX1-LABEL: cmpne_knownzeros_zext_v8i32_v8i32: @@ -519,23 +493,12 @@ define <8 x i32> @cmpne_knownzeros_zext_v8i32_v8i32(<8 x i32> %x) { ; AVX1-NEXT: vpsrld $31, %xmm0, %xmm1 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 ; AVX1-NEXT: vpsrld $31, %xmm0, %xmm0 -; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 -; AVX1-NEXT: vpcmpeqd %xmm2, %xmm0, %xmm0 -; AVX1-NEXT: vpcmpeqd %xmm3, %xmm3, %xmm3 -; AVX1-NEXT: vpxor %xmm3, %xmm0, %xmm0 -; AVX1-NEXT: vpcmpeqd %xmm2, %xmm1, %xmm1 -; AVX1-NEXT: vpxor %xmm3, %xmm1, %xmm1 ; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 -; AVX1-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 ; AVX1-NEXT: retq ; ; AVX2-LABEL: cmpne_knownzeros_zext_v8i32_v8i32: ; AVX2: # %bb.0: ; AVX2-NEXT: vpsrld $31, %ymm0, %ymm0 -; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 -; AVX2-NEXT: vpcmpeqd %ymm1, %ymm0, %ymm0 -; AVX2-NEXT: vpbroadcastd {{.*#+}} ymm1 = [1,1,1,1,1,1,1,1] -; AVX2-NEXT: vpandn %ymm1, %ymm0, %ymm0 ; AVX2-NEXT: retq %a = lshr <8 x i32> %x, %b = icmp ne <8 x i32> %a, zeroinitializer @@ -544,46 +507,34 @@ define <8 x i32> @cmpne_knownzeros_zext_v8i32_v8i32(<8 x i32> %x) { } define <8 x i16> @cmpne_knownzeros_zext_v8i32_v8i16(<8 x i32> %x) { -; SSE-LABEL: cmpne_knownzeros_zext_v8i32_v8i16: -; SSE: # %bb.0: -; SSE-NEXT: psrld $31, %xmm0 -; SSE-NEXT: psrld $31, %xmm1 -; SSE-NEXT: pxor %xmm2, %xmm2 -; SSE-NEXT: pcmpeqd %xmm2, %xmm1 -; SSE-NEXT: pcmpeqd %xmm3, %xmm3 -; SSE-NEXT: pxor %xmm3, %xmm1 -; SSE-NEXT: pcmpeqd %xmm2, %xmm0 -; SSE-NEXT: pxor %xmm3, %xmm0 -; SSE-NEXT: packssdw %xmm1, %xmm0 -; SSE-NEXT: psrlw $15, %xmm0 -; SSE-NEXT: retq +; SSE2-LABEL: cmpne_knownzeros_zext_v8i32_v8i16: +; SSE2: # %bb.0: +; SSE2-NEXT: psrld $31, %xmm1 +; SSE2-NEXT: psrld $31, %xmm0 +; SSE2-NEXT: packuswb %xmm1, %xmm0 +; SSE2-NEXT: retq +; +; SSE42-LABEL: cmpne_knownzeros_zext_v8i32_v8i16: +; SSE42: # %bb.0: +; SSE42-NEXT: psrld $31, %xmm1 +; SSE42-NEXT: psrld $31, %xmm0 +; SSE42-NEXT: packusdw %xmm1, %xmm0 +; SSE42-NEXT: retq ; ; AVX1-LABEL: cmpne_knownzeros_zext_v8i32_v8i16: ; AVX1: # %bb.0: -; AVX1-NEXT: vpsrld $31, %xmm0, %xmm1 -; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm0 +; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 +; AVX1-NEXT: vpsrld $31, %xmm1, %xmm1 ; AVX1-NEXT: vpsrld $31, %xmm0, %xmm0 -; AVX1-NEXT: vpxor %xmm2, %xmm2, %xmm2 -; AVX1-NEXT: vpcmpeqd %xmm2, %xmm0, %xmm0 -; AVX1-NEXT: vpcmpeqd %xmm3, %xmm3, %xmm3 -; AVX1-NEXT: vpxor %xmm3, %xmm0, %xmm0 -; AVX1-NEXT: vpcmpeqd %xmm2, %xmm1, %xmm1 -; AVX1-NEXT: vpxor %xmm3, %xmm1, %xmm1 -; AVX1-NEXT: vpackssdw %xmm0, %xmm1, %xmm0 -; AVX1-NEXT: vpsrlw $15, %xmm0, %xmm0 +; AVX1-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 ; AVX1-NEXT: vzeroupper ; AVX1-NEXT: retq ; ; AVX2-LABEL: cmpne_knownzeros_zext_v8i32_v8i16: ; AVX2: # %bb.0: ; AVX2-NEXT: vpsrld $31, %ymm0, %ymm0 -; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 -; AVX2-NEXT: vpcmpeqd %ymm1, %ymm0, %ymm0 -; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 -; AVX2-NEXT: vpxor %ymm1, %ymm0, %ymm0 ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 -; AVX2-NEXT: vpackssdw %xmm1, %xmm0, %xmm0 -; AVX2-NEXT: vpsrlw $15, %xmm0, %xmm0 +; AVX2-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 ; AVX2-NEXT: vzeroupper ; AVX2-NEXT: retq %a = lshr <8 x i32> %x,