Skip to content

Commit ef1367f

Browse files
authored
[RISCV] Use vnclip(u) to handle fp_to_(s/u)int_sat that needs additional narrowing. (#100071)
If vncvt doesn't produce the destination type directly, use vnclip to do additional narrowing with saturation.
1 parent 87f2c25 commit ef1367f

File tree

4 files changed

+109
-521
lines changed

4 files changed

+109
-521
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2955,10 +2955,6 @@ static SDValue lowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG,
29552955
if (SatVT != DstEltVT)
29562956
return SDValue();
29572957

2958-
// FIXME: Don't support narrowing by more than 1 steps for now.
2959-
if (SrcEltSize > (2 * DstEltSize))
2960-
return SDValue();
2961-
29622958
MVT DstContainerVT = DstVT;
29632959
MVT SrcContainerVT = SrcVT;
29642960
if (DstVT.isFixedLengthVector()) {
@@ -2986,9 +2982,29 @@ static SDValue lowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG,
29862982
Src = DAG.getNode(RISCVISD::FP_EXTEND_VL, DL, InterVT, Src, Mask, VL);
29872983
}
29882984

2985+
MVT CvtContainerVT = DstContainerVT;
2986+
MVT CvtEltVT = DstEltVT;
2987+
if (SrcEltSize > (2 * DstEltSize)) {
2988+
CvtEltVT = MVT::getIntegerVT(SrcEltVT.getSizeInBits() / 2);
2989+
CvtContainerVT = CvtContainerVT.changeVectorElementType(CvtEltVT);
2990+
}
2991+
29892992
unsigned RVVOpc =
29902993
IsSigned ? RISCVISD::VFCVT_RTZ_X_F_VL : RISCVISD::VFCVT_RTZ_XU_F_VL;
2991-
SDValue Res = DAG.getNode(RVVOpc, DL, DstContainerVT, Src, Mask, VL);
2994+
SDValue Res = DAG.getNode(RVVOpc, DL, CvtContainerVT, Src, Mask, VL);
2995+
2996+
while (CvtContainerVT != DstContainerVT) {
2997+
CvtEltVT = MVT::getIntegerVT(CvtEltVT.getSizeInBits() / 2);
2998+
CvtContainerVT = CvtContainerVT.changeVectorElementType(CvtEltVT);
2999+
// Rounding mode here is arbitrary since we aren't shifting out any bits.
3000+
unsigned ClipOpc = IsSigned ? RISCVISD::VNCLIP_VL : RISCVISD::VNCLIPU_VL;
3001+
Res = DAG.getNode(
3002+
ClipOpc, DL, CvtContainerVT,
3003+
{Res, DAG.getConstant(0, DL, CvtContainerVT),
3004+
DAG.getUNDEF(CvtContainerVT), Mask,
3005+
DAG.getTargetConstant(RISCVVXRndMode::RNU, DL, Subtarget.getXLenVT()),
3006+
VL});
3007+
}
29923008

29933009
SDValue SplatZero = DAG.getNode(
29943010
RISCVISD::VMV_V_X_VL, DL, DstContainerVT, DAG.getUNDEF(DstContainerVT),

0 commit comments

Comments
 (0)