summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2017-08-28 15:28:33 +0000
committerCraig Topper <craig.topper@intel.com>2017-08-28 15:28:33 +0000
commit029a21dfdc9d0930beaf31dafaf5e69ba04443d8 (patch)
tree44aefd5b5191f5e1e6bb71b4c533b299e03fd0ee /llvm/lib/CodeGen/SelectionDAG
parent476f21d87ec1d512a0143dd37a62d08ab71dc5b5 (diff)
downloadbcm5719-llvm-029a21dfdc9d0930beaf31dafaf5e69ba04443d8.tar.gz
bcm5719-llvm-029a21dfdc9d0930beaf31dafaf5e69ba04443d8.zip
[DAGCombiner] Teach visitEXTRACT_SUBVECTOR to turn extracts of BUILD_VECTOR into smaller BUILD_VECTORs
Only do this before operations are legalized of BUILD_VECTOR is Legal for the target. Differential Revision: https://reviews.llvm.org/D37186 llvm-svn: 311892
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index df38ef423fa..306fd6f4984 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -15157,6 +15157,29 @@ SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode* N) {
// Skip bitcasting
V = peekThroughBitcast(V);
+ // If the input is a build vector. Try to make a smaller build vector.
+ if (V->getOpcode() == ISD::BUILD_VECTOR) {
+ if (auto *Idx = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
+ EVT InVT = V->getValueType(0);
+ unsigned NumElems = NVT.getSizeInBits() / InVT.getScalarSizeInBits();
+ if (NumElems > 0) {
+ EVT ExtractVT = EVT::getVectorVT(*DAG.getContext(),
+ InVT.getVectorElementType(), NumElems);
+ if (!LegalOperations ||
+ TLI.isOperationLegal(ISD::BUILD_VECTOR, ExtractVT)) {
+ unsigned IdxVal = Idx->getZExtValue() * NVT.getScalarSizeInBits() /
+ InVT.getScalarSizeInBits();
+
+ // Extract the pieces from the original build_vector.
+ SDValue BuildVec = DAG.getBuildVector(ExtractVT, SDLoc(N),
+ makeArrayRef(V->op_begin() + IdxVal,
+ NumElems));
+ return DAG.getBitcast(NVT, BuildVec);
+ }
+ }
+ }
+ }
+
if (V->getOpcode() == ISD::INSERT_SUBVECTOR) {
// Handle only simple case where vector being inserted and vector
// being extracted are of same size.
OpenPOWER on IntegriCloud