Skip to content

Commit b9d6e8c

Browse files
committed
[RISCV] Lower VECTOR_SPLICE to RVV instructions.
This lowers VECTOR_SPLICE of scalable vectors to a slidedown follow by a slideup. Fixed vectors are encouraged to use shufflevector instruction. The equivalent patch for fixed vectors is D119039. I've used a tail agnostic slidedown and limited the VL to only the elements that will not be overwritten by the slideup. The slideup uses VLMax for its VL. It unfortunately uses tail undisturbed policy but it isn't required as there is no tail. We just need the merge operand to carry the bits for the lower portion of the result. Care was taken to ensure that either the slideup or slidedown will be able to use a .vi instruction when the immediate is small. Which one uses the immediate depends on the sign of the immediate. Reviewed By: frasercrmck, ABataev Differential Revision: https://reviews.llvm.org/D119303
1 parent 7bc6667 commit b9d6e8c

File tree

3 files changed

+2078
-0
lines changed

3 files changed

+2078
-0
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
675675
setLoadExtAction(ISD::ZEXTLOAD, OtherVT, VT, Expand);
676676
}
677677

678+
// Splice
679+
setOperationAction(ISD::VECTOR_SPLICE, VT, Custom);
680+
678681
// Lower CTLZ_ZERO_UNDEF and CTTZ_ZERO_UNDEF if we have a floating point
679682
// type that can represent the value exactly.
680683
if (VT.getVectorElementType() != MVT::i64) {
@@ -753,6 +756,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
753756
setOperationAction(ISD::EXTRACT_SUBVECTOR, VT, Custom);
754757

755758
setOperationAction(ISD::VECTOR_REVERSE, VT, Custom);
759+
setOperationAction(ISD::VECTOR_SPLICE, VT, Custom);
756760

757761
for (unsigned VPOpc : FloatingPointVPOps)
758762
setOperationAction(VPOpc, VT, Custom);
@@ -3507,6 +3511,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
35073511
return lowerSTEP_VECTOR(Op, DAG);
35083512
case ISD::VECTOR_REVERSE:
35093513
return lowerVECTOR_REVERSE(Op, DAG);
3514+
case ISD::VECTOR_SPLICE:
3515+
return lowerVECTOR_SPLICE(Op, DAG);
35103516
case ISD::BUILD_VECTOR:
35113517
return lowerBUILD_VECTOR(Op, DAG, Subtarget);
35123518
case ISD::SPLAT_VECTOR:
@@ -5628,6 +5634,43 @@ SDValue RISCVTargetLowering::lowerVECTOR_REVERSE(SDValue Op,
56285634
return DAG.getNode(GatherOpc, DL, VecVT, Op.getOperand(0), Indices, Mask, VL);
56295635
}
56305636

5637+
SDValue RISCVTargetLowering::lowerVECTOR_SPLICE(SDValue Op,
5638+
SelectionDAG &DAG) const {
5639+
SDLoc DL(Op);
5640+
SDValue V1 = Op.getOperand(0);
5641+
SDValue V2 = Op.getOperand(1);
5642+
MVT XLenVT = Subtarget.getXLenVT();
5643+
MVT VecVT = Op.getSimpleValueType();
5644+
5645+
unsigned MinElts = VecVT.getVectorMinNumElements();
5646+
SDValue VLMax = DAG.getNode(ISD::VSCALE, DL, XLenVT,
5647+
DAG.getConstant(MinElts, DL, XLenVT));
5648+
5649+
int64_t ImmValue = cast<ConstantSDNode>(Op.getOperand(2))->getSExtValue();
5650+
SDValue DownOffset, UpOffset;
5651+
if (ImmValue >= 0) {
5652+
// The operand is a TargetConstant, we need to rebuild it as a regular
5653+
// constant.
5654+
DownOffset = DAG.getConstant(ImmValue, DL, XLenVT);
5655+
UpOffset = DAG.getNode(ISD::SUB, DL, XLenVT, VLMax, DownOffset);
5656+
} else {
5657+
// The operand is a TargetConstant, we need to rebuild it as a regular
5658+
// constant rather than negating the original operand.
5659+
UpOffset = DAG.getConstant(-ImmValue, DL, XLenVT);
5660+
DownOffset = DAG.getNode(ISD::SUB, DL, XLenVT, VLMax, UpOffset);
5661+
}
5662+
5663+
MVT MaskVT = MVT::getVectorVT(MVT::i1, VecVT.getVectorElementCount());
5664+
SDValue TrueMask = DAG.getNode(RISCVISD::VMSET_VL, DL, MaskVT, VLMax);
5665+
5666+
SDValue SlideDown =
5667+
DAG.getNode(RISCVISD::VSLIDEDOWN_VL, DL, VecVT, DAG.getUNDEF(VecVT), V1,
5668+
DownOffset, TrueMask, UpOffset);
5669+
return DAG.getNode(RISCVISD::VSLIDEUP_VL, DL, VecVT, SlideDown, V2, UpOffset,
5670+
TrueMask,
5671+
DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, XLenVT));
5672+
}
5673+
56315674
SDValue
56325675
RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(SDValue Op,
56335676
SelectionDAG &DAG) const {

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ class RISCVTargetLowering : public TargetLowering {
615615
SDValue lowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
616616
SDValue lowerSTEP_VECTOR(SDValue Op, SelectionDAG &DAG) const;
617617
SDValue lowerVECTOR_REVERSE(SDValue Op, SelectionDAG &DAG) const;
618+
SDValue lowerVECTOR_SPLICE(SDValue Op, SelectionDAG &DAG) const;
618619
SDValue lowerABS(SDValue Op, SelectionDAG &DAG) const;
619620
SDValue lowerMaskedLoad(SDValue Op, SelectionDAG &DAG) const;
620621
SDValue lowerMaskedStore(SDValue Op, SelectionDAG &DAG) const;

0 commit comments

Comments
 (0)