diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td @@ -392,16 +392,12 @@ // [u]int->float. Match GCC and default to using dynamic rounding mode. def : Pat<(sint_to_fp GPR:$rs1), (FCVT_S_W $rs1, 0b111)>; def : Pat<(uint_to_fp GPR:$rs1), (FCVT_S_WU $rs1, 0b111)>; -} // Predicates = [HasStdExtF, IsRV32] - -let Predicates = [HasStdExtF, IsRV32] in { -// FP->[u]int. Round-to-zero must be used -def : Pat<(fp_to_sint FPR32:$rs1), (FCVT_W_S $rs1, 0b001)>; -def : Pat<(fp_to_uint FPR32:$rs1), (FCVT_WU_S $rs1, 0b001)>; -// [u]int->fp. Match GCC and default to using dynamic rounding mode. -def : Pat<(sint_to_fp GPR:$rs1), (FCVT_S_W $rs1, 0b111)>; -def : Pat<(uint_to_fp GPR:$rs1), (FCVT_S_WU $rs1, 0b111)>; +// [u]int->double->float +def : Pat<(fpround (f64 (sint_to_fp GPR:$rs1))), + (FCVT_S_W GPR:$rs1, 0b111)>; +def : Pat<(fpround (f64 (uint_to_fp GPR:$rs1))), + (FCVT_S_WU GPR:$rs1, 0b111)>; } // Predicates = [HasStdExtF, IsRV32] let Predicates = [HasStdExtF, IsRV64] in { @@ -426,4 +422,11 @@ def : Pat<(uint_to_fp (zexti32 GPR:$rs1)), (FCVT_S_WU $rs1, 0b111)>; def : Pat<(sint_to_fp GPR:$rs1), (FCVT_S_L $rs1, 0b111)>; def : Pat<(uint_to_fp GPR:$rs1), (FCVT_S_LU $rs1, 0b111)>; + +// [u]int->double->float +def : Pat<(fpround (f64 (sint_to_fp (sext_inreg GPR:$rs1, i32)))), + (FCVT_S_W GPR:$rs1, 0b111)>; +def : Pat<(fpround (f64 (uint_to_fp (zexti32 GPR:$rs1)))), + (FCVT_S_WU GPR:$rs1, 0b111)>; + } // Predicates = [HasStdExtF, IsRV64] diff --git a/llvm/test/CodeGen/RISCV/double-convert-indirect.ll b/llvm/test/CodeGen/RISCV/double-convert-indirect.ll --- a/llvm/test/CodeGen/RISCV/double-convert-indirect.ll +++ b/llvm/test/CodeGen/RISCV/double-convert-indirect.ll @@ -14,15 +14,13 @@ define float @fcvt_s_w_via_d(i32 %0) nounwind { ; RV32IFD-LABEL: fcvt_s_w_via_d: ; RV32IFD: # %bb.0: -; RV32IFD-NEXT: fcvt.d.w ft0, a0 -; RV32IFD-NEXT: fcvt.s.d ft0, ft0 +; RV32IFD-NEXT: fcvt.s.w ft0, a0 ; RV32IFD-NEXT: fmv.x.w a0, ft0 ; RV32IFD-NEXT: ret ; ; RV64IFD-LABEL: fcvt_s_w_via_d: ; RV64IFD: # %bb.0: -; RV64IFD-NEXT: fcvt.d.w ft0, a0 -; RV64IFD-NEXT: fcvt.s.d ft0, ft0 +; RV64IFD-NEXT: fcvt.s.w ft0, a0 ; RV64IFD-NEXT: fmv.x.w a0, ft0 ; RV64IFD-NEXT: ret %2 = sitofp i32 %0 to double @@ -33,15 +31,13 @@ define float @fcvt_s_wu_via_d(i32 %0) nounwind { ; RV32IFD-LABEL: fcvt_s_wu_via_d: ; RV32IFD: # %bb.0: -; RV32IFD-NEXT: fcvt.d.wu ft0, a0 -; RV32IFD-NEXT: fcvt.s.d ft0, ft0 +; RV32IFD-NEXT: fcvt.s.wu ft0, a0 ; RV32IFD-NEXT: fmv.x.w a0, ft0 ; RV32IFD-NEXT: ret ; ; RV64IFD-LABEL: fcvt_s_wu_via_d: ; RV64IFD: # %bb.0: -; RV64IFD-NEXT: fcvt.d.wu ft0, a0 -; RV64IFD-NEXT: fcvt.s.d ft0, ft0 +; RV64IFD-NEXT: fcvt.s.wu ft0, a0 ; RV64IFD-NEXT: fmv.x.w a0, ft0 ; RV64IFD-NEXT: ret %2 = uitofp i32 %0 to double