summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorMichael Liao <michael.liao@intel.com>2012-10-17 20:48:33 +0000
committerMichael Liao <michael.liao@intel.com>2012-10-17 20:48:33 +0000
commit7a442c8031f717ff59908c795eb64acd7cbefb73 (patch)
treec7e5204aea11788c19a2345159054c81f28a6a20 /llvm
parent7a9f0c09de8350679beb54a9c7aebebdd995ca3a (diff)
downloadbcm5719-llvm-7a442c8031f717ff59908c795eb64acd7cbefb73.tar.gz
bcm5719-llvm-7a442c8031f717ff59908c795eb64acd7cbefb73.zip
Teach DAG combine to fold (extract_subvec (concat v1, ..) i) to v_i
- If the extracted vector has the same type of all vectored being concatenated together, it should be simplified directly into v_i, where i is the index of the element being extracted. llvm-svn: 166125
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp19
-rw-r--r--llvm/test/CodeGen/X86/extract-concat.ll17
2 files changed, 34 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 6e4a772a89d..4ac6d1b5163 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -8610,8 +8610,8 @@ SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode* N) {
return SDValue();
// Only handle cases where both indexes are constants with the same type.
- ConstantSDNode *InsIdx = dyn_cast<ConstantSDNode>(N->getOperand(1));
- ConstantSDNode *ExtIdx = dyn_cast<ConstantSDNode>(V->getOperand(2));
+ ConstantSDNode *ExtIdx = dyn_cast<ConstantSDNode>(N->getOperand(1));
+ ConstantSDNode *InsIdx = dyn_cast<ConstantSDNode>(V->getOperand(2));
if (InsIdx && ExtIdx &&
InsIdx->getValueType(0).getSizeInBits() <= 64 &&
@@ -8628,6 +8628,21 @@ SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode* N) {
}
}
+ if (V->getOpcode() == ISD::CONCAT_VECTORS) {
+ // Combine:
+ // (extract_subvec (concat V1, V2, ...), i)
+ // Into:
+ // Vi if possible
+ for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i)
+ if (V->getOperand(i).getValueType() != NVT)
+ return SDValue();
+ unsigned Idx = dyn_cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
+ unsigned NumElems = NVT.getVectorNumElements();
+ assert((Idx % NumElems) == 0 &&
+ "IDX in concat is not a multiple of the result vector length.");
+ return V->getOperand(Idx / NumElems);
+ }
+
return SDValue();
}
diff --git a/llvm/test/CodeGen/X86/extract-concat.ll b/llvm/test/CodeGen/X86/extract-concat.ll
new file mode 100644
index 00000000000..5c8d20a651d
--- /dev/null
+++ b/llvm/test/CodeGen/X86/extract-concat.ll
@@ -0,0 +1,17 @@
+; RUN: llc < %s -mcpu=corei7 -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
+
+define void @foo(<4 x float> %in, <4 x i8>* %out) {
+ %t0 = fptoui <4 x float> %in to <4 x i32>
+ %t1 = trunc <4 x i32> %t0 to <4 x i16>
+ %t2 = shufflevector <4 x i16> %t1, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+ %t3 = trunc <8 x i16> %t2 to <8 x i8>
+ %t4 = shufflevector <8 x i8> %t3, <8 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %t5 = insertelement <4 x i8> %t4, i8 -1, i32 3
+ store <4 x i8> %t5, <4 x i8>* %out
+ ret void
+; CHECK: foo
+; CHECK: cvttps2dq
+; CHECK-NOT: pextrd
+; CHECK: pshufb
+; CHECK: ret
+}
OpenPOWER on IntegriCloud