mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +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);
|
||||
}
|
||||
|
||||
// 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 N0 = N->getOperand(0);
|
||||
SDValue N1 = N->getOperand(1);
|
||||
@ -4664,6 +4714,17 @@ SDValue DAGCombiner::visitVSELECT(SDNode *N) {
|
||||
if (ISD::isBuildVectorAllZeros(N0.getNode()))
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
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: 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