Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -15489,6 +15489,24 @@ return SDValue(); } + // If both inputs are splats of the same value then we can safely merge this + // to a single BUILD_VECTOR with only the common undef elements. + auto *BV0 = dyn_cast(N0); + auto *BV1 = dyn_cast(N1); + if (BV0 && BV1) { + BitVector Undefs0, Undefs1; + SDValue Splat0 = BV0->getSplatValue(&Undefs0); + SDValue Splat1 = BV1->getSplatValue(&Undefs1); + if (Splat0 && Splat0 == Splat1) { + Undefs0 &= Undefs1; + SmallVector Ops(NumElts, Splat0); + for (unsigned i = 0; i != NumElts; ++i) + if (Undefs0[0]) + Ops[i] = DAG.getUNDEF(Splat0.getValueType()); + return DAG.getBuildVector(VT, SDLoc(SVN), Ops); + } + } + SmallVector Ops; SmallSet DuplicateOps; for (int M : SVN->getMask()) { Index: test/CodeGen/X86/avx-vbroadcast.ll =================================================================== --- test/CodeGen/X86/avx-vbroadcast.ll +++ test/CodeGen/X86/avx-vbroadcast.ll @@ -853,14 +853,12 @@ ; X32-LABEL: broadcast_shuffle1032: ; X32: ## BB#0: ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax -; X32-NEXT: vmovddup {{.*#+}} xmm0 = mem[0,0] -; X32-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 +; X32-NEXT: vbroadcastsd (%eax), %ymm0 ; X32-NEXT: retl ; ; X64-LABEL: broadcast_shuffle1032: ; X64: ## BB#0: -; X64-NEXT: vmovddup {{.*#+}} xmm0 = mem[0,0] -; X64-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 +; X64-NEXT: vbroadcastsd (%rdi), %ymm0 ; X64-NEXT: retq %1 = load double, double* %p %2 = insertelement <2 x double> undef, double %1, i32 1