diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 92164e92543..69efae738af 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -11749,20 +11749,17 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { if (AllSame) return N0; - // If the splatted element is a constant, just build the vector out of - // constants directly. + // Canonicalize any other splat as a build_vector. const SDValue &Splatted = V->getOperand(SVN->getSplatIndex()); - if (isa(Splatted) || isa(Splatted)) { - SmallVector Ops(NumElts, Splatted); - SDValue NewBV = DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), - V->getValueType(0), Ops); + SmallVector Ops(NumElts, Splatted); + SDValue NewBV = DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), + V->getValueType(0), Ops); - // We may have jumped through bitcasts, so the type of the - // BUILD_VECTOR may not match the type of the shuffle. - if (V->getValueType(0) != VT) - NewBV = DAG.getNode(ISD::BITCAST, SDLoc(N), VT, NewBV); - return NewBV; - } + // We may have jumped through bitcasts, so the type of the + // BUILD_VECTOR may not match the type of the shuffle. + if (V->getValueType(0) != VT) + NewBV = DAG.getNode(ISD::BITCAST, SDLoc(N), VT, NewBV); + return NewBV; } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 1e0e196389d..9466f4dd060 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1581,22 +1581,19 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, return N1; } - // If the shuffle itself creates a constant splat, build the vector - // directly. + // If the shuffle itself creates a splat, build the vector directly. if (AllSame && SameNumElts) { - const SDValue &Splatted = BV->getOperand(MaskVec[0]); - if (isa(Splatted) || isa(Splatted)) { - SmallVector Ops(NElts, Splatted); + const SDValue &Splatted = BV->getOperand(MaskVec[0]); + SmallVector Ops(NElts, Splatted); - SDValue NewBV = - getNode(ISD::BUILD_VECTOR, dl, BV->getValueType(0), Ops); + EVT BuildVT = BV->getValueType(0); + SDValue NewBV = getNode(ISD::BUILD_VECTOR, dl, BuildVT, Ops); - // We may have jumped through bitcasts, so the type of the - // BUILD_VECTOR may not match the type of the shuffle. - if (BV->getValueType(0) != VT) - NewBV = getNode(ISD::BITCAST, dl, VT, NewBV); - return NewBV; - } + // We may have jumped through bitcasts, so the type of the + // BUILD_VECTOR may not match the type of the shuffle. + if (BuildVT != VT) + NewBV = getNode(ISD::BITCAST, dl, VT, NewBV); + return NewBV; } } } diff --git a/test/CodeGen/ARM/vdup.ll b/test/CodeGen/ARM/vdup.ll index 89f355c6875..6f8b3dda9cd 100644 --- a/test/CodeGen/ARM/vdup.ll +++ b/test/CodeGen/ARM/vdup.ll @@ -347,17 +347,17 @@ define <2 x float> @check_spr_splat2(<2 x float> %p, i16 %q) { define <4 x float> @check_spr_splat4(<4 x float> %p, i16 %q) { ;CHECK-LABEL: check_spr_splat4: -;CHECK: vdup.32 q +;CHECK: vld1.16 %conv = sitofp i16 %q to float %splat.splatinsert = insertelement <4 x float> undef, float %conv, i32 0 %splat.splat = shufflevector <4 x float> %splat.splatinsert, <4 x float> undef, <4 x i32> zeroinitializer %sub = fsub <4 x float> %splat.splat, %p ret <4 x float> %sub } - +; Same codegen as above test; scalar is splatted using vld1, so shuffle index is irrelevant. define <4 x float> @check_spr_splat4_lane1(<4 x float> %p, i16 %q) { ;CHECK-LABEL: check_spr_splat4_lane1: -;CHECK: vdup.32 q{{.*}}, d{{.*}}[1] +;CHECK: vld1.16 %conv = sitofp i16 %q to float %splat.splatinsert = insertelement <4 x float> undef, float %conv, i32 1 %splat.splat = shufflevector <4 x float> %splat.splatinsert, <4 x float> undef, <4 x i32> diff --git a/test/CodeGen/X86/vector-shuffle-256-v4.ll b/test/CodeGen/X86/vector-shuffle-256-v4.ll index 7b8c1d62fc4..bb08b941566 100644 --- a/test/CodeGen/X86/vector-shuffle-256-v4.ll +++ b/test/CodeGen/X86/vector-shuffle-256-v4.ll @@ -885,8 +885,7 @@ define <4 x double> @splat_mem_v4f64(double* %ptr) { define <4 x i64> @splat_mem_v4i64(i64* %ptr) { ; AVX1-LABEL: splat_mem_v4i64: ; AVX1: # BB#0: -; AVX1-NEXT: vmovddup {{.*#+}} xmm0 = mem[0,0] -; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 +; AVX1-NEXT: vbroadcastsd (%rdi), %ymm0 ; AVX1-NEXT: retq ; ; AVX2-LABEL: splat_mem_v4i64: