diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d5b2f3658bc..307bfa502b7 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4809,7 +4809,7 @@ SDValue DAGCombiner::visitCTPOP(SDNode *N) { EVT VT = N->getValueType(0); // fold (ctpop c1) -> c2 - if (isa(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTPOP, SDLoc(N), VT, N0); return SDValue(); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index b9eb8f0d0ff..f72bfc6ceaa 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2910,7 +2910,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, case ISD::FP_TO_UINT: case ISD::TRUNCATE: case ISD::UINT_TO_FP: - case ISD::SINT_TO_FP: { + case ISD::SINT_TO_FP: + case ISD::CTPOP: { EVT SVT = VT.getScalarType(); EVT InVT = BV->getValueType(0); EVT InSVT = InVT.getScalarType(); diff --git a/test/CodeGen/X86/vector-popcnt-128.ll b/test/CodeGen/X86/vector-popcnt-128.ll index f5d54323f26..e8fde0964f4 100644 --- a/test/CodeGen/X86/vector-popcnt-128.ll +++ b/test/CodeGen/X86/vector-popcnt-128.ll @@ -400,6 +400,62 @@ define <16 x i8> @testv16i8(<16 x i8> %in) { ret <16 x i8> %out } +define <2 x i64> @foldv2i64() { +; SSE-LABEL: foldv2i64: +; SSE: # BB#0: +; SSE-NEXT: movaps {{.*#+}} xmm0 = [1,64] +; SSE-NEXT: retq +; +; AVX-LABEL: foldv2i64: +; AVX: # BB#0: +; AVX-NEXT: vmovaps {{.*#+}} xmm0 = [1,64] +; AVX-NEXT: retq + %out = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> ) + ret <2 x i64> %out +} + +define <4 x i32> @foldv4i32() { +; SSE-LABEL: foldv4i32: +; SSE: # BB#0: +; SSE-NEXT: movaps {{.*#+}} xmm0 = [1,32,0,8] +; SSE-NEXT: retq +; +; AVX-LABEL: foldv4i32: +; AVX: # BB#0: +; AVX-NEXT: vmovaps {{.*#+}} xmm0 = [1,32,0,8] +; AVX-NEXT: retq + %out = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> ) + ret <4 x i32> %out +} + +define <8 x i16> @foldv8i16() { +; SSE-LABEL: foldv8i16: +; SSE: # BB#0: +; SSE-NEXT: movaps {{.*#+}} xmm0 = [1,16,0,8,0,3,2,3] +; SSE-NEXT: retq +; +; AVX-LABEL: foldv8i16: +; AVX: # BB#0: +; AVX-NEXT: vmovaps {{.*#+}} xmm0 = [1,16,0,8,0,3,2,3] +; AVX-NEXT: retq + %out = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> ) + ret <8 x i16> %out +} + +define <16 x i8> @foldv16i8() { +; SSE-LABEL: foldv16i8: +; SSE: # BB#0: +; SSE-NEXT: movaps {{.*#+}} xmm0 = [0,8,0,8,0,3,2,3,7,7,1,1,1,1,1,1] +; SSE-NEXT: retq +; +; AVX-LABEL: foldv16i8: +; AVX: # BB#0: +; AVX-NEXT: vmovaps {{.*#+}} xmm0 = [0,8,0,8,0,3,2,3,7,7,1,1,1,1,1,1] +; AVX-NEXT: retq + %out = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> ) + ret <16 x i8> %out +} + declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) declare <4 x i32> @llvm.ctpop.v4i32(<4 x i32>) declare <8 x i16> @llvm.ctpop.v8i16(<8 x i16>) diff --git a/test/CodeGen/X86/vector-popcnt-256.ll b/test/CodeGen/X86/vector-popcnt-256.ll index 85ad91c7c77..709565597cc 100644 --- a/test/CodeGen/X86/vector-popcnt-256.ll +++ b/test/CodeGen/X86/vector-popcnt-256.ll @@ -178,6 +178,42 @@ define <32 x i8> @testv32i8(<32 x i8> %in) { ret <32 x i8> %out } +define <4 x i64> @foldv4i64() { +; AVX-LABEL: foldv4i64: +; AVX: # BB#0: +; AVX-NEXT: vmovaps {{.*#+}} ymm0 = [1,64,0,8] +; AVX-NEXT: retq + %out = call <4 x i64> @llvm.ctpop.v4i64(<4 x i64> ) + ret <4 x i64> %out +} + +define <8 x i32> @foldv8i32() { +; AVX-LABEL: foldv8i32: +; AVX: # BB#0: +; AVX-NEXT: vmovaps {{.*#+}} ymm0 = [1,32,0,8,16,3,2,3] +; AVX-NEXT: retq + %out = call <8 x i32> @llvm.ctpop.v8i32(<8 x i32> ) + ret <8 x i32> %out +} + +define <16 x i16> @foldv16i16() { +; AVX-LABEL: foldv16i16: +; AVX: # BB#0: +; AVX-NEXT: vmovaps {{.*#+}} ymm0 = [1,16,0,8,0,3,2,3,15,7,1,1,1,1,1,1] +; AVX-NEXT: retq + %out = call <16 x i16> @llvm.ctpop.v16i16(<16 x i16> ) + ret <16 x i16> %out +} + +define <32 x i8> @foldv32i8() { +; AVX-LABEL: foldv32i8: +; AVX: # BB#0: +; AVX-NEXT: vmovaps {{.*#+}} ymm0 = [0,8,0,8,0,3,2,3,7,7,1,1,1,1,1,1,1,1,0,0,1,2,3,4,5,6,7,8,2,2,3,7] +; AVX-NEXT: retq + %out = call <32 x i8> @llvm.ctpop.v32i8(<32 x i8> ) + ret <32 x i8> %out +} + declare <4 x i64> @llvm.ctpop.v4i64(<4 x i64>) declare <8 x i32> @llvm.ctpop.v8i32(<8 x i32>) declare <16 x i16> @llvm.ctpop.v16i16(<16 x i16>)