Changes in directory llvm/lib/Target/X86:
X86ISelLowering.cpp updated: 1.403 -> 1.404 --- Log message: Fix a bogus check that prevented folding VECTOR_SHUFFLE to UNDEF; add an optimization to fold VECTOR_SHUFFLE to a zero vector. --- Diffs of the changes: (+61 -24) X86ISelLowering.cpp | 85 +++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 61 insertions(+), 24 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.403 llvm/lib/Target/X86/X86ISelLowering.cpp:1.404 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.403 Thu May 17 12:13:13 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu May 17 13:45:50 2007 @@ -1630,7 +1630,7 @@ return ::isSHUFPMask(N->op_begin(), N->getNumOperands()); } -/// isCommutedSHUFP - Returns true if the shuffle mask is except +/// isCommutedSHUFP - Returns true if the shuffle mask is exactly /// the reverse of what x86 shuffles want. x86 shuffles requires the lower /// half elements to come from vector 1 (which would equal the dest.) and /// the upper half to come from vector 2. @@ -2188,7 +2188,7 @@ /// isUndefShuffle - Returns true if N is a VECTOR_SHUFFLE that can be resolved /// to an undef. static bool isUndefShuffle(SDNode *N) { - if (N->getOpcode() != ISD::BUILD_VECTOR) + if (N->getOpcode() != ISD::VECTOR_SHUFFLE) return false; SDOperand V1 = N->getOperand(0); @@ -2208,6 +2208,61 @@ return true; } +/// isZeroNode - Returns true if Elt is a constant zero or a floating point +/// constant +0.0. +static inline bool isZeroNode(SDOperand Elt) { + return ((isa<ConstantSDNode>(Elt) && + cast<ConstantSDNode>(Elt)->getValue() == 0) || + (isa<ConstantFPSDNode>(Elt) && + cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0))); +} + +/// isZeroShuffle - Returns true if N is a VECTOR_SHUFFLE that can be resolved +/// to an zero vector. +static bool isZeroShuffle(SDNode *N) { + if (N->getOpcode() != ISD::VECTOR_SHUFFLE) + return false; + + SDOperand V1 = N->getOperand(0); + SDOperand V2 = N->getOperand(1); + SDOperand Mask = N->getOperand(2); + unsigned NumElems = Mask.getNumOperands(); + for (unsigned i = 0; i != NumElems; ++i) { + SDOperand Arg = Mask.getOperand(i); + if (Arg.getOpcode() != ISD::UNDEF) { + unsigned Idx = cast<ConstantSDNode>(Arg)->getValue(); + if (Idx < NumElems) { + unsigned Opc = V1.Val->getOpcode(); + if (Opc == ISD::UNDEF) + continue; + if (Opc != ISD::BUILD_VECTOR || + !isZeroNode(V1.Val->getOperand(Idx))) + return false; + } else if (Idx >= NumElems) { + unsigned Opc = V2.Val->getOpcode(); + if (Opc == ISD::UNDEF) + continue; + if (Opc != ISD::BUILD_VECTOR || + !isZeroNode(V2.Val->getOperand(Idx - NumElems))) + return false; + } + } + } + return true; +} + +/// getZeroVector - Returns a vector of specified type with all zero elements. +/// +static SDOperand getZeroVector(MVT::ValueType VT, SelectionDAG &DAG) { + assert(MVT::isVector(VT) && "Expected a vector type"); + unsigned NumElems = getVectorNumElements(VT); + MVT::ValueType EVT = MVT::getVectorBaseType(VT); + bool isFP = MVT::isFloatingPoint(EVT); + SDOperand Zero = isFP ? DAG.getConstantFP(0.0, EVT) : DAG.getConstant(0, EVT); + SmallVector<SDOperand, 8> ZeroVec(NumElems, Zero); + return DAG.getNode(ISD::BUILD_VECTOR, VT, &ZeroVec[0], ZeroVec.size()); +} + /// NormalizeMask - V2 is a splat, modify the mask (if needed) so all elements /// that point to V2 points to its first element. static SDOperand NormalizeMask(SDOperand Mask, SelectionDAG &DAG) { @@ -2274,18 +2329,6 @@ return DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size()); } -/// getZeroVector - Returns a vector of specified type with all zero elements. -/// -static SDOperand getZeroVector(MVT::ValueType VT, SelectionDAG &DAG) { - assert(MVT::isVector(VT) && "Expected a vector type"); - unsigned NumElems = getVectorNumElements(VT); - MVT::ValueType EVT = MVT::getVectorBaseType(VT); - bool isFP = MVT::isFloatingPoint(EVT); - SDOperand Zero = isFP ? DAG.getConstantFP(0.0, EVT) : DAG.getConstant(0, EVT); - SmallVector<SDOperand, 8> ZeroVec(NumElems, Zero); - return DAG.getNode(ISD::BUILD_VECTOR, VT, &ZeroVec[0], ZeroVec.size()); -} - /// PromoteSplat - Promote a splat of v8i16 or v16i8 to v4i32. /// static SDOperand PromoteSplat(SDOperand Op, SelectionDAG &DAG) { @@ -2307,17 +2350,8 @@ return DAG.getNode(ISD::BIT_CONVERT, VT, Shuffle); } -/// isZeroNode - Returns true if Elt is a constant zero or a floating point -/// constant +0.0. -static inline bool isZeroNode(SDOperand Elt) { - return ((isa<ConstantSDNode>(Elt) && - cast<ConstantSDNode>(Elt)->getValue() == 0) || - (isa<ConstantFPSDNode>(Elt) && - cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0))); -} - /// getShuffleVectorZeroOrUndef - Return a vector_shuffle of the specified -/// vector and zero or undef vector. +/// vector of zero or undef vector. static SDOperand getShuffleVectorZeroOrUndef(SDOperand V2, MVT::ValueType VT, unsigned NumElems, unsigned Idx, bool isZero, SelectionDAG &DAG) { @@ -2584,6 +2618,9 @@ if (isUndefShuffle(Op.Val)) return DAG.getNode(ISD::UNDEF, VT); + if (isZeroShuffle(Op.Val)) + return getZeroVector(VT, DAG); + if (isSplatMask(PermMask.Val)) { if (NumElems <= 4) return Op; // Promote it to a v4i32 splat. _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits