diff options
author | Chris Lattner <sabre@nondot.org> | 2006-03-19 01:27:56 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-03-19 01:27:56 +0000 |
commit | ca2424423416032dc95dae4c106a5cf99795e589 (patch) | |
tree | c10f9519f4179b5a18fa9904eb62b41de2446a81 | |
parent | 152c72d88a3c3062a5dd4823efa5d258c195520b (diff) |
fold insertelement(buildvector) -> buildvector if the inserted element # is
a constant. This implements test_constant_insert in CodeGen/Generic/vector.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26851 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 6152d228cc..8a0f488fde 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -209,6 +209,8 @@ namespace { SDOperand visitBR_CC(SDNode *N); SDOperand visitLOAD(SDNode *N); SDOperand visitSTORE(SDNode *N); + SDOperand visitINSERT_VECTOR_ELT(SDNode *N); + SDOperand visitVINSERT_VECTOR_ELT(SDNode *N); SDOperand ReassociateOps(unsigned Opc, SDOperand LHS, SDOperand RHS); @@ -640,6 +642,8 @@ SDOperand DAGCombiner::visit(SDNode *N) { case ISD::BR_CC: return visitBR_CC(N); case ISD::LOAD: return visitLOAD(N); case ISD::STORE: return visitSTORE(N); + case ISD::INSERT_VECTOR_ELT: return visitINSERT_VECTOR_ELT(N); + case ISD::VINSERT_VECTOR_ELT: return visitVINSERT_VECTOR_ELT(N); } return SDOperand(); } @@ -2290,6 +2294,44 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) { return SDOperand(); } +SDOperand DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) { + SDOperand InVec = N->getOperand(0); + SDOperand InVal = N->getOperand(1); + SDOperand EltNo = N->getOperand(2); + + // If the invec is a BUILD_VECTOR and if EltNo is a constant, build a new + // vector with the inserted element. + if (InVec.getOpcode() == ISD::BUILD_VECTOR && isa<ConstantSDNode>(EltNo)) { + unsigned Elt = cast<ConstantSDNode>(EltNo)->getValue(); + std::vector<SDOperand> Ops(InVec.Val->op_begin(), InVec.Val->op_end()); + if (Elt < Ops.size()) + Ops[Elt] = InVal; + return DAG.getNode(ISD::BUILD_VECTOR, InVec.getValueType(), Ops); + } + + return SDOperand(); +} + +SDOperand DAGCombiner::visitVINSERT_VECTOR_ELT(SDNode *N) { + SDOperand InVec = N->getOperand(0); + SDOperand InVal = N->getOperand(1); + SDOperand EltNo = N->getOperand(2); + SDOperand NumElts = N->getOperand(3); + SDOperand EltType = N->getOperand(4); + + // If the invec is a VBUILD_VECTOR and if EltNo is a constant, build a new + // vector with the inserted element. + if (InVec.getOpcode() == ISD::VBUILD_VECTOR && isa<ConstantSDNode>(EltNo)) { + unsigned Elt = cast<ConstantSDNode>(EltNo)->getValue(); + std::vector<SDOperand> Ops(InVec.Val->op_begin(), InVec.Val->op_end()); + if (Elt < Ops.size()-2) + Ops[Elt] = InVal; + return DAG.getNode(ISD::VBUILD_VECTOR, InVec.getValueType(), Ops); + } + + return SDOperand(); +} + SDOperand DAGCombiner::SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2){ assert(N0.getOpcode() ==ISD::SETCC && "First argument must be a SetCC node!"); |