Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -11598,23 +11598,21 @@ 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; - for (unsigned i = 0; i != NumElts; ++i) { - Ops.push_back(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; + SmallVector Ops; + for (unsigned i = 0; i != NumElts; ++i) { + Ops.push_back(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; } } Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1553,24 +1553,20 @@ 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; - for (unsigned i = 0; i != NElts; ++i) - Ops.push_back(Splatted); - - SDValue NewBV = - getNode(ISD::BUILD_VECTOR, dl, BV->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 (BV->getValueType(0) != VT) - NewBV = getNode(ISD::BITCAST, dl, VT, NewBV); - return NewBV; - } + const SDValue &Splatted = BV->getOperand(MaskVec[0]); + SmallVector Ops; + for (unsigned i = 0; i != NElts; ++i) + Ops.push_back(Splatted); + + SDValue NewBV =getNode(ISD::BUILD_VECTOR, dl, BV->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 (BV->getValueType(0) != VT) + NewBV = getNode(ISD::BITCAST, dl, VT, NewBV); + return NewBV; } } } Index: test/CodeGen/ARM/vdup.ll =================================================================== --- test/CodeGen/ARM/vdup.ll +++ test/CodeGen/ARM/vdup.ll @@ -347,17 +347,17 @@ 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> Index: test/CodeGen/X86/vector-shuffle-256-v4.ll =================================================================== --- test/CodeGen/X86/vector-shuffle-256-v4.ll +++ test/CodeGen/X86/vector-shuffle-256-v4.ll @@ -847,8 +847,7 @@ define <4 x i64> @splat_mem_v4i64(i64* %ptr) { ; AVX1-LABEL: splat_mem_v4i64: ; AVX1: # BB#0: -; AVX1-NEXT: vmovddup (%rdi), %xmm0 -; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 +; AVX1-NEXT: vbroadcastsd (%rdi), %ymm0 ; AVX1-NEXT: retq ; ; AVX2-LABEL: splat_mem_v4i64: