@@ -675,7 +675,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
675
675
ISD::VP_FP_TO_UINT, ISD::VP_SETCC, ISD::VP_SIGN_EXTEND,
676
676
ISD::VP_ZERO_EXTEND, ISD::VP_TRUNCATE, ISD::VP_SMIN,
677
677
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 };
679
679
680
680
static const unsigned FloatingPointVPOps[] = {
681
681
ISD::VP_FADD, ISD::VP_FSUB, ISD::VP_FMUL,
@@ -688,7 +688,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
688
688
ISD::VP_FCEIL, ISD::VP_FFLOOR, ISD::VP_FROUND,
689
689
ISD::VP_FROUNDEVEN, ISD::VP_FCOPYSIGN, ISD::VP_FROUNDTOZERO,
690
690
ISD::VP_FRINT, ISD::VP_FNEARBYINT, ISD::VP_IS_FPCLASS,
691
- ISD::EXPERIMENTAL_VP_REVERSE};
691
+ ISD::EXPERIMENTAL_VP_REVERSE, ISD::EXPERIMENTAL_VP_SPLICE };
692
692
693
693
static const unsigned IntegerVecReduceOps[] = {
694
694
ISD::VECREDUCE_ADD, ISD::VECREDUCE_AND, ISD::VECREDUCE_OR,
@@ -773,6 +773,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
773
773
774
774
setOperationAction(ISD::VECTOR_REVERSE, VT, Custom);
775
775
776
+ setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
776
777
setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
777
778
778
779
setOperationPromotedToType(
@@ -1147,6 +1148,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
1147
1148
ISD::VP_SETCC, ISD::VP_TRUNCATE},
1148
1149
VT, Custom);
1149
1150
1151
+ setOperationAction(ISD::EXPERIMENTAL_VP_SPLICE, VT, Custom);
1150
1152
setOperationAction(ISD::EXPERIMENTAL_VP_REVERSE, VT, Custom);
1151
1153
continue;
1152
1154
}
@@ -6637,6 +6639,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
6637
6639
!Subtarget.hasVInstructionsF16()))
6638
6640
return SplitVPOp(Op, DAG);
6639
6641
return lowerVectorFTRUNC_FCEIL_FFLOOR_FROUND(Op, DAG, Subtarget);
6642
+ case ISD::EXPERIMENTAL_VP_SPLICE:
6643
+ return lowerVPSpliceExperimental(Op, DAG);
6640
6644
case ISD::EXPERIMENTAL_VP_REVERSE:
6641
6645
return lowerVPReverseExperimental(Op, DAG);
6642
6646
}
@@ -10582,6 +10586,87 @@ SDValue RISCVTargetLowering::lowerVPFPIntConvOp(SDValue Op,
10582
10586
return convertFromScalableVector(VT, Result, DAG, Subtarget);
10583
10587
}
10584
10588
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
+
10585
10670
SDValue
10586
10671
RISCVTargetLowering::lowerVPReverseExperimental(SDValue Op,
10587
10672
SelectionDAG &DAG) const {
0 commit comments