diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index e41d459f39d..15baf14f2d9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1496,6 +1496,11 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, N1 = getUNDEF(VT); commuteShuffle(N1, N2, MaskVec); } + // Reset our undef status after accounting for the mask. + N2Undef = N2.getOpcode() == ISD::UNDEF; + // Re-check whether both sides ended up undef. + if (N1.getOpcode() == ISD::UNDEF && N2Undef) + return getUNDEF(VT); // If Identity shuffle return that node. bool Identity = true; @@ -1506,11 +1511,36 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, return N1; // Shuffling a constant splat doesn't change the result. - bool SplatHasUndefs; - if (N2Undef && N1.getOpcode() == ISD::BUILD_VECTOR) - if (cast(N1)->getConstantSplatNode(SplatHasUndefs) && - !SplatHasUndefs) - return N1; + if (N2Undef) { + SDValue V = N1; + + // Look through any bitcasts. We check that these don't change the number + // (and size) of elements and just changes their types. + while (V.getOpcode() == ISD::BITCAST) + V = V->getOperand(0); + + // A splat should always show up as a build vector node. + if (auto *BV = dyn_cast(V)) { + bool SplatHasUndefs; + SDValue Splat = BV->getSplatValue(SplatHasUndefs); + // If this is a splat of an undef, shuffling it is also undef. + if (Splat && Splat.getOpcode() == ISD::UNDEF) + return getUNDEF(VT); + + // We only have a splat which can skip shuffles if there is a splatted + // value and no undef lanes rearranged by the shuffle. + if (Splat && !SplatHasUndefs) { + // Splat of , return , provided that the + // number of elements match or the value splatted is a zero constant. + if (V.getValueType().getVectorNumElements() == + VT.getVectorNumElements()) + return N1; + if (auto *C = dyn_cast(Splat)) + if (C->isNullValue()) + return N1; + } + } + } FoldingSetNodeID ID; SDValue Ops[2] = { N1, N2 }; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 39537e358b9..306a659c983 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -7924,47 +7924,6 @@ static SDValue lowerVectorShuffle(SDValue Op, const X86Subtarget *Subtarget, return DAG.getVectorShuffle(VT, dl, V1, V2, NewMask); } - // Check for a shuffle of a splat, and return just the splat. While DAG - // combining will do a similar transformation, this shows up with the - // internally created shuffles and so we handle it specially here as we won't - // have another chance to DAG-combine the generic shuffle instructions. - if (V2IsUndef) { - SDValue V = V1; - - // Look through any bitcasts. These can't change the size, just the number - // of elements which we check later. - while (V.getOpcode() == ISD::BITCAST) - V = V->getOperand(0); - - // A splat should always show up as a build vector node. - if (V.getOpcode() == ISD::BUILD_VECTOR) { - SDValue Base; - bool AllSame = true; - for (unsigned i = 0; i != V->getNumOperands(); ++i) - if (V->getOperand(i).getOpcode() != ISD::UNDEF) { - Base = V->getOperand(i); - break; - } - // Splat of , return - if (!Base) - return V1; - for (unsigned i = 0; i != V->getNumOperands(); ++i) - if (V->getOperand(i) != Base) { - AllSame = false; - break; - } - // Splat of , return , provided that the - // number of elements match or the value splatted is a zero constant. - if (AllSame) { - if (V.getValueType().getVectorNumElements() == (unsigned)NumElements) - return V1; - if (auto *C = dyn_cast(Base)) - if (C->isNullValue()) - return V1; - } - } - } - // For integer vector shuffles, try to collapse them into a shuffle of fewer // lanes but wider integers. We cap this to not form integers larger than i64 // but it might be interesting to form i128 integers to handle flipping the diff --git a/test/CodeGen/X86/widen_cast-6.ll b/test/CodeGen/X86/widen_cast-6.ll index 7c06ad8ca66..46d8dd787a3 100644 --- a/test/CodeGen/X86/widen_cast-6.ll +++ b/test/CodeGen/X86/widen_cast-6.ll @@ -1,9 +1,13 @@ ; RUN: llc < %s -march=x86 -mattr=+sse4.1 | FileCheck %s -; CHECK: movd ; Test bit convert that requires widening in the operand. define i32 @return_v2hi() nounwind { +; CHECK-LABEL: @return_v2hi +; CHECK: pushl +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: popl +; CHECK-NEXT: ret entry: %retval12 = bitcast <2 x i16> zeroinitializer to i32 ; [#uses=1] ret i32 %retval12