diff options
author | Craig Topper <craig.topper@gmail.com> | 2017-02-04 23:26:39 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2017-02-04 23:26:39 +0000 |
commit | 42b83f8d6e44225562451cf428cea3d7af2a69db (patch) | |
tree | e18e887f4b6cc6c731269f4d95eea417c055b883 /llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
parent | 04dce84ead73732dc7a88eab9fbee5b60a9bcd1a (diff) | |
download | bcm5719-llvm-42b83f8d6e44225562451cf428cea3d7af2a69db.tar.gz bcm5719-llvm-42b83f8d6e44225562451cf428cea3d7af2a69db.zip |
[DAGCombiner] Canonicalize the order of a chain of INSERT_SUBVECTORs.
Based on similar code for INSERT_VECTOR_ELT.
llvm-svn: 294110
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d38a9fca019..aad07d8ae3c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -14547,15 +14547,35 @@ SDValue DAGCombiner::visitINSERT_SUBVECTOR(SDNode *N) { return DAG.getNode(ISD::INSERT_SUBVECTOR, SDLoc(N), VT, N0.getOperand(0), N1, N2); + if (!isa<ConstantSDNode>(N2)) + return SDValue(); + + unsigned InsIdx = cast<ConstantSDNode>(N2)->getZExtValue(); + + // Canonicalize insert_subvector dag nodes. + // Example: + // (insert_subvector (insert_subvector A, Idx0), Idx1) + // -> (insert_subvector (insert_subvector A, Idx1), Idx0) + if (N0.getOpcode() == ISD::INSERT_SUBVECTOR && N0.hasOneUse() && + N1.getValueType() == N0.getOperand(1).getValueType() && + isa<ConstantSDNode>(N0.getOperand(2))) { + unsigned OtherIdx = cast<ConstantSDNode>(N0.getOperand(2))->getZExtValue(); + if (InsIdx < OtherIdx) { + // Swap nodes. + SDValue NewOp = DAG.getNode(ISD::INSERT_SUBVECTOR, SDLoc(N), VT, + N0.getOperand(0), N1, N2); + AddToWorklist(NewOp.getNode()); + return DAG.getNode(ISD::INSERT_SUBVECTOR, SDLoc(N0.getNode()), + VT, NewOp, N0.getOperand(1), N0.getOperand(2)); + } + } + if (N0.getValueType() != N1.getValueType()) return SDValue(); // If the input vector is a concatenation, and the insert replaces // one of the halves, we can optimize into a single concat_vectors. - if (N0.getOpcode() == ISD::CONCAT_VECTORS && N0->getNumOperands() == 2 && - isa<ConstantSDNode>(N2)) { - unsigned InsIdx = cast<ConstantSDNode>(N2)->getZExtValue(); - + if (N0.getOpcode() == ISD::CONCAT_VECTORS && N0->getNumOperands() == 2) { // Lower half: fold (insert_subvector (concat_vectors X, Y), Z) -> // (concat_vectors Z, Y) if (InsIdx == 0) |