diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 6eb85d4009b8e..5cb220cd8fe2e 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -1959,7 +1959,7 @@ static SDValue lowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG, 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); } @@ -7480,16 +7480,27 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, 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, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td index f50bb59f4bc51..1ce7b2398c45e 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td @@ -464,7 +464,4 @@ def : Pat<(i64 (any_llround FPR16:$rs1)), (FCVT_L_S (FCVT_S_H $rs1), 0b100)>; // [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]