-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[IR][RISCV] Add llvm.vector.(de)interleave3/5/7 #124825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
2dac3c3
db32a93
c6ac1aa
dcaaf4f
732df7d
ae39c1b
0cc3cd5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8251,10 +8251,28 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, | |
visitCallBrLandingPad(I); | ||
return; | ||
case Intrinsic::vector_interleave2: | ||
visitVectorInterleave(I); | ||
visitVectorInterleave(I, 2); | ||
return; | ||
case Intrinsic::vector_interleave3: | ||
visitVectorInterleave(I, 3); | ||
return; | ||
case Intrinsic::vector_interleave5: | ||
visitVectorInterleave(I, 5); | ||
return; | ||
case Intrinsic::vector_interleave7: | ||
visitVectorInterleave(I, 7); | ||
return; | ||
case Intrinsic::vector_deinterleave2: | ||
visitVectorDeinterleave(I); | ||
visitVectorDeinterleave(I, 2); | ||
return; | ||
case Intrinsic::vector_deinterleave3: | ||
visitVectorDeinterleave(I, 3); | ||
return; | ||
case Intrinsic::vector_deinterleave5: | ||
visitVectorDeinterleave(I, 5); | ||
return; | ||
case Intrinsic::vector_deinterleave7: | ||
visitVectorDeinterleave(I, 7); | ||
return; | ||
case Intrinsic::experimental_vector_compress: | ||
setValue(&I, DAG.getNode(ISD::VECTOR_COMPRESS, sdl, | ||
|
@@ -12565,59 +12583,75 @@ void SelectionDAGBuilder::visitVectorReverse(const CallInst &I) { | |
setValue(&I, DAG.getVectorShuffle(VT, DL, V, DAG.getUNDEF(VT), Mask)); | ||
} | ||
|
||
void SelectionDAGBuilder::visitVectorDeinterleave(const CallInst &I) { | ||
void SelectionDAGBuilder::visitVectorDeinterleave(const CallInst &I, | ||
unsigned Factor) { | ||
auto DL = getCurSDLoc(); | ||
SDValue InVec = getValue(I.getOperand(0)); | ||
EVT OutVT = | ||
InVec.getValueType().getHalfNumVectorElementsVT(*DAG.getContext()); | ||
|
||
SmallVector<EVT, 4> ValueVTs; | ||
ComputeValueVTs(DAG.getTargetLoweringInfo(), DAG.getDataLayout(), I.getType(), | ||
ValueVTs); | ||
|
||
EVT OutVT = ValueVTs[0]; | ||
unsigned OutNumElts = OutVT.getVectorMinNumElements(); | ||
|
||
// ISD Node needs the input vectors split into two equal parts | ||
SDValue Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, OutVT, InVec, | ||
DAG.getVectorIdxConstant(0, DL)); | ||
SDValue Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, OutVT, InVec, | ||
DAG.getVectorIdxConstant(OutNumElts, DL)); | ||
SmallVector<SDValue, 4> SubVecs(Factor); | ||
for (unsigned i = 0; i != Factor; ++i) { | ||
assert(ValueVTs[i] == OutVT && "Expected VTs to be the same"); | ||
SubVecs[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, OutVT, InVec, | ||
DAG.getVectorIdxConstant(OutNumElts * i, DL)); | ||
} | ||
|
||
// Use VECTOR_SHUFFLE for fixed-length vectors to benefit from existing | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment needs updating There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
// legalisation and combines. | ||
if (OutVT.isFixedLengthVector()) { | ||
SDValue Even = DAG.getVectorShuffle(OutVT, DL, Lo, Hi, | ||
if (OutVT.isFixedLengthVector() && Factor == 2) { | ||
SDValue Even = DAG.getVectorShuffle(OutVT, DL, SubVecs[0], SubVecs[1], | ||
createStrideMask(0, 2, OutNumElts)); | ||
SDValue Odd = DAG.getVectorShuffle(OutVT, DL, Lo, Hi, | ||
SDValue Odd = DAG.getVectorShuffle(OutVT, DL, SubVecs[0], SubVecs[1], | ||
createStrideMask(1, 2, OutNumElts)); | ||
SDValue Res = DAG.getMergeValues({Even, Odd}, getCurSDLoc()); | ||
setValue(&I, Res); | ||
return; | ||
} | ||
|
||
SDValue Res = DAG.getNode(ISD::VECTOR_DEINTERLEAVE, DL, | ||
DAG.getVTList(OutVT, OutVT), Lo, Hi); | ||
DAG.getVTList(ValueVTs), SubVecs); | ||
setValue(&I, Res); | ||
} | ||
|
||
void SelectionDAGBuilder::visitVectorInterleave(const CallInst &I) { | ||
void SelectionDAGBuilder::visitVectorInterleave(const CallInst &I, | ||
unsigned Factor) { | ||
auto DL = getCurSDLoc(); | ||
EVT InVT = getValue(I.getOperand(0)).getValueType(); | ||
SDValue InVec0 = getValue(I.getOperand(0)); | ||
SDValue InVec1 = getValue(I.getOperand(1)); | ||
const TargetLowering &TLI = DAG.getTargetLoweringInfo(); | ||
EVT InVT = getValue(I.getOperand(0)).getValueType(); | ||
EVT OutVT = TLI.getValueType(DAG.getDataLayout(), I.getType()); | ||
|
||
SmallVector<SDValue, 8> InVecs(Factor); | ||
for (unsigned i = 0; i < Factor; ++i) { | ||
InVecs[i] = getValue(I.getOperand(i)); | ||
assert(InVecs[i].getValueType() == InVecs[0].getValueType() && | ||
"Expected VTs to be the same"); | ||
} | ||
|
||
// Use VECTOR_SHUFFLE for fixed-length vectors to benefit from existing | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment needs updating There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
// legalisation and combines. | ||
if (OutVT.isFixedLengthVector()) { | ||
if (OutVT.isFixedLengthVector() && Factor == 2) { | ||
unsigned NumElts = InVT.getVectorMinNumElements(); | ||
SDValue V = DAG.getNode(ISD::CONCAT_VECTORS, DL, OutVT, InVec0, InVec1); | ||
SDValue V = DAG.getNode(ISD::CONCAT_VECTORS, DL, OutVT, InVecs); | ||
setValue(&I, DAG.getVectorShuffle(OutVT, DL, V, DAG.getUNDEF(OutVT), | ||
createInterleaveMask(NumElts, 2))); | ||
return; | ||
} | ||
|
||
SDValue Res = DAG.getNode(ISD::VECTOR_INTERLEAVE, DL, | ||
DAG.getVTList(InVT, InVT), InVec0, InVec1); | ||
Res = DAG.getNode(ISD::CONCAT_VECTORS, DL, OutVT, Res.getValue(0), | ||
Res.getValue(1)); | ||
SmallVector<EVT, 8> ValueVTs(Factor, InVT); | ||
SDValue Res = | ||
DAG.getNode(ISD::VECTOR_INTERLEAVE, DL, DAG.getVTList(ValueVTs), InVecs); | ||
|
||
SmallVector<SDValue, 8> Results(Factor); | ||
for (unsigned i = 0; i < Factor; ++i) | ||
Results[i] = Res.getValue(i); | ||
|
||
Res = DAG.getNode(ISD::CONCAT_VECTORS, DL, OutVT, Results); | ||
setValue(&I, Res); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we make them consecutive?
(I don't know why we have a bubble between 31 and 34...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There were two IIT w.r.t legacy pointer types that got deprecated after we adopted opaque pointers.
I was going to make them more compact, but now you pointed out I think it's not really necessary. It is fixed now.