@@ -675,7 +675,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
675675 ISD::VP_FP_TO_UINT, ISD::VP_SETCC, ISD::VP_SIGN_EXTEND,
676676 ISD::VP_ZERO_EXTEND, ISD::VP_TRUNCATE, ISD::VP_SMIN,
677677 ISD::VP_SMAX, ISD::VP_UMIN, ISD::VP_UMAX,
678- ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE};
678+ ISD::VP_ABS, ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE };
679679
680680 static const unsigned FloatingPointVPOps[] = {
681681 ISD::VP_FADD, ISD::VP_FSUB, ISD::VP_FMUL,
@@ -688,7 +688,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
688688 ISD::VP_FCEIL, ISD::VP_FFLOOR, ISD::VP_FROUND,
689689 ISD::VP_FROUNDEVEN, ISD::VP_FCOPYSIGN, ISD::VP_FROUNDTOZERO,
690690 ISD::VP_FRINT, ISD::VP_FNEARBYINT, ISD::VP_IS_FPCLASS,
691- ISD::EXPERIMENTAL_VP_REVERSE};
691+ ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE };
692692
693693 static const unsigned IntegerVecReduceOps[] = {
694694 ISD::VECREDUCE_ADD, ISD::VECREDUCE_AND, ISD::VECREDUCE_OR,
@@ -773,6 +773,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
773773
774774 setOperationAction(ISD::VECTOR_REVERSE, VT, Custom);
775775
776+ setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
776777 setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
777778
778779 setOperationPromotedToType(
@@ -1147,6 +1148,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
11471148 ISD::VP_SETCC, ISD::VP_TRUNCATE},
11481149 VT, Custom);
11491150
1151+ setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
11501152 setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
11511153 continue;
11521154 }
@@ -6637,6 +6639,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
66376639 !Subtarget.hasVInstructionsF16()))
66386640 return SplitVPOp(Op, DAG);
66396641 return lowerVectorFTRUNC_FCEIL_FFLOOR_FROUND(Op, DAG, Subtarget);
6642+ case ISD::EXPERIMENTAL_VP_SPLICE:
6643+ return lowerVPSpliceExperimental(Op, DAG);
66406644 case ISD::EXPERIMENTAL_VP_REVERSE:
66416645 return lowerVPReverseExperimental(Op, DAG);
66426646 }
@@ -10582,6 +10586,87 @@ SDValue RISCVTargetLowering::lowerVPFPIntConvOp(SDValue Op,
1058210586 return convertFromScalableVector(VT, Result, DAG, Subtarget);
1058310587}
1058410588
10589+ SDValue
10590+ RISCVTargetLowering::lowerVPSpliceExperimental(SDValue Op,
10591+ SelectionDAG &DAG) const {
10592+ SDLoc DL(Op);
10593+
10594+ SDValue Op1 = Op.getOperand(0);
10595+ SDValue Op2 = Op.getOperand(1);
10596+ SDValue Offset = Op.getOperand(2);
10597+ SDValue Mask = Op.getOperand(3);
10598+ SDValue EVL1 = Op.getOperand(4);
10599+ SDValue EVL2 = Op.getOperand(5);
10600+
10601+ const MVT XLenVT = Subtarget.getXLenVT();
10602+ MVT VT = Op.getSimpleValueType();
10603+ MVT ContainerVT = VT;
10604+ if (VT.isFixedLengthVector()) {
10605+ ContainerVT = getContainerForFixedLengthVector(VT);
10606+ Op1 = convertToScalableVector(ContainerVT, Op1, DAG, Subtarget);
10607+ Op2 = convertToScalableVector(ContainerVT, Op2, DAG, Subtarget);
10608+ MVT MaskVT = getMaskTypeFor(ContainerVT);
10609+ Mask = convertToScalableVector(MaskVT, Mask, DAG, Subtarget);
10610+ }
10611+
10612+ bool IsMaskVector = VT.getVectorElementType() == MVT::i1;
10613+ if (IsMaskVector) {
10614+ ContainerVT = ContainerVT.changeVectorElementType(MVT::i8);
10615+
10616+ // Expand input operands
10617+ SDValue SplatOneOp1 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
10618+ DAG.getUNDEF(ContainerVT),
10619+ DAG.getConstant(1, DL, XLenVT), EVL1);
10620+ SDValue SplatZeroOp1 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
10621+ DAG.getUNDEF(ContainerVT),
10622+ DAG.getConstant(0, DL, XLenVT), EVL1);
10623+ Op1 = DAG.getNode(RISCVISD::VSELECT_VL, DL, ContainerVT, Op1, SplatOneOp1,
10624+ SplatZeroOp1, EVL1);
10625+
10626+ SDValue SplatOneOp2 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
10627+ DAG.getUNDEF(ContainerVT),
10628+ DAG.getConstant(1, DL, XLenVT), EVL2);
10629+ SDValue SplatZeroOp2 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
10630+ DAG.getUNDEF(ContainerVT),
10631+ DAG.getConstant(0, DL, XLenVT), EVL2);
10632+ Op2 = DAG.getNode(RISCVISD::VSELECT_VL, DL, ContainerVT, Op2, SplatOneOp2,
10633+ SplatZeroOp2, EVL2);
10634+ }
10635+
10636+ int64_t ImmValue = cast<ConstantSDNode>(Offset)->getSExtValue();
10637+ SDValue DownOffset, UpOffset;
10638+ if (ImmValue >= 0) {
10639+ // The operand is a TargetConstant, we need to rebuild it as a regular
10640+ // constant.
10641+ DownOffset = DAG.getConstant(ImmValue, DL, XLenVT);
10642+ UpOffset = DAG.getNode(ISD::SUB, DL, XLenVT, EVL1, DownOffset);
10643+ } else {
10644+ // The operand is a TargetConstant, we need to rebuild it as a regular
10645+ // constant rather than negating the original operand.
10646+ UpOffset = DAG.getConstant(-ImmValue, DL, XLenVT);
10647+ DownOffset = DAG.getNode(ISD::SUB, DL, XLenVT, EVL1, UpOffset);
10648+ }
10649+
10650+ SDValue SlideDown =
10651+ getVSlidedown(DAG, Subtarget, DL, ContainerVT, DAG.getUNDEF(ContainerVT),
10652+ Op1, DownOffset, Mask, UpOffset);
10653+ SDValue Result = getVSlideup(DAG, Subtarget, DL, ContainerVT, SlideDown, Op2,
10654+ UpOffset, Mask, EVL2, RISCVII::TAIL_AGNOSTIC);
10655+
10656+ if (IsMaskVector) {
10657+ // Truncate Result back to a mask vector (Result has same EVL as Op2)
10658+ Result = DAG.getNode(
10659+ RISCVISD::SETCC_VL, DL, ContainerVT.changeVectorElementType(MVT::i1),
10660+ {Result, DAG.getConstant(0, DL, ContainerVT),
10661+ DAG.getCondCode(ISD::SETNE), DAG.getUNDEF(getMaskTypeFor(ContainerVT)),
10662+ Mask, EVL2});
10663+ }
10664+
10665+ if (!VT.isFixedLengthVector())
10666+ return Result;
10667+ return convertFromScalableVector(VT, Result, DAG, Subtarget);
10668+ }
10669+
1058510670SDValue
1058610671RISCVTargetLowering::lowerVPReverseExperimental(SDValue Op,
1058710672 SelectionDAG &DAG) const {
0 commit comments