Skip to content

Commit 0dcff0d

Browse files
authored
[RISCV] Add codegen support for experimental.vp.splice (#74688)
IR intrinsics were already defined, but no codegen support had been added. I extracted this code from our downstream. Some of it may have come from https://repo.hca.bsc.es/gitlab/rferrer/llvm-epi/ originally.
1 parent 199a0f9 commit 0dcff0d

File tree

8 files changed

+1586
-2
lines changed

8 files changed

+1586
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,6 +1871,9 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
18711871
case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
18721872
Res = PromoteIntOp_VP_STRIDED(N, OpNo);
18731873
break;
1874+
case ISD::EXPERIMENTAL_VP_SPLICE:
1875+
Res = PromoteIntOp_VP_SPLICE(N, OpNo);
1876+
break;
18741877
}
18751878

18761879
// If the result is null, the sub-method took care of registering results etc.
@@ -2549,6 +2552,20 @@ SDValue DAGTypeLegalizer::PromoteIntOp_VP_STRIDED(SDNode *N, unsigned OpNo) {
25492552
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
25502553
}
25512554

2555+
SDValue DAGTypeLegalizer::PromoteIntOp_VP_SPLICE(SDNode *N, unsigned OpNo) {
2556+
SmallVector<SDValue, 6> NewOps(N->op_begin(), N->op_end());
2557+
2558+
if (OpNo == 2) { // Offset operand
2559+
NewOps[OpNo] = SExtPromotedInteger(N->getOperand(OpNo));
2560+
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
2561+
}
2562+
2563+
assert((OpNo == 4 || OpNo == 5) && "Unexpected operand for promotion");
2564+
2565+
NewOps[OpNo] = ZExtPromotedInteger(N->getOperand(OpNo));
2566+
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
2567+
}
2568+
25522569
//===----------------------------------------------------------------------===//
25532570
// Integer Result Expansion
25542571
//===----------------------------------------------------------------------===//

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
410410
SDValue PromoteIntOp_STACKMAP(SDNode *N, unsigned OpNo);
411411
SDValue PromoteIntOp_PATCHPOINT(SDNode *N, unsigned OpNo);
412412
SDValue PromoteIntOp_VP_STRIDED(SDNode *N, unsigned OpNo);
413+
SDValue PromoteIntOp_VP_SPLICE(SDNode *N, unsigned OpNo);
413414

414415
void PromoteSetCCOperands(SDValue &LHS,SDValue &RHS, ISD::CondCode Code);
415416

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
1058510670
SDValue
1058610671
RISCVTargetLowering::lowerVPReverseExperimental(SDValue Op,
1058710672
SelectionDAG &DAG) const {

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,7 @@ class RISCVTargetLowering : public TargetLowering {
910910
SDValue lowerLogicVPOp(SDValue Op, SelectionDAG &DAG) const;
911911
SDValue lowerVPExtMaskOp(SDValue Op, SelectionDAG &DAG) const;
912912
SDValue lowerVPSetCCMaskOp(SDValue Op, SelectionDAG &DAG) const;
913+
SDValue lowerVPSpliceExperimental(SDValue Op, SelectionDAG &DAG) const;
913914
SDValue lowerVPReverseExperimental(SDValue Op, SelectionDAG &DAG) const;
914915
SDValue lowerVPFPIntConvOp(SDValue Op, SelectionDAG &DAG) const;
915916
SDValue lowerVPStridedLoad(SDValue Op, SelectionDAG &DAG) const;

0 commit comments

Comments
 (0)