llvm.org GIT mirror llvm / d99cefb
Convert a vselect into a concat_vector if possible Summary: If both vector args to vselect are concat_vectors and the condition is constant and picks half a vector from each argument, convert the vselect into a concat_vectors. Added a test. The ConvertSelectToConcatVector is assuming it doesn't get vselects with arguments of, for example, <undef, undef, true, true>. Those get taken care of in the checks above its call. Reviewers: nadav, delena, grosbach, hfinkel Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D3916 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209929 91177308-0d34-0410-b5e6-96231b3b80d8 Filipe Cabecinhas 6 years ago
3 changed file(s) with 75 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
45914591 return std::make_pair(Lo, Hi);
45924592 }
45934593
4594 // This function assumes all the vselect's arguments are CONCAT_VECTOR
4595 // nodes and that the condition is a BV of ConstantSDNodes (or undefs).
4596 static SDValue ConvertSelectToConcatVector(SDNode *N, SelectionDAG &DAG) {
4597 SDLoc dl(N);
4598 SDValue Cond = N->getOperand(0);
4599 SDValue LHS = N->getOperand(1);
4600 SDValue RHS = N->getOperand(2);
4601 MVT VT = N->getSimpleValueType(0);
4602 int NumElems = VT.getVectorNumElements();
4603 assert(LHS.getOpcode() == ISD::CONCAT_VECTORS &&
4604 RHS.getOpcode() == ISD::CONCAT_VECTORS &&
4605 Cond.getOpcode() == ISD::BUILD_VECTOR);
4606
4607 // We're sure we have an even number of elements due to the
4608 // concat_vectors we have as arguments to vselect.
4609 // Skip BV elements until we find one that's not an UNDEF
4610 // After we find an UNDEF element, keep looping until we get to half the
4611 // length of the BV and see if all the non-undef nodes are the same.
4612 ConstantSDNode *BottomHalf = nullptr;
4613 for (int i = 0; i < NumElems / 2; ++i) {
4614 if (Cond->getOperand(i)->getOpcode() == ISD::UNDEF)
4615 continue;
4616
4617 if (BottomHalf == nullptr)
4618 BottomHalf = cast(Cond.getOperand(i));
4619 else if (Cond->getOperand(i).getNode() != BottomHalf)
4620 return SDValue();
4621 }
4622
4623 // Do the same for the second half of the BuildVector
4624 ConstantSDNode *TopHalf = nullptr;
4625 for (int i = NumElems / 2; i < NumElems; ++i) {
4626 if (Cond->getOperand(i)->getOpcode() == ISD::UNDEF)
4627 continue;
4628
4629 if (TopHalf == nullptr)
4630 TopHalf = cast(Cond.getOperand(i));
4631 else if (Cond->getOperand(i).getNode() != TopHalf)
4632 return SDValue();
4633 }
4634
4635 assert(TopHalf && BottomHalf &&
4636 "One half of the selector was all UNDEFs and the other was all the "
4637 "same value. This should have been addressed before this function.");
4638 return DAG.getNode(
4639 ISD::CONCAT_VECTORS, dl, VT,
4640 BottomHalf->isNullValue() ? RHS->getOperand(0) : LHS->getOperand(0),
4641 TopHalf->isNullValue() ? RHS->getOperand(1) : LHS->getOperand(1));
4642 }
4643
45944644 SDValue DAGCombiner::visitVSELECT(SDNode *N) {
45954645 SDValue N0 = N->getOperand(0);
45964646 SDValue N1 = N->getOperand(1);
46624712 // Fold (vselect (build_vector all_zeros), N1, N2) -> N2
46634713 if (ISD::isBuildVectorAllZeros(N0.getNode()))
46644714 return N2;
4715
4716 // The ConvertSelectToConcatVector function is assuming both the above
4717 // checks for (vselect (build_vector all{ones,zeros) ...) have been made
4718 // and addressed.
4719 if (N1.getOpcode() == ISD::CONCAT_VECTORS &&
4720 N2.getOpcode() == ISD::CONCAT_VECTORS &&
4721 ISD::isBuildVectorOfConstantSDNodes(N0.getNode())) {
4722 SDValue CV = ConvertSelectToConcatVector(N, DAG);
4723 if (CV.getNode())
4724 return CV;
4725 }
46654726
46664727 return SDValue();
46674728 }
191191 %s = select <1 x i1> %cond, <1 x i32> %a, <1 x i32> %b
192192 ret <1 x i32> %s
193193 }
194
261261 ; CHECK: movsd
262262 ; CHECK: ret
263263
264 define <4 x float> @select_of_shuffles_0(<2 x float> %a0, <2 x float> %b0, <2 x float> %a1, <2 x float> %b1) {
265 ; CHECK-LABEL: select_of_shuffles_0
266 ; CHECK-DAG: movlhps %xmm2, [[REGA:%xmm[0-9]+]]
267 ; CHECK-DAG: movlhps %xmm3, [[REGB:%xmm[0-9]+]]
268 ; CHECK: subps [[REGB]], [[REGA]]
269 %1 = shufflevector <2 x float> %a0, <2 x float> undef, <4 x i32>
270 %2 = shufflevector <2 x float> %a1, <2 x float> undef, <4 x i32>
271 %3 = select <4 x i1> , <4 x float> %2, <4 x float> %1
272 %4 = shufflevector <2 x float> %b0, <2 x float> undef, <4 x i32>
273 %5 = shufflevector <2 x float> %b1, <2 x float> undef, <4 x i32>
274 %6 = select <4 x i1> , <4 x float> %5, <4 x float> %4
275 %7 = fsub <4 x float> %3, %6
276 ret <4 x float> %7
277 }