bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT_SAT;
if (!DstVT.isVector()) {
- // In absense, of Zfh, promote f16 to f32, then saturate the result.
+ // In absense of Zfh, promote f16 to f32, then saturate the result.
if (Src.getSimpleValueType() == MVT::f16 && !Subtarget.hasStdExtZfh()) {
Src = DAG.getNode(ISD::FP_EXTEND, SDLoc(Op), MVT::f32, Src);
}
if (!isTypeLegal(Op0.getValueType()))
return;
if (IsStrict) {
+ SDValue Chain = N->getOperand(0);
+ // In absense of Zfh, promote f16 to f32, then convert.
+ if (Op0.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh()) {
+ Op0 = DAG.getNode(ISD::STRICT_FP_EXTEND, DL, {MVT::f32, MVT::Other},
+ {Chain, Op0});
+ Chain = Op0.getValue(1);
+ }
unsigned Opc = IsSigned ? RISCVISD::STRICT_FCVT_W_RV64
: RISCVISD::STRICT_FCVT_WU_RV64;
SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Other);
SDValue Res = DAG.getNode(
- Opc, DL, VTs, N->getOperand(0), Op0,
+ Opc, DL, VTs, Chain, Op0,
DAG.getTargetConstant(RISCVFPRndMode::RTZ, DL, MVT::i64));
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
Results.push_back(Res.getValue(1));
return;
}
+ // In absense of Zfh, promote f16 to f32, then convert.
+ if (Op0.getValueType() == MVT::f16 && !Subtarget.hasStdExtZfh())
+ Op0 = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Op0);
+
unsigned Opc = IsSigned ? RISCVISD::FCVT_W_RV64 : RISCVISD::FCVT_WU_RV64;
SDValue Res =
DAG.getNode(Opc, DL, MVT::i64, Op0,
// [u]int->fp. Match GCC and default to using dynamic rounding mode.
def : Pat<(any_sint_to_fp (i64 GPR:$rs1)), (FCVT_H_S (FCVT_S_L $rs1, 0b111), 0b111)>;
def : Pat<(any_uint_to_fp (i64 GPR:$rs1)), (FCVT_H_S (FCVT_S_LU $rs1, 0b111), 0b111)>;
-
-def : Pat<(riscv_any_fcvt_w_rv64 FPR16:$rs1, timm:$frm), (FCVT_W_S (FCVT_S_H $rs1), timm:$frm)>;
-def : Pat<(riscv_any_fcvt_wu_rv64 FPR16:$rs1, timm:$frm), (FCVT_WU_S (FCVT_S_H $rs1), timm:$frm)>;
} // Predicates = [HasStdExtZfhmin, NoStdExtZfh, IsRV64]