aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-04-20 08:56:16 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-04-20 08:56:16 +0000
commit44f1f09b4e08bf6f94269c1fe4363b99ef17af50 (patch)
tree6009067276265c856d355978a1c9b57e46c32725 /lib/CodeGen/SelectionDAG/DAGCombiner.cpp
parentc313c66a88a19f6cb59f8c349fe86eb69ee68b5f (diff)
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
Diffstat (limited to 'lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp65
1 files changed, 64 insertions, 1 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 900a775f51..26448bba5b 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<SDOperand> IdxOps;
+ unsigned NumOps = RHS.getNumOperands();
+ unsigned NumElts = NumOps-2;
+ MVT::ValueType EVT = cast<VTSDNode>(RHS.getOperand(NumOps-1))->getVT();
+ for (unsigned i = 0; i != NumElts; ++i) {
+ SDOperand Elt = RHS.getOperand(i);
+ if (!isa<ConstantSDNode>(Elt))
+ return SDOperand();
+ else if (cast<ConstantSDNode>(Elt)->isAllOnesValue())
+ IdxOps.push_back(DAG.getConstant(i, EVT));
+ else if (cast<ConstantSDNode>(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<SDOperand> Ops;
+ LHS = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, LHS, NumEltsNode, EVTNode);
+ Ops.push_back(LHS);
+ AddToWorkList(LHS.Val);
+ std::vector<SDOperand> 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 &&