From: Bruno Cardoso Lopes Date: Tue, 20 Sep 2011 23:19:33 +0000 (+0000) Subject: Add a DAGCombine for subvector extracts to remove useless chains of X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e97190fdf875843e8161a942f2046fd3ef81330f;p=oota-llvm.git Add a DAGCombine for subvector extracts to remove useless chains of subvector inserts and extracts. Initial patch by Rackover, Zvi with some tweak done by me. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140204 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index c47dd0964e4..1b73b0711ea 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -216,6 +216,7 @@ namespace { SDValue visitEXTRACT_VECTOR_ELT(SDNode *N); SDValue visitBUILD_VECTOR(SDNode *N); SDValue visitCONCAT_VECTORS(SDNode *N); + SDValue visitEXTRACT_SUBVECTOR(SDNode *N); SDValue visitVECTOR_SHUFFLE(SDNode *N); SDValue visitMEMBARRIER(SDNode *N); @@ -1105,6 +1106,7 @@ SDValue DAGCombiner::visit(SDNode *N) { case ISD::EXTRACT_VECTOR_ELT: return visitEXTRACT_VECTOR_ELT(N); case ISD::BUILD_VECTOR: return visitBUILD_VECTOR(N); case ISD::CONCAT_VECTORS: return visitCONCAT_VECTORS(N); + case ISD::EXTRACT_SUBVECTOR: return visitEXTRACT_SUBVECTOR(N); case ISD::VECTOR_SHUFFLE: return visitVECTOR_SHUFFLE(N); case ISD::MEMBARRIER: return visitMEMBARRIER(N); } @@ -7031,6 +7033,36 @@ SDValue DAGCombiner::visitCONCAT_VECTORS(SDNode *N) { return SDValue(); } +SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode* N) { + EVT NVT = N->getValueType(0); + SDValue V = N->getOperand(0); + + if (V->getOpcode() == ISD::INSERT_SUBVECTOR) { + // Handle only simple case where vector being inserted and vector + // being extracted are of same type, and are half size of larger vectors. + EVT BigVT = V->getOperand(0).getValueType(); + EVT SmallVT = V->getOperand(1).getValueType(); + if (NVT != SmallVT || NVT.getSizeInBits()*2 != BigVT.getSizeInBits()) + return SDValue(); + + // Combine: + // (extract_subvec (insert_subvec V1, V2, InsIdx), ExtIdx) + // Into: + // indicies are equal => V1 + // otherwise => (extract_subvec V1, ExtIdx) + // + SDValue InsIdx = N->getOperand(1); + SDValue ExtIdx = V->getOperand(2); + + if (InsIdx == ExtIdx) + return V->getOperand(1); + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, N->getDebugLoc(), NVT, + V->getOperand(0), N->getOperand(1)); + } + + return SDValue(); +} + SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { EVT VT = N->getValueType(0); unsigned NumElts = VT.getVectorNumElements(); diff --git a/test/CodeGen/X86/avx-vinsertf128.ll b/test/CodeGen/X86/avx-vinsertf128.ll index 2b2f7e54116..cda1331da32 100644 --- a/test/CodeGen/X86/avx-vinsertf128.ll +++ b/test/CodeGen/X86/avx-vinsertf128.ll @@ -37,3 +37,22 @@ allocas: ret void } +;; DAG Combine must remove useless vinsertf128 instructions + +; CHECK: DAGCombineA +; CHECK-NOT: vinsertf128 $1 +define <4 x i32> @DAGCombineA(<4 x i32> %v1) nounwind readonly { + %1 = shufflevector <4 x i32> %v1, <4 x i32> undef, <8 x i32> + %2 = shufflevector <8 x i32> %1, <8 x i32> undef, <4 x i32> + ret <4 x i32> %2 +} + +; CHECK: DAGCombineB +; CHECK: vpaddd %xmm +; CHECK-NOT: vinsertf128 $1 +; CHECK: vpaddd %xmm +define <8 x i32> @DAGCombineB(<8 x i32> %v1, <8 x i32> %v2) nounwind readonly { + %1 = add <8 x i32> %v1, %v2 + %2 = add <8 x i32> %1, %v1 + ret <8 x i32> %2 +}