From 44f1f09b4e08bf6f94269c1fe4363b99ef17af50 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 20 Apr 2006 08:56:16 +0000 Subject: [PATCH] Turn a VAND into a VECTOR_SHUFFLE is applicable. DAG combiner can turn a VAND V, <-1, 0, -1, -1>, i.e. vector clear elements, into a vector shuffle with a zero vector. It only does so when TLI tells it the xform is profitable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27874 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 65 +++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 900a775f510..26448bba5b8 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -218,6 +218,7 @@ namespace { SDOperand visitVECTOR_SHUFFLE(SDNode *N); SDOperand visitVVECTOR_SHUFFLE(SDNode *N); + SDOperand XformToShuffleWithZero(SDNode *N); SDOperand ReassociateOps(unsigned Opc, SDOperand LHS, SDOperand RHS); bool SimplifySelectOps(SDNode *SELECT, SDOperand LHS, SDOperand RHS); @@ -2774,6 +2775,66 @@ SDOperand DAGCombiner::visitVVECTOR_SHUFFLE(SDNode *N) { return SDOperand(); } +/// XformToShuffleWithZero - Returns a vector_shuffle if it able to transform +/// a VAND to a vector_shuffle with the destination vector and a zero vector. +/// e.g. VAND V, <0xffffffff, 0, 0xffffffff, 0>. ==> +/// vector_shuffle V, Zero, <0, 4, 2, 4> +SDOperand DAGCombiner::XformToShuffleWithZero(SDNode *N) { + SDOperand LHS = N->getOperand(0); + SDOperand RHS = N->getOperand(1); + if (N->getOpcode() == ISD::VAND) { + SDOperand DstVecSize = *(LHS.Val->op_end()-2); + SDOperand DstVecEVT = *(LHS.Val->op_end()-1); + if (RHS.getOpcode() == ISD::VBIT_CONVERT) + RHS = RHS.getOperand(0); + if (RHS.getOpcode() == ISD::VBUILD_VECTOR) { + std::vector IdxOps; + unsigned NumOps = RHS.getNumOperands(); + unsigned NumElts = NumOps-2; + MVT::ValueType EVT = cast(RHS.getOperand(NumOps-1))->getVT(); + for (unsigned i = 0; i != NumElts; ++i) { + SDOperand Elt = RHS.getOperand(i); + if (!isa(Elt)) + return SDOperand(); + else if (cast(Elt)->isAllOnesValue()) + IdxOps.push_back(DAG.getConstant(i, EVT)); + else if (cast(Elt)->isNullValue()) + IdxOps.push_back(DAG.getConstant(NumElts, EVT)); + else + return SDOperand(); + } + + // Let's see if the target supports this vector_shuffle. + if (!TLI.isVectorClearMaskLegal(IdxOps, EVT, DAG)) + return SDOperand(); + + // Return the new VVECTOR_SHUFFLE node. + SDOperand NumEltsNode = DAG.getConstant(NumElts, MVT::i32); + SDOperand EVTNode = DAG.getValueType(EVT); + std::vector Ops; + LHS = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, LHS, NumEltsNode, EVTNode); + Ops.push_back(LHS); + AddToWorkList(LHS.Val); + std::vector ZeroOps(NumElts, DAG.getConstant(0, EVT)); + ZeroOps.push_back(NumEltsNode); + ZeroOps.push_back(EVTNode); + Ops.push_back(DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, ZeroOps)); + IdxOps.push_back(NumEltsNode); + IdxOps.push_back(EVTNode); + Ops.push_back(DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, IdxOps)); + Ops.push_back(NumEltsNode); + Ops.push_back(EVTNode); + SDOperand Result = DAG.getNode(ISD::VVECTOR_SHUFFLE, MVT::Vector, Ops); + if (NumEltsNode != DstVecSize || EVTNode != DstVecEVT) { + Result = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, Result, + DstVecSize, DstVecEVT); + } + return Result; + } + } + return SDOperand(); +} + /// visitVBinOp - Visit a binary vector operation, like VADD. IntOp indicates /// the scalar operation of the vop if it is operating on an integer vector /// (e.g. ADD) and FPOp indicates the FP version (e.g. FADD). @@ -2783,7 +2844,9 @@ SDOperand DAGCombiner::visitVBinOp(SDNode *N, ISD::NodeType IntOp, ISD::NodeType ScalarOp = MVT::isInteger(EltType) ? IntOp : FPOp; SDOperand LHS = N->getOperand(0); SDOperand RHS = N->getOperand(1); - + SDOperand Shuffle = XformToShuffleWithZero(N); + if (Shuffle.Val) return Shuffle; + // If the LHS and RHS are VBUILD_VECTOR nodes, see if we can constant fold // this operation. if (LHS.getOpcode() == ISD::VBUILD_VECTOR && -- 2.34.1