Skip to content

Commit

Permalink
[RISCV] Use vnclip(u) to handle fp_to_(s/u)int_sat that needs additio…
Browse files Browse the repository at this point in the history
…nal narrowing. (llvm#100071)

If vncvt doesn't produce the destination type directly, use vnclip to do
additional narrowing with saturation.
  • Loading branch information
topperc authored Jul 23, 2024
1 parent 87f2c25 commit ef1367f
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 521 deletions.
26 changes: 21 additions & 5 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2955,10 +2955,6 @@ static SDValue lowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG,
if (SatVT != DstEltVT)
return SDValue();

// FIXME: Don't support narrowing by more than 1 steps for now.
if (SrcEltSize > (2 * DstEltSize))
return SDValue();

MVT DstContainerVT = DstVT;
MVT SrcContainerVT = SrcVT;
if (DstVT.isFixedLengthVector()) {
Expand Down Expand Up @@ -2986,9 +2982,29 @@ static SDValue lowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG,
Src = DAG.getNode(RISCVISD::FP_EXTEND_VL, DL, InterVT, Src, Mask, VL);
}

MVT CvtContainerVT = DstContainerVT;
MVT CvtEltVT = DstEltVT;
if (SrcEltSize > (2 * DstEltSize)) {
CvtEltVT = MVT::getIntegerVT(SrcEltVT.getSizeInBits() / 2);
CvtContainerVT = CvtContainerVT.changeVectorElementType(CvtEltVT);
}

unsigned RVVOpc =
IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
SDValue Res = DAG.getNode(RVVOpc, DL, DstContainerVT, Src, Mask, VL);
SDValue Res = DAG.getNode(RVVOpc, DL, CvtContainerVT, Src, Mask, VL);

while (CvtContainerVT != DstContainerVT) {
CvtEltVT = MVT::getIntegerVT(CvtEltVT.getSizeInBits() / 2);
CvtContainerVT = CvtContainerVT.changeVectorElementType(CvtEltVT);
// Rounding mode here is arbitrary since we aren't shifting out any bits.
unsigned ClipOpc = IsSigned ? RISCVISD::VNCLIP_VL : RISCVISD::VNCLIPU_VL;
Res = DAG.getNode(
ClipOpc, DL, CvtContainerVT,
{Res, DAG.getConstant(0, DL, CvtContainerVT),
DAG.getUNDEF(CvtContainerVT), Mask,
DAG.getTargetConstant(RISCVVXRndMode::RNU, DL, Subtarget.getXLenVT()),
VL});
}

SDValue SplatZero = DAG.getNode(
RISCVISD::VMV_V_X_VL, DL, DstContainerVT, DAG.getUNDEF(DstContainerVT),
Expand Down
Loading

0 comments on commit ef1367f

Please sign in to comment.