mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-06 04:31:08 +00:00
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
This commit is contained in:
parent
96241f26fc
commit
d99cefbad1
@ -4592,6 +4592,56 @@ std::pair<SDValue, SDValue> SplitVSETCC(const SDNode *N, SelectionDAG &DAG) {
|
|||||||
return std::make_pair(Lo, Hi);
|
return std::make_pair(Lo, Hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function assumes all the vselect's arguments are CONCAT_VECTOR
|
||||||
|
// nodes and that the condition is a BV of ConstantSDNodes (or undefs).
|
||||||
|
static SDValue ConvertSelectToConcatVector(SDNode *N, SelectionDAG &DAG) {
|
||||||
|
SDLoc dl(N);
|
||||||
|
SDValue Cond = N->getOperand(0);
|
||||||
|
SDValue LHS = N->getOperand(1);
|
||||||
|
SDValue RHS = N->getOperand(2);
|
||||||
|
MVT VT = N->getSimpleValueType(0);
|
||||||
|
int NumElems = VT.getVectorNumElements();
|
||||||
|
assert(LHS.getOpcode() == ISD::CONCAT_VECTORS &&
|
||||||
|
RHS.getOpcode() == ISD::CONCAT_VECTORS &&
|
||||||
|
Cond.getOpcode() == ISD::BUILD_VECTOR);
|
||||||
|
|
||||||
|
// We're sure we have an even number of elements due to the
|
||||||
|
// concat_vectors we have as arguments to vselect.
|
||||||
|
// Skip BV elements until we find one that's not an UNDEF
|
||||||
|
// After we find an UNDEF element, keep looping until we get to half the
|
||||||
|
// length of the BV and see if all the non-undef nodes are the same.
|
||||||
|
ConstantSDNode *BottomHalf = nullptr;
|
||||||
|
for (int i = 0; i < NumElems / 2; ++i) {
|
||||||
|
if (Cond->getOperand(i)->getOpcode() == ISD::UNDEF)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (BottomHalf == nullptr)
|
||||||
|
BottomHalf = cast<ConstantSDNode>(Cond.getOperand(i));
|
||||||
|
else if (Cond->getOperand(i).getNode() != BottomHalf)
|
||||||
|
return SDValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the same for the second half of the BuildVector
|
||||||
|
ConstantSDNode *TopHalf = nullptr;
|
||||||
|
for (int i = NumElems / 2; i < NumElems; ++i) {
|
||||||
|
if (Cond->getOperand(i)->getOpcode() == ISD::UNDEF)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (TopHalf == nullptr)
|
||||||
|
TopHalf = cast<ConstantSDNode>(Cond.getOperand(i));
|
||||||
|
else if (Cond->getOperand(i).getNode() != TopHalf)
|
||||||
|
return SDValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(TopHalf && BottomHalf &&
|
||||||
|
"One half of the selector was all UNDEFs and the other was all the "
|
||||||
|
"same value. This should have been addressed before this function.");
|
||||||
|
return DAG.getNode(
|
||||||
|
ISD::CONCAT_VECTORS, dl, VT,
|
||||||
|
BottomHalf->isNullValue() ? RHS->getOperand(0) : LHS->getOperand(0),
|
||||||
|
TopHalf->isNullValue() ? RHS->getOperand(1) : LHS->getOperand(1));
|
||||||
|
}
|
||||||
|
|
||||||
SDValue DAGCombiner::visitVSELECT(SDNode *N) {
|
SDValue DAGCombiner::visitVSELECT(SDNode *N) {
|
||||||
SDValue N0 = N->getOperand(0);
|
SDValue N0 = N->getOperand(0);
|
||||||
SDValue N1 = N->getOperand(1);
|
SDValue N1 = N->getOperand(1);
|
||||||
@ -4664,6 +4714,17 @@ SDValue DAGCombiner::visitVSELECT(SDNode *N) {
|
|||||||
if (ISD::isBuildVectorAllZeros(N0.getNode()))
|
if (ISD::isBuildVectorAllZeros(N0.getNode()))
|
||||||
return N2;
|
return N2;
|
||||||
|
|
||||||
|
// The ConvertSelectToConcatVector function is assuming both the above
|
||||||
|
// checks for (vselect (build_vector all{ones,zeros) ...) have been made
|
||||||
|
// and addressed.
|
||||||
|
if (N1.getOpcode() == ISD::CONCAT_VECTORS &&
|
||||||
|
N2.getOpcode() == ISD::CONCAT_VECTORS &&
|
||||||
|
ISD::isBuildVectorOfConstantSDNodes(N0.getNode())) {
|
||||||
|
SDValue CV = ConvertSelectToConcatVector(N, DAG);
|
||||||
|
if (CV.getNode())
|
||||||
|
return CV;
|
||||||
|
}
|
||||||
|
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,4 +192,3 @@ define <1 x i32> @checkScalariseVSELECT(<1 x i32> %a, <1 x i32> %b) {
|
|||||||
%s = select <1 x i1> %cond, <1 x i32> %a, <1 x i32> %b
|
%s = select <1 x i1> %cond, <1 x i32> %a, <1 x i32> %b
|
||||||
ret <1 x i32> %s
|
ret <1 x i32> %s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,3 +262,17 @@ define <2 x i64> @test25(<2 x i64> %a, <2 x i64> %b) {
|
|||||||
; CHECK: movsd
|
; CHECK: movsd
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
|
|
||||||
|
define <4 x float> @select_of_shuffles_0(<2 x float> %a0, <2 x float> %b0, <2 x float> %a1, <2 x float> %b1) {
|
||||||
|
; CHECK-LABEL: select_of_shuffles_0
|
||||||
|
; CHECK-DAG: movlhps %xmm2, [[REGA:%xmm[0-9]+]]
|
||||||
|
; CHECK-DAG: movlhps %xmm3, [[REGB:%xmm[0-9]+]]
|
||||||
|
; CHECK: subps [[REGB]], [[REGA]]
|
||||||
|
%1 = shufflevector <2 x float> %a0, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
|
||||||
|
%2 = shufflevector <2 x float> %a1, <2 x float> undef, <4 x i32> <i32 undef, i32 undef, i32 0, i32 1>
|
||||||
|
%3 = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x float> %2, <4 x float> %1
|
||||||
|
%4 = shufflevector <2 x float> %b0, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
|
||||||
|
%5 = shufflevector <2 x float> %b1, <2 x float> undef, <4 x i32> <i32 undef, i32 undef, i32 0, i32 1>
|
||||||
|
%6 = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x float> %5, <4 x float> %4
|
||||||
|
%7 = fsub <4 x float> %3, %6
|
||||||
|
ret <4 x float> %7
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user