[llvm] b7376c3 - [RISCV][NFC] Add comments and tests for frint case of performFP_TO_INT_SATCombine. (#76014)

via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 19 22:56:32 PST 2023


Author: Yeting Kuo
Date: 2023-12-20T14:56:28+08:00
New Revision: b7376c319630a6b8395f3df5a46ba73e8fe29ea9

URL: https://github.com/llvm/llvm-project/commit/b7376c319630a6b8395f3df5a46ba73e8fe29ea9
DIFF: https://github.com/llvm/llvm-project/commit/b7376c319630a6b8395f3df5a46ba73e8fe29ea9.diff

LOG: [RISCV][NFC] Add comments and tests for frint case of performFP_TO_INT_SATCombine. (#76014)

performFP_TO_INT_SATCombine could also serve pattern (fp_to_int_sat
(frint X)).

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/double-round-conv-sat.ll
    llvm/test/CodeGen/RISCV/float-round-conv-sat.ll
    llvm/test/CodeGen/RISCV/half-round-conv-sat.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 22c61eb20885b8..97d76ca494cbee 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -13594,6 +13594,7 @@ static SDValue performFP_TO_INTCombine(SDNode *N,
 //   (fp_to_int_sat (ffloor X))     -> (select X == nan, 0, (fcvt X, rdn))
 //   (fp_to_int_sat (fceil X))      -> (select X == nan, 0, (fcvt X, rup))
 //   (fp_to_int_sat (fround X))     -> (select X == nan, 0, (fcvt X, rmm))
+//   (fp_to_int_sat (frint X))      -> (select X == nan, 0, (fcvt X, dyn))
 static SDValue performFP_TO_INT_SATCombine(SDNode *N,
                                        TargetLowering::DAGCombinerInfo &DCI,
                                        const RISCVSubtarget &Subtarget) {

diff  --git a/llvm/test/CodeGen/RISCV/double-round-conv-sat.ll b/llvm/test/CodeGen/RISCV/double-round-conv-sat.ll
index 1fd0d629e9a7a9..5c5b4bb723b686 100644
--- a/llvm/test/CodeGen/RISCV/double-round-conv-sat.ll
+++ b/llvm/test/CodeGen/RISCV/double-round-conv-sat.ll
@@ -1338,11 +1338,278 @@ define i64 @test_roundeven_ui64(double %x) nounwind {
   ret i64 %b
 }
 
+define signext i32 @test_rint_si32(double %x) {
+; CHECKIFD-LABEL: test_rint_si32:
+; CHECKIFD:       # %bb.0:
+; CHECKIFD-NEXT:    fcvt.w.d a0, fa0
+; CHECKIFD-NEXT:    feq.d a1, fa0, fa0
+; CHECKIFD-NEXT:    seqz a1, a1
+; CHECKIFD-NEXT:    addi a1, a1, -1
+; CHECKIFD-NEXT:    and a0, a1, a0
+; CHECKIFD-NEXT:    ret
+;
+; RV32IZFINXZDINX-LABEL: test_rint_si32:
+; RV32IZFINXZDINX:       # %bb.0:
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, -16
+; RV32IZFINXZDINX-NEXT:    .cfi_def_cfa_offset 16
+; RV32IZFINXZDINX-NEXT:    sw a0, 8(sp)
+; RV32IZFINXZDINX-NEXT:    sw a1, 12(sp)
+; RV32IZFINXZDINX-NEXT:    lw a0, 8(sp)
+; RV32IZFINXZDINX-NEXT:    lw a1, 12(sp)
+; RV32IZFINXZDINX-NEXT:    fcvt.w.d a2, a0
+; RV32IZFINXZDINX-NEXT:    feq.d a0, a0, a0
+; RV32IZFINXZDINX-NEXT:    seqz a0, a0
+; RV32IZFINXZDINX-NEXT:    addi a0, a0, -1
+; RV32IZFINXZDINX-NEXT:    and a0, a0, a2
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, 16
+; RV32IZFINXZDINX-NEXT:    ret
+;
+; RV64IZFINXZDINX-LABEL: test_rint_si32:
+; RV64IZFINXZDINX:       # %bb.0:
+; RV64IZFINXZDINX-NEXT:    fcvt.w.d a1, a0
+; RV64IZFINXZDINX-NEXT:    feq.d a0, a0, a0
+; RV64IZFINXZDINX-NEXT:    seqz a0, a0
+; RV64IZFINXZDINX-NEXT:    addi a0, a0, -1
+; RV64IZFINXZDINX-NEXT:    and a0, a0, a1
+; RV64IZFINXZDINX-NEXT:    ret
+  %a = call double @llvm.rint.f64(double %x)
+  %b = call i32 @llvm.fptosi.sat.i32.f64(double %a)
+  ret i32 %b
+}
+
+define i64 @test_rint_si64(double %x) nounwind {
+; RV32IFD-LABEL: test_rint_si64:
+; RV32IFD:       # %bb.0:
+; RV32IFD-NEXT:    addi sp, sp, -16
+; RV32IFD-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT:    fsd fs0, 0(sp) # 8-byte Folded Spill
+; RV32IFD-NEXT:    call rint at plt
+; RV32IFD-NEXT:    lui a0, %hi(.LCPI21_0)
+; RV32IFD-NEXT:    fld fa5, %lo(.LCPI21_0)(a0)
+; RV32IFD-NEXT:    fmv.d fs0, fa0
+; RV32IFD-NEXT:    fle.d s0, fa5, fa0
+; RV32IFD-NEXT:    call __fixdfdi at plt
+; RV32IFD-NEXT:    lui a4, 524288
+; RV32IFD-NEXT:    lui a2, 524288
+; RV32IFD-NEXT:    beqz s0, .LBB21_2
+; RV32IFD-NEXT:  # %bb.1:
+; RV32IFD-NEXT:    mv a2, a1
+; RV32IFD-NEXT:  .LBB21_2:
+; RV32IFD-NEXT:    lui a1, %hi(.LCPI21_1)
+; RV32IFD-NEXT:    fld fa5, %lo(.LCPI21_1)(a1)
+; RV32IFD-NEXT:    flt.d a3, fa5, fs0
+; RV32IFD-NEXT:    beqz a3, .LBB21_4
+; RV32IFD-NEXT:  # %bb.3:
+; RV32IFD-NEXT:    addi a2, a4, -1
+; RV32IFD-NEXT:  .LBB21_4:
+; RV32IFD-NEXT:    feq.d a1, fs0, fs0
+; RV32IFD-NEXT:    neg a4, a1
+; RV32IFD-NEXT:    and a1, a4, a2
+; RV32IFD-NEXT:    neg a2, a3
+; RV32IFD-NEXT:    neg a3, s0
+; RV32IFD-NEXT:    and a0, a3, a0
+; RV32IFD-NEXT:    or a0, a2, a0
+; RV32IFD-NEXT:    and a0, a4, a0
+; RV32IFD-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT:    fld fs0, 0(sp) # 8-byte Folded Reload
+; RV32IFD-NEXT:    addi sp, sp, 16
+; RV32IFD-NEXT:    ret
+;
+; RV64IFD-LABEL: test_rint_si64:
+; RV64IFD:       # %bb.0:
+; RV64IFD-NEXT:    fcvt.l.d a0, fa0
+; RV64IFD-NEXT:    feq.d a1, fa0, fa0
+; RV64IFD-NEXT:    seqz a1, a1
+; RV64IFD-NEXT:    addi a1, a1, -1
+; RV64IFD-NEXT:    and a0, a1, a0
+; RV64IFD-NEXT:    ret
+;
+; RV32IZFINXZDINX-LABEL: test_rint_si64:
+; RV32IZFINXZDINX:       # %bb.0:
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, -32
+; RV32IZFINXZDINX-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    sw s2, 20(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    sw s3, 16(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    call rint at plt
+; RV32IZFINXZDINX-NEXT:    sw a0, 8(sp)
+; RV32IZFINXZDINX-NEXT:    sw a1, 12(sp)
+; RV32IZFINXZDINX-NEXT:    lw s2, 8(sp)
+; RV32IZFINXZDINX-NEXT:    lw s3, 12(sp)
+; RV32IZFINXZDINX-NEXT:    lui a2, %hi(.LCPI21_0)
+; RV32IZFINXZDINX-NEXT:    lw a3, %lo(.LCPI21_0+4)(a2)
+; RV32IZFINXZDINX-NEXT:    lw a2, %lo(.LCPI21_0)(a2)
+; RV32IZFINXZDINX-NEXT:    fle.d s0, a2, s2
+; RV32IZFINXZDINX-NEXT:    call __fixdfdi at plt
+; RV32IZFINXZDINX-NEXT:    lui a4, 524288
+; RV32IZFINXZDINX-NEXT:    lui a2, 524288
+; RV32IZFINXZDINX-NEXT:    beqz s0, .LBB21_2
+; RV32IZFINXZDINX-NEXT:  # %bb.1:
+; RV32IZFINXZDINX-NEXT:    mv a2, a1
+; RV32IZFINXZDINX-NEXT:  .LBB21_2:
+; RV32IZFINXZDINX-NEXT:    lui a1, %hi(.LCPI21_1)
+; RV32IZFINXZDINX-NEXT:    lw a6, %lo(.LCPI21_1)(a1)
+; RV32IZFINXZDINX-NEXT:    lw a7, %lo(.LCPI21_1+4)(a1)
+; RV32IZFINXZDINX-NEXT:    flt.d a3, a6, s2
+; RV32IZFINXZDINX-NEXT:    beqz a3, .LBB21_4
+; RV32IZFINXZDINX-NEXT:  # %bb.3:
+; RV32IZFINXZDINX-NEXT:    addi a2, a4, -1
+; RV32IZFINXZDINX-NEXT:  .LBB21_4:
+; RV32IZFINXZDINX-NEXT:    feq.d a1, s2, s2
+; RV32IZFINXZDINX-NEXT:    neg a4, a1
+; RV32IZFINXZDINX-NEXT:    and a1, a4, a2
+; RV32IZFINXZDINX-NEXT:    neg a2, s0
+; RV32IZFINXZDINX-NEXT:    and a0, a2, a0
+; RV32IZFINXZDINX-NEXT:    neg a2, a3
+; RV32IZFINXZDINX-NEXT:    or a0, a2, a0
+; RV32IZFINXZDINX-NEXT:    and a0, a4, a0
+; RV32IZFINXZDINX-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    lw s2, 20(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    lw s3, 16(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, 32
+; RV32IZFINXZDINX-NEXT:    ret
+;
+; RV64IZFINXZDINX-LABEL: test_rint_si64:
+; RV64IZFINXZDINX:       # %bb.0:
+; RV64IZFINXZDINX-NEXT:    fcvt.l.d a1, a0
+; RV64IZFINXZDINX-NEXT:    feq.d a0, a0, a0
+; RV64IZFINXZDINX-NEXT:    seqz a0, a0
+; RV64IZFINXZDINX-NEXT:    addi a0, a0, -1
+; RV64IZFINXZDINX-NEXT:    and a0, a0, a1
+; RV64IZFINXZDINX-NEXT:    ret
+  %a = call double @llvm.rint.f64(double %x)
+  %b = call i64 @llvm.fptosi.sat.i64.f64(double %a)
+  ret i64 %b
+}
+
+define signext i32 @test_rint_ui32(double %x) {
+; CHECKIFD-LABEL: test_rint_ui32:
+; CHECKIFD:       # %bb.0:
+; CHECKIFD-NEXT:    fcvt.wu.d a0, fa0
+; CHECKIFD-NEXT:    feq.d a1, fa0, fa0
+; CHECKIFD-NEXT:    seqz a1, a1
+; CHECKIFD-NEXT:    addi a1, a1, -1
+; CHECKIFD-NEXT:    and a0, a1, a0
+; CHECKIFD-NEXT:    ret
+;
+; RV32IZFINXZDINX-LABEL: test_rint_ui32:
+; RV32IZFINXZDINX:       # %bb.0:
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, -16
+; RV32IZFINXZDINX-NEXT:    .cfi_def_cfa_offset 16
+; RV32IZFINXZDINX-NEXT:    sw a0, 8(sp)
+; RV32IZFINXZDINX-NEXT:    sw a1, 12(sp)
+; RV32IZFINXZDINX-NEXT:    lw a0, 8(sp)
+; RV32IZFINXZDINX-NEXT:    lw a1, 12(sp)
+; RV32IZFINXZDINX-NEXT:    fcvt.wu.d a2, a0
+; RV32IZFINXZDINX-NEXT:    feq.d a0, a0, a0
+; RV32IZFINXZDINX-NEXT:    seqz a0, a0
+; RV32IZFINXZDINX-NEXT:    addi a0, a0, -1
+; RV32IZFINXZDINX-NEXT:    and a0, a0, a2
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, 16
+; RV32IZFINXZDINX-NEXT:    ret
+;
+; RV64IZFINXZDINX-LABEL: test_rint_ui32:
+; RV64IZFINXZDINX:       # %bb.0:
+; RV64IZFINXZDINX-NEXT:    fcvt.wu.d a1, a0
+; RV64IZFINXZDINX-NEXT:    feq.d a0, a0, a0
+; RV64IZFINXZDINX-NEXT:    seqz a0, a0
+; RV64IZFINXZDINX-NEXT:    addi a0, a0, -1
+; RV64IZFINXZDINX-NEXT:    and a0, a0, a1
+; RV64IZFINXZDINX-NEXT:    ret
+  %a = call double @llvm.rint.f64(double %x)
+  %b = call i32 @llvm.fptoui.sat.i32.f64(double %a)
+  ret i32 %b
+}
+
+define i64 @test_rint_ui64(double %x) nounwind {
+; RV32IFD-LABEL: test_rint_ui64:
+; RV32IFD:       # %bb.0:
+; RV32IFD-NEXT:    addi sp, sp, -16
+; RV32IFD-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT:    call rint at plt
+; RV32IFD-NEXT:    lui a0, %hi(.LCPI23_0)
+; RV32IFD-NEXT:    fld fa5, %lo(.LCPI23_0)(a0)
+; RV32IFD-NEXT:    flt.d a0, fa5, fa0
+; RV32IFD-NEXT:    neg s0, a0
+; RV32IFD-NEXT:    fcvt.d.w fa5, zero
+; RV32IFD-NEXT:    fle.d a0, fa5, fa0
+; RV32IFD-NEXT:    neg s1, a0
+; RV32IFD-NEXT:    call __fixunsdfdi at plt
+; RV32IFD-NEXT:    and a0, s1, a0
+; RV32IFD-NEXT:    or a0, s0, a0
+; RV32IFD-NEXT:    and a1, s1, a1
+; RV32IFD-NEXT:    or a1, s0, a1
+; RV32IFD-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT:    addi sp, sp, 16
+; RV32IFD-NEXT:    ret
+;
+; RV64IFD-LABEL: test_rint_ui64:
+; RV64IFD:       # %bb.0:
+; RV64IFD-NEXT:    fcvt.lu.d a0, fa0
+; RV64IFD-NEXT:    feq.d a1, fa0, fa0
+; RV64IFD-NEXT:    seqz a1, a1
+; RV64IFD-NEXT:    addi a1, a1, -1
+; RV64IFD-NEXT:    and a0, a1, a0
+; RV64IFD-NEXT:    ret
+;
+; RV32IZFINXZDINX-LABEL: test_rint_ui64:
+; RV32IZFINXZDINX:       # %bb.0:
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, -32
+; RV32IZFINXZDINX-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    call rint at plt
+; RV32IZFINXZDINX-NEXT:    sw a0, 8(sp)
+; RV32IZFINXZDINX-NEXT:    sw a1, 12(sp)
+; RV32IZFINXZDINX-NEXT:    lw s0, 8(sp)
+; RV32IZFINXZDINX-NEXT:    lw s1, 12(sp)
+; RV32IZFINXZDINX-NEXT:    fcvt.d.w a2, zero
+; RV32IZFINXZDINX-NEXT:    fle.d a2, a2, s0
+; RV32IZFINXZDINX-NEXT:    neg s2, a2
+; RV32IZFINXZDINX-NEXT:    call __fixunsdfdi at plt
+; RV32IZFINXZDINX-NEXT:    lui a2, %hi(.LCPI23_0)
+; RV32IZFINXZDINX-NEXT:    lw a3, %lo(.LCPI23_0+4)(a2)
+; RV32IZFINXZDINX-NEXT:    lw a2, %lo(.LCPI23_0)(a2)
+; RV32IZFINXZDINX-NEXT:    and a0, s2, a0
+; RV32IZFINXZDINX-NEXT:    flt.d a2, a2, s0
+; RV32IZFINXZDINX-NEXT:    neg a2, a2
+; RV32IZFINXZDINX-NEXT:    or a0, a2, a0
+; RV32IZFINXZDINX-NEXT:    and a1, s2, a1
+; RV32IZFINXZDINX-NEXT:    or a1, a2, a1
+; RV32IZFINXZDINX-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, 32
+; RV32IZFINXZDINX-NEXT:    ret
+;
+; RV64IZFINXZDINX-LABEL: test_rint_ui64:
+; RV64IZFINXZDINX:       # %bb.0:
+; RV64IZFINXZDINX-NEXT:    fcvt.lu.d a1, a0
+; RV64IZFINXZDINX-NEXT:    feq.d a0, a0, a0
+; RV64IZFINXZDINX-NEXT:    seqz a0, a0
+; RV64IZFINXZDINX-NEXT:    addi a0, a0, -1
+; RV64IZFINXZDINX-NEXT:    and a0, a0, a1
+; RV64IZFINXZDINX-NEXT:    ret
+  %a = call double @llvm.rint.f64(double %x)
+  %b = call i64 @llvm.fptoui.sat.i64.f64(double %a)
+  ret i64 %b
+}
+
 declare double @llvm.floor.f64(double)
 declare double @llvm.ceil.f64(double)
 declare double @llvm.trunc.f64(double)
 declare double @llvm.round.f64(double)
 declare double @llvm.roundeven.f64(double)
+declare double @llvm.rint.f64(double)
 declare i32 @llvm.fptosi.sat.i32.f64(double)
 declare i64 @llvm.fptosi.sat.i64.f64(double)
 declare i32 @llvm.fptoui.sat.i32.f64(double)

diff  --git a/llvm/test/CodeGen/RISCV/float-round-conv-sat.ll b/llvm/test/CodeGen/RISCV/float-round-conv-sat.ll
index 61337216c7fb5b..d947d0f25cdd8f 100644
--- a/llvm/test/CodeGen/RISCV/float-round-conv-sat.ll
+++ b/llvm/test/CodeGen/RISCV/float-round-conv-sat.ll
@@ -1308,11 +1308,272 @@ define i64 @test_roundeven_ui64(float %x) nounwind {
   ret i64 %b
 }
 
+define signext i32 @test_rint_si32(float %x) {
+; CHECKIF-LABEL: test_rint_si32:
+; CHECKIF:       # %bb.0:
+; CHECKIF-NEXT:    fcvt.w.s a0, fa0
+; CHECKIF-NEXT:    feq.s a1, fa0, fa0
+; CHECKIF-NEXT:    seqz a1, a1
+; CHECKIF-NEXT:    addi a1, a1, -1
+; CHECKIF-NEXT:    and a0, a1, a0
+; CHECKIF-NEXT:    ret
+;
+; CHECKIZFINX-LABEL: test_rint_si32:
+; CHECKIZFINX:       # %bb.0:
+; CHECKIZFINX-NEXT:    fcvt.w.s a1, a0
+; CHECKIZFINX-NEXT:    feq.s a0, a0, a0
+; CHECKIZFINX-NEXT:    seqz a0, a0
+; CHECKIZFINX-NEXT:    addi a0, a0, -1
+; CHECKIZFINX-NEXT:    and a0, a0, a1
+; CHECKIZFINX-NEXT:    ret
+  %a = call float @llvm.rint.f32(float %x)
+  %b = call i32 @llvm.fptosi.sat.i32.f32(float %a)
+  ret i32 %b
+}
+
+define i64 @test_rint_si64(float %x) nounwind {
+; RV32IF-LABEL: test_rint_si64:
+; RV32IF:       # %bb.0:
+; RV32IF-NEXT:    addi sp, sp, -16
+; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IF-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IF-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
+; RV32IF-NEXT:    fmv.s fs0, fa0
+; RV32IF-NEXT:    lui a0, 307200
+; RV32IF-NEXT:    fmv.w.x fa5, a0
+; RV32IF-NEXT:    fabs.s fa4, fa0
+; RV32IF-NEXT:    flt.s a0, fa4, fa5
+; RV32IF-NEXT:    beqz a0, .LBB21_2
+; RV32IF-NEXT:  # %bb.1:
+; RV32IF-NEXT:    fcvt.w.s a0, fs0
+; RV32IF-NEXT:    fcvt.s.w fa5, a0
+; RV32IF-NEXT:    fsgnj.s fs0, fa5, fs0
+; RV32IF-NEXT:  .LBB21_2:
+; RV32IF-NEXT:    lui a0, 913408
+; RV32IF-NEXT:    fmv.w.x fa5, a0
+; RV32IF-NEXT:    fle.s s0, fa5, fs0
+; RV32IF-NEXT:    fmv.s fa0, fs0
+; RV32IF-NEXT:    call __fixsfdi at plt
+; RV32IF-NEXT:    lui a4, 524288
+; RV32IF-NEXT:    lui a2, 524288
+; RV32IF-NEXT:    beqz s0, .LBB21_4
+; RV32IF-NEXT:  # %bb.3:
+; RV32IF-NEXT:    mv a2, a1
+; RV32IF-NEXT:  .LBB21_4:
+; RV32IF-NEXT:    lui a1, %hi(.LCPI21_0)
+; RV32IF-NEXT:    flw fa5, %lo(.LCPI21_0)(a1)
+; RV32IF-NEXT:    flt.s a3, fa5, fs0
+; RV32IF-NEXT:    beqz a3, .LBB21_6
+; RV32IF-NEXT:  # %bb.5:
+; RV32IF-NEXT:    addi a2, a4, -1
+; RV32IF-NEXT:  .LBB21_6:
+; RV32IF-NEXT:    feq.s a1, fs0, fs0
+; RV32IF-NEXT:    neg a4, a1
+; RV32IF-NEXT:    and a1, a4, a2
+; RV32IF-NEXT:    neg a2, s0
+; RV32IF-NEXT:    and a0, a2, a0
+; RV32IF-NEXT:    neg a2, a3
+; RV32IF-NEXT:    or a0, a2, a0
+; RV32IF-NEXT:    and a0, a4, a0
+; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IF-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IF-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
+; RV32IF-NEXT:    addi sp, sp, 16
+; RV32IF-NEXT:    ret
+;
+; RV64IF-LABEL: test_rint_si64:
+; RV64IF:       # %bb.0:
+; RV64IF-NEXT:    fcvt.l.s a0, fa0
+; RV64IF-NEXT:    feq.s a1, fa0, fa0
+; RV64IF-NEXT:    seqz a1, a1
+; RV64IF-NEXT:    addi a1, a1, -1
+; RV64IF-NEXT:    and a0, a1, a0
+; RV64IF-NEXT:    ret
+;
+; RV32IZFINX-LABEL: test_rint_si64:
+; RV32IZFINX:       # %bb.0:
+; RV32IZFINX-NEXT:    addi sp, sp, -16
+; RV32IZFINX-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZFINX-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IZFINX-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
+; RV32IZFINX-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
+; RV32IZFINX-NEXT:    mv s0, a0
+; RV32IZFINX-NEXT:    lui a0, 307200
+; RV32IZFINX-NEXT:    fabs.s a1, s0
+; RV32IZFINX-NEXT:    flt.s a0, a1, a0
+; RV32IZFINX-NEXT:    beqz a0, .LBB21_2
+; RV32IZFINX-NEXT:  # %bb.1:
+; RV32IZFINX-NEXT:    fcvt.w.s a0, s0
+; RV32IZFINX-NEXT:    fcvt.s.w a0, a0
+; RV32IZFINX-NEXT:    fsgnj.s s0, a0, s0
+; RV32IZFINX-NEXT:  .LBB21_2:
+; RV32IZFINX-NEXT:    lui a0, 913408
+; RV32IZFINX-NEXT:    fle.s s1, a0, s0
+; RV32IZFINX-NEXT:    neg s2, s1
+; RV32IZFINX-NEXT:    mv a0, s0
+; RV32IZFINX-NEXT:    call __fixsfdi at plt
+; RV32IZFINX-NEXT:    lui a2, %hi(.LCPI21_0)
+; RV32IZFINX-NEXT:    lw a2, %lo(.LCPI21_0)(a2)
+; RV32IZFINX-NEXT:    and a0, s2, a0
+; RV32IZFINX-NEXT:    flt.s a4, a2, s0
+; RV32IZFINX-NEXT:    neg a2, a4
+; RV32IZFINX-NEXT:    or a0, a2, a0
+; RV32IZFINX-NEXT:    feq.s a2, s0, s0
+; RV32IZFINX-NEXT:    neg a2, a2
+; RV32IZFINX-NEXT:    lui a5, 524288
+; RV32IZFINX-NEXT:    lui a3, 524288
+; RV32IZFINX-NEXT:    beqz s1, .LBB21_4
+; RV32IZFINX-NEXT:  # %bb.3:
+; RV32IZFINX-NEXT:    mv a3, a1
+; RV32IZFINX-NEXT:  .LBB21_4:
+; RV32IZFINX-NEXT:    and a0, a2, a0
+; RV32IZFINX-NEXT:    beqz a4, .LBB21_6
+; RV32IZFINX-NEXT:  # %bb.5:
+; RV32IZFINX-NEXT:    addi a3, a5, -1
+; RV32IZFINX-NEXT:  .LBB21_6:
+; RV32IZFINX-NEXT:    and a1, a2, a3
+; RV32IZFINX-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZFINX-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IZFINX-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
+; RV32IZFINX-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
+; RV32IZFINX-NEXT:    addi sp, sp, 16
+; RV32IZFINX-NEXT:    ret
+;
+; RV64IZFINX-LABEL: test_rint_si64:
+; RV64IZFINX:       # %bb.0:
+; RV64IZFINX-NEXT:    fcvt.l.s a1, a0
+; RV64IZFINX-NEXT:    feq.s a0, a0, a0
+; RV64IZFINX-NEXT:    seqz a0, a0
+; RV64IZFINX-NEXT:    addi a0, a0, -1
+; RV64IZFINX-NEXT:    and a0, a0, a1
+; RV64IZFINX-NEXT:    ret
+  %a = call float @llvm.rint.f32(float %x)
+  %b = call i64 @llvm.fptosi.sat.i64.f32(float %a)
+  ret i64 %b
+}
+
+define signext i32 @test_rint_ui32(float %x) {
+; CHECKIF-LABEL: test_rint_ui32:
+; CHECKIF:       # %bb.0:
+; CHECKIF-NEXT:    fcvt.wu.s a0, fa0
+; CHECKIF-NEXT:    feq.s a1, fa0, fa0
+; CHECKIF-NEXT:    seqz a1, a1
+; CHECKIF-NEXT:    addi a1, a1, -1
+; CHECKIF-NEXT:    and a0, a1, a0
+; CHECKIF-NEXT:    ret
+;
+; CHECKIZFINX-LABEL: test_rint_ui32:
+; CHECKIZFINX:       # %bb.0:
+; CHECKIZFINX-NEXT:    fcvt.wu.s a1, a0
+; CHECKIZFINX-NEXT:    feq.s a0, a0, a0
+; CHECKIZFINX-NEXT:    seqz a0, a0
+; CHECKIZFINX-NEXT:    addi a0, a0, -1
+; CHECKIZFINX-NEXT:    and a0, a0, a1
+; CHECKIZFINX-NEXT:    ret
+  %a = call float @llvm.rint.f32(float %x)
+  %b = call i32 @llvm.fptoui.sat.i32.f32(float %a)
+  ret i32 %b
+}
+
+define i64 @test_rint_ui64(float %x) nounwind {
+; RV32IF-LABEL: test_rint_ui64:
+; RV32IF:       # %bb.0:
+; RV32IF-NEXT:    addi sp, sp, -16
+; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IF-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IF-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
+; RV32IF-NEXT:    fmv.s fs0, fa0
+; RV32IF-NEXT:    lui a0, 307200
+; RV32IF-NEXT:    fmv.w.x fa5, a0
+; RV32IF-NEXT:    fabs.s fa4, fa0
+; RV32IF-NEXT:    flt.s a0, fa4, fa5
+; RV32IF-NEXT:    beqz a0, .LBB23_2
+; RV32IF-NEXT:  # %bb.1:
+; RV32IF-NEXT:    fcvt.w.s a0, fs0
+; RV32IF-NEXT:    fcvt.s.w fa5, a0
+; RV32IF-NEXT:    fsgnj.s fs0, fa5, fs0
+; RV32IF-NEXT:  .LBB23_2:
+; RV32IF-NEXT:    fmv.w.x fa5, zero
+; RV32IF-NEXT:    fle.s a0, fa5, fs0
+; RV32IF-NEXT:    neg s0, a0
+; RV32IF-NEXT:    fmv.s fa0, fs0
+; RV32IF-NEXT:    call __fixunssfdi at plt
+; RV32IF-NEXT:    lui a2, %hi(.LCPI23_0)
+; RV32IF-NEXT:    flw fa5, %lo(.LCPI23_0)(a2)
+; RV32IF-NEXT:    and a0, s0, a0
+; RV32IF-NEXT:    flt.s a2, fa5, fs0
+; RV32IF-NEXT:    neg a2, a2
+; RV32IF-NEXT:    or a0, a2, a0
+; RV32IF-NEXT:    and a1, s0, a1
+; RV32IF-NEXT:    or a1, a2, a1
+; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IF-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IF-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
+; RV32IF-NEXT:    addi sp, sp, 16
+; RV32IF-NEXT:    ret
+;
+; RV64IF-LABEL: test_rint_ui64:
+; RV64IF:       # %bb.0:
+; RV64IF-NEXT:    fcvt.lu.s a0, fa0
+; RV64IF-NEXT:    feq.s a1, fa0, fa0
+; RV64IF-NEXT:    seqz a1, a1
+; RV64IF-NEXT:    addi a1, a1, -1
+; RV64IF-NEXT:    and a0, a1, a0
+; RV64IF-NEXT:    ret
+;
+; RV32IZFINX-LABEL: test_rint_ui64:
+; RV32IZFINX:       # %bb.0:
+; RV32IZFINX-NEXT:    addi sp, sp, -16
+; RV32IZFINX-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZFINX-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IZFINX-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
+; RV32IZFINX-NEXT:    mv s0, a0
+; RV32IZFINX-NEXT:    lui a0, 307200
+; RV32IZFINX-NEXT:    fabs.s a1, s0
+; RV32IZFINX-NEXT:    flt.s a0, a1, a0
+; RV32IZFINX-NEXT:    beqz a0, .LBB23_2
+; RV32IZFINX-NEXT:  # %bb.1:
+; RV32IZFINX-NEXT:    fcvt.w.s a0, s0
+; RV32IZFINX-NEXT:    fcvt.s.w a0, a0
+; RV32IZFINX-NEXT:    fsgnj.s s0, a0, s0
+; RV32IZFINX-NEXT:  .LBB23_2:
+; RV32IZFINX-NEXT:    fle.s a0, zero, s0
+; RV32IZFINX-NEXT:    neg s1, a0
+; RV32IZFINX-NEXT:    mv a0, s0
+; RV32IZFINX-NEXT:    call __fixunssfdi at plt
+; RV32IZFINX-NEXT:    lui a2, %hi(.LCPI23_0)
+; RV32IZFINX-NEXT:    lw a2, %lo(.LCPI23_0)(a2)
+; RV32IZFINX-NEXT:    and a0, s1, a0
+; RV32IZFINX-NEXT:    flt.s a2, a2, s0
+; RV32IZFINX-NEXT:    neg a2, a2
+; RV32IZFINX-NEXT:    or a0, a2, a0
+; RV32IZFINX-NEXT:    and a1, s1, a1
+; RV32IZFINX-NEXT:    or a1, a2, a1
+; RV32IZFINX-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZFINX-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IZFINX-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
+; RV32IZFINX-NEXT:    addi sp, sp, 16
+; RV32IZFINX-NEXT:    ret
+;
+; RV64IZFINX-LABEL: test_rint_ui64:
+; RV64IZFINX:       # %bb.0:
+; RV64IZFINX-NEXT:    fcvt.lu.s a1, a0
+; RV64IZFINX-NEXT:    feq.s a0, a0, a0
+; RV64IZFINX-NEXT:    seqz a0, a0
+; RV64IZFINX-NEXT:    addi a0, a0, -1
+; RV64IZFINX-NEXT:    and a0, a0, a1
+; RV64IZFINX-NEXT:    ret
+  %a = call float @llvm.rint.f32(float %x)
+  %b = call i64 @llvm.fptoui.sat.i64.f32(float %a)
+  ret i64 %b
+}
+
 declare float @llvm.floor.f32(float)
 declare float @llvm.ceil.f32(float)
 declare float @llvm.trunc.f32(float)
 declare float @llvm.round.f32(float)
 declare float @llvm.roundeven.f32(float)
+declare float @llvm.rint.f32(float)
 declare i32 @llvm.fptosi.sat.i32.f32(float)
 declare i64 @llvm.fptosi.sat.i64.f32(float)
 declare i32 @llvm.fptoui.sat.i32.f32(float)

diff  --git a/llvm/test/CodeGen/RISCV/half-round-conv-sat.ll b/llvm/test/CodeGen/RISCV/half-round-conv-sat.ll
index e7215f07c22045..962ed8393b7269 100644
--- a/llvm/test/CodeGen/RISCV/half-round-conv-sat.ll
+++ b/llvm/test/CodeGen/RISCV/half-round-conv-sat.ll
@@ -3576,11 +3576,724 @@ define i64 @test_roundeven_ui64(half %x) nounwind {
   ret i64 %b
 }
 
+define signext i32 @test_rint_si32(half %x) {
+; CHECKIZFH-LABEL: test_rint_si32:
+; CHECKIZFH:       # %bb.0:
+; CHECKIZFH-NEXT:    fcvt.w.h a0, fa0
+; CHECKIZFH-NEXT:    feq.h a1, fa0, fa0
+; CHECKIZFH-NEXT:    seqz a1, a1
+; CHECKIZFH-NEXT:    addi a1, a1, -1
+; CHECKIZFH-NEXT:    and a0, a1, a0
+; CHECKIZFH-NEXT:    ret
+;
+; CHECKIZHINX-LABEL: test_rint_si32:
+; CHECKIZHINX:       # %bb.0:
+; CHECKIZHINX-NEXT:    lui a1, %hi(.LCPI20_0)
+; CHECKIZHINX-NEXT:    lh a1, %lo(.LCPI20_0)(a1)
+; CHECKIZHINX-NEXT:    fabs.h a2, a0
+; CHECKIZHINX-NEXT:    flt.h a1, a2, a1
+; CHECKIZHINX-NEXT:    beqz a1, .LBB20_2
+; CHECKIZHINX-NEXT:  # %bb.1:
+; CHECKIZHINX-NEXT:    fcvt.w.h a1, a0
+; CHECKIZHINX-NEXT:    fcvt.h.w a1, a1
+; CHECKIZHINX-NEXT:    fsgnj.h a0, a1, a0
+; CHECKIZHINX-NEXT:  .LBB20_2:
+; CHECKIZHINX-NEXT:    fcvt.w.h a1, a0, rtz
+; CHECKIZHINX-NEXT:    feq.h a0, a0, a0
+; CHECKIZHINX-NEXT:    seqz a0, a0
+; CHECKIZHINX-NEXT:    addi a0, a0, -1
+; CHECKIZHINX-NEXT:    and a0, a0, a1
+; CHECKIZHINX-NEXT:    ret
+;
+; CHECKIZFHMIN-LABEL: test_rint_si32:
+; CHECKIZFHMIN:       # %bb.0:
+; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; CHECKIZFHMIN-NEXT:    lui a0, 307200
+; CHECKIZFHMIN-NEXT:    fmv.w.x fa4, a0
+; CHECKIZFHMIN-NEXT:    fabs.s fa3, fa5
+; CHECKIZFHMIN-NEXT:    flt.s a0, fa3, fa4
+; CHECKIZFHMIN-NEXT:    beqz a0, .LBB20_2
+; CHECKIZFHMIN-NEXT:  # %bb.1:
+; CHECKIZFHMIN-NEXT:    fcvt.w.s a0, fa5
+; CHECKIZFHMIN-NEXT:    fcvt.s.w fa4, a0
+; CHECKIZFHMIN-NEXT:    fsgnj.s fa5, fa4, fa5
+; CHECKIZFHMIN-NEXT:  .LBB20_2:
+; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
+; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
+; CHECKIZFHMIN-NEXT:    fcvt.w.s a0, fa5, rtz
+; CHECKIZFHMIN-NEXT:    feq.s a1, fa5, fa5
+; CHECKIZFHMIN-NEXT:    seqz a1, a1
+; CHECKIZFHMIN-NEXT:    addi a1, a1, -1
+; CHECKIZFHMIN-NEXT:    and a0, a1, a0
+; CHECKIZFHMIN-NEXT:    ret
+;
+; CHECKIZHINXMIN-LABEL: test_rint_si32:
+; CHECKIZHINXMIN:       # %bb.0:
+; CHECKIZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; CHECKIZHINXMIN-NEXT:    lui a1, 307200
+; CHECKIZHINXMIN-NEXT:    fabs.s a2, a0
+; CHECKIZHINXMIN-NEXT:    flt.s a1, a2, a1
+; CHECKIZHINXMIN-NEXT:    beqz a1, .LBB20_2
+; CHECKIZHINXMIN-NEXT:  # %bb.1:
+; CHECKIZHINXMIN-NEXT:    fcvt.w.s a1, a0
+; CHECKIZHINXMIN-NEXT:    fcvt.s.w a1, a1
+; CHECKIZHINXMIN-NEXT:    fsgnj.s a0, a1, a0
+; CHECKIZHINXMIN-NEXT:  .LBB20_2:
+; CHECKIZHINXMIN-NEXT:    fcvt.h.s a0, a0
+; CHECKIZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; CHECKIZHINXMIN-NEXT:    fcvt.w.s a1, a0, rtz
+; CHECKIZHINXMIN-NEXT:    feq.s a0, a0, a0
+; CHECKIZHINXMIN-NEXT:    seqz a0, a0
+; CHECKIZHINXMIN-NEXT:    addi a0, a0, -1
+; CHECKIZHINXMIN-NEXT:    and a0, a0, a1
+; CHECKIZHINXMIN-NEXT:    ret
+  %a = call half @llvm.rint.f16(half %x)
+  %b = call i32 @llvm.fptosi.sat.i32.f16(half %a)
+  ret i32 %b
+}
+
+define i64 @test_rint_si64(half %x) nounwind {
+; RV32IZFH-LABEL: test_rint_si64:
+; RV32IZFH:       # %bb.0:
+; RV32IZFH-NEXT:    lui a0, %hi(.LCPI21_0)
+; RV32IZFH-NEXT:    flh fa5, %lo(.LCPI21_0)(a0)
+; RV32IZFH-NEXT:    fabs.h fa4, fa0
+; RV32IZFH-NEXT:    flt.h a0, fa4, fa5
+; RV32IZFH-NEXT:    beqz a0, .LBB21_2
+; RV32IZFH-NEXT:  # %bb.1:
+; RV32IZFH-NEXT:    fcvt.w.h a0, fa0
+; RV32IZFH-NEXT:    fcvt.h.w fa5, a0
+; RV32IZFH-NEXT:    fsgnj.h fa0, fa5, fa0
+; RV32IZFH-NEXT:  .LBB21_2:
+; RV32IZFH-NEXT:    addi sp, sp, -16
+; RV32IZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZFH-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IZFH-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
+; RV32IZFH-NEXT:    fcvt.s.h fs0, fa0
+; RV32IZFH-NEXT:    lui a0, 913408
+; RV32IZFH-NEXT:    fmv.w.x fa5, a0
+; RV32IZFH-NEXT:    fle.s s0, fa5, fs0
+; RV32IZFH-NEXT:    fmv.s fa0, fs0
+; RV32IZFH-NEXT:    call __fixsfdi at plt
+; RV32IZFH-NEXT:    lui a4, 524288
+; RV32IZFH-NEXT:    lui a2, 524288
+; RV32IZFH-NEXT:    beqz s0, .LBB21_4
+; RV32IZFH-NEXT:  # %bb.3:
+; RV32IZFH-NEXT:    mv a2, a1
+; RV32IZFH-NEXT:  .LBB21_4:
+; RV32IZFH-NEXT:    lui a1, %hi(.LCPI21_1)
+; RV32IZFH-NEXT:    flw fa5, %lo(.LCPI21_1)(a1)
+; RV32IZFH-NEXT:    flt.s a3, fa5, fs0
+; RV32IZFH-NEXT:    beqz a3, .LBB21_6
+; RV32IZFH-NEXT:  # %bb.5:
+; RV32IZFH-NEXT:    addi a2, a4, -1
+; RV32IZFH-NEXT:  .LBB21_6:
+; RV32IZFH-NEXT:    feq.s a1, fs0, fs0
+; RV32IZFH-NEXT:    neg a4, a1
+; RV32IZFH-NEXT:    and a1, a4, a2
+; RV32IZFH-NEXT:    neg a2, s0
+; RV32IZFH-NEXT:    and a0, a2, a0
+; RV32IZFH-NEXT:    neg a2, a3
+; RV32IZFH-NEXT:    or a0, a2, a0
+; RV32IZFH-NEXT:    and a0, a4, a0
+; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZFH-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IZFH-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
+; RV32IZFH-NEXT:    addi sp, sp, 16
+; RV32IZFH-NEXT:    ret
+;
+; RV64IZFH-LABEL: test_rint_si64:
+; RV64IZFH:       # %bb.0:
+; RV64IZFH-NEXT:    fcvt.l.h a0, fa0
+; RV64IZFH-NEXT:    feq.h a1, fa0, fa0
+; RV64IZFH-NEXT:    seqz a1, a1
+; RV64IZFH-NEXT:    addi a1, a1, -1
+; RV64IZFH-NEXT:    and a0, a1, a0
+; RV64IZFH-NEXT:    ret
+;
+; RV32IZHINX-LABEL: test_rint_si64:
+; RV32IZHINX:       # %bb.0:
+; RV32IZHINX-NEXT:    lui a1, %hi(.LCPI21_0)
+; RV32IZHINX-NEXT:    lh a1, %lo(.LCPI21_0)(a1)
+; RV32IZHINX-NEXT:    fabs.h a2, a0
+; RV32IZHINX-NEXT:    flt.h a1, a2, a1
+; RV32IZHINX-NEXT:    beqz a1, .LBB21_2
+; RV32IZHINX-NEXT:  # %bb.1:
+; RV32IZHINX-NEXT:    fcvt.w.h a1, a0
+; RV32IZHINX-NEXT:    fcvt.h.w a1, a1
+; RV32IZHINX-NEXT:    fsgnj.h a0, a1, a0
+; RV32IZHINX-NEXT:  .LBB21_2:
+; RV32IZHINX-NEXT:    addi sp, sp, -16
+; RV32IZHINX-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZHINX-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IZHINX-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
+; RV32IZHINX-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
+; RV32IZHINX-NEXT:    fcvt.s.h s0, a0
+; RV32IZHINX-NEXT:    lui a0, 913408
+; RV32IZHINX-NEXT:    fle.s s1, a0, s0
+; RV32IZHINX-NEXT:    neg s2, s1
+; RV32IZHINX-NEXT:    mv a0, s0
+; RV32IZHINX-NEXT:    call __fixsfdi at plt
+; RV32IZHINX-NEXT:    lui a2, %hi(.LCPI21_1)
+; RV32IZHINX-NEXT:    lw a2, %lo(.LCPI21_1)(a2)
+; RV32IZHINX-NEXT:    and a0, s2, a0
+; RV32IZHINX-NEXT:    flt.s a4, a2, s0
+; RV32IZHINX-NEXT:    neg a2, a4
+; RV32IZHINX-NEXT:    or a0, a2, a0
+; RV32IZHINX-NEXT:    feq.s a2, s0, s0
+; RV32IZHINX-NEXT:    neg a2, a2
+; RV32IZHINX-NEXT:    lui a5, 524288
+; RV32IZHINX-NEXT:    lui a3, 524288
+; RV32IZHINX-NEXT:    beqz s1, .LBB21_4
+; RV32IZHINX-NEXT:  # %bb.3:
+; RV32IZHINX-NEXT:    mv a3, a1
+; RV32IZHINX-NEXT:  .LBB21_4:
+; RV32IZHINX-NEXT:    and a0, a2, a0
+; RV32IZHINX-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZHINX-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IZHINX-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
+; RV32IZHINX-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
+; RV32IZHINX-NEXT:    addi sp, sp, 16
+; RV32IZHINX-NEXT:    beqz a4, .LBB21_6
+; RV32IZHINX-NEXT:  # %bb.5:
+; RV32IZHINX-NEXT:    addi a3, a5, -1
+; RV32IZHINX-NEXT:  .LBB21_6:
+; RV32IZHINX-NEXT:    and a1, a2, a3
+; RV32IZHINX-NEXT:    ret
+;
+; RV64IZHINX-LABEL: test_rint_si64:
+; RV64IZHINX:       # %bb.0:
+; RV64IZHINX-NEXT:    lui a1, %hi(.LCPI21_0)
+; RV64IZHINX-NEXT:    lh a1, %lo(.LCPI21_0)(a1)
+; RV64IZHINX-NEXT:    fabs.h a2, a0
+; RV64IZHINX-NEXT:    flt.h a1, a2, a1
+; RV64IZHINX-NEXT:    beqz a1, .LBB21_2
+; RV64IZHINX-NEXT:  # %bb.1:
+; RV64IZHINX-NEXT:    fcvt.w.h a1, a0
+; RV64IZHINX-NEXT:    fcvt.h.w a1, a1
+; RV64IZHINX-NEXT:    fsgnj.h a0, a1, a0
+; RV64IZHINX-NEXT:  .LBB21_2:
+; RV64IZHINX-NEXT:    fcvt.l.h a1, a0, rtz
+; RV64IZHINX-NEXT:    feq.h a0, a0, a0
+; RV64IZHINX-NEXT:    seqz a0, a0
+; RV64IZHINX-NEXT:    addi a0, a0, -1
+; RV64IZHINX-NEXT:    and a0, a0, a1
+; RV64IZHINX-NEXT:    ret
+;
+; RV32IZFHMIN-LABEL: test_rint_si64:
+; RV32IZFHMIN:       # %bb.0:
+; RV32IZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; RV32IZFHMIN-NEXT:    lui a0, 307200
+; RV32IZFHMIN-NEXT:    fmv.w.x fa4, a0
+; RV32IZFHMIN-NEXT:    fabs.s fa3, fa5
+; RV32IZFHMIN-NEXT:    flt.s a0, fa3, fa4
+; RV32IZFHMIN-NEXT:    beqz a0, .LBB21_2
+; RV32IZFHMIN-NEXT:  # %bb.1:
+; RV32IZFHMIN-NEXT:    fcvt.w.s a0, fa5
+; RV32IZFHMIN-NEXT:    fcvt.s.w fa4, a0
+; RV32IZFHMIN-NEXT:    fsgnj.s fa5, fa4, fa5
+; RV32IZFHMIN-NEXT:  .LBB21_2:
+; RV32IZFHMIN-NEXT:    addi sp, sp, -16
+; RV32IZFHMIN-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZFHMIN-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IZFHMIN-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
+; RV32IZFHMIN-NEXT:    fcvt.h.s fa5, fa5
+; RV32IZFHMIN-NEXT:    fcvt.s.h fs0, fa5
+; RV32IZFHMIN-NEXT:    lui a0, 913408
+; RV32IZFHMIN-NEXT:    fmv.w.x fa5, a0
+; RV32IZFHMIN-NEXT:    fle.s s0, fa5, fs0
+; RV32IZFHMIN-NEXT:    fmv.s fa0, fs0
+; RV32IZFHMIN-NEXT:    call __fixsfdi at plt
+; RV32IZFHMIN-NEXT:    lui a4, 524288
+; RV32IZFHMIN-NEXT:    lui a2, 524288
+; RV32IZFHMIN-NEXT:    beqz s0, .LBB21_4
+; RV32IZFHMIN-NEXT:  # %bb.3:
+; RV32IZFHMIN-NEXT:    mv a2, a1
+; RV32IZFHMIN-NEXT:  .LBB21_4:
+; RV32IZFHMIN-NEXT:    lui a1, %hi(.LCPI21_0)
+; RV32IZFHMIN-NEXT:    flw fa5, %lo(.LCPI21_0)(a1)
+; RV32IZFHMIN-NEXT:    flt.s a3, fa5, fs0
+; RV32IZFHMIN-NEXT:    beqz a3, .LBB21_6
+; RV32IZFHMIN-NEXT:  # %bb.5:
+; RV32IZFHMIN-NEXT:    addi a2, a4, -1
+; RV32IZFHMIN-NEXT:  .LBB21_6:
+; RV32IZFHMIN-NEXT:    feq.s a1, fs0, fs0
+; RV32IZFHMIN-NEXT:    neg a4, a1
+; RV32IZFHMIN-NEXT:    and a1, a4, a2
+; RV32IZFHMIN-NEXT:    neg a2, s0
+; RV32IZFHMIN-NEXT:    and a0, a2, a0
+; RV32IZFHMIN-NEXT:    neg a2, a3
+; RV32IZFHMIN-NEXT:    or a0, a2, a0
+; RV32IZFHMIN-NEXT:    and a0, a4, a0
+; RV32IZFHMIN-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZFHMIN-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IZFHMIN-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
+; RV32IZFHMIN-NEXT:    addi sp, sp, 16
+; RV32IZFHMIN-NEXT:    ret
+;
+; RV64IZFHMIN-LABEL: test_rint_si64:
+; RV64IZFHMIN:       # %bb.0:
+; RV64IZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; RV64IZFHMIN-NEXT:    lui a0, 307200
+; RV64IZFHMIN-NEXT:    fmv.w.x fa4, a0
+; RV64IZFHMIN-NEXT:    fabs.s fa3, fa5
+; RV64IZFHMIN-NEXT:    flt.s a0, fa3, fa4
+; RV64IZFHMIN-NEXT:    beqz a0, .LBB21_2
+; RV64IZFHMIN-NEXT:  # %bb.1:
+; RV64IZFHMIN-NEXT:    fcvt.w.s a0, fa5
+; RV64IZFHMIN-NEXT:    fcvt.s.w fa4, a0
+; RV64IZFHMIN-NEXT:    fsgnj.s fa5, fa4, fa5
+; RV64IZFHMIN-NEXT:  .LBB21_2:
+; RV64IZFHMIN-NEXT:    fcvt.h.s fa5, fa5
+; RV64IZFHMIN-NEXT:    fcvt.s.h fa5, fa5
+; RV64IZFHMIN-NEXT:    fcvt.l.s a0, fa5, rtz
+; RV64IZFHMIN-NEXT:    feq.s a1, fa5, fa5
+; RV64IZFHMIN-NEXT:    seqz a1, a1
+; RV64IZFHMIN-NEXT:    addi a1, a1, -1
+; RV64IZFHMIN-NEXT:    and a0, a1, a0
+; RV64IZFHMIN-NEXT:    ret
+;
+; RV32IZHINXMIN-LABEL: test_rint_si64:
+; RV32IZHINXMIN:       # %bb.0:
+; RV32IZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; RV32IZHINXMIN-NEXT:    lui a1, 307200
+; RV32IZHINXMIN-NEXT:    fabs.s a2, a0
+; RV32IZHINXMIN-NEXT:    flt.s a1, a2, a1
+; RV32IZHINXMIN-NEXT:    beqz a1, .LBB21_2
+; RV32IZHINXMIN-NEXT:  # %bb.1:
+; RV32IZHINXMIN-NEXT:    fcvt.w.s a1, a0
+; RV32IZHINXMIN-NEXT:    fcvt.s.w a1, a1
+; RV32IZHINXMIN-NEXT:    fsgnj.s a0, a1, a0
+; RV32IZHINXMIN-NEXT:  .LBB21_2:
+; RV32IZHINXMIN-NEXT:    addi sp, sp, -16
+; RV32IZHINXMIN-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZHINXMIN-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IZHINXMIN-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
+; RV32IZHINXMIN-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
+; RV32IZHINXMIN-NEXT:    fcvt.h.s a0, a0
+; RV32IZHINXMIN-NEXT:    fcvt.s.h s0, a0
+; RV32IZHINXMIN-NEXT:    lui a0, 913408
+; RV32IZHINXMIN-NEXT:    fle.s s1, a0, s0
+; RV32IZHINXMIN-NEXT:    neg s2, s1
+; RV32IZHINXMIN-NEXT:    mv a0, s0
+; RV32IZHINXMIN-NEXT:    call __fixsfdi at plt
+; RV32IZHINXMIN-NEXT:    lui a2, %hi(.LCPI21_0)
+; RV32IZHINXMIN-NEXT:    lw a2, %lo(.LCPI21_0)(a2)
+; RV32IZHINXMIN-NEXT:    and a0, s2, a0
+; RV32IZHINXMIN-NEXT:    flt.s a4, a2, s0
+; RV32IZHINXMIN-NEXT:    neg a2, a4
+; RV32IZHINXMIN-NEXT:    or a0, a2, a0
+; RV32IZHINXMIN-NEXT:    feq.s a2, s0, s0
+; RV32IZHINXMIN-NEXT:    neg a2, a2
+; RV32IZHINXMIN-NEXT:    lui a5, 524288
+; RV32IZHINXMIN-NEXT:    lui a3, 524288
+; RV32IZHINXMIN-NEXT:    beqz s1, .LBB21_4
+; RV32IZHINXMIN-NEXT:  # %bb.3:
+; RV32IZHINXMIN-NEXT:    mv a3, a1
+; RV32IZHINXMIN-NEXT:  .LBB21_4:
+; RV32IZHINXMIN-NEXT:    and a0, a2, a0
+; RV32IZHINXMIN-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZHINXMIN-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IZHINXMIN-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
+; RV32IZHINXMIN-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
+; RV32IZHINXMIN-NEXT:    addi sp, sp, 16
+; RV32IZHINXMIN-NEXT:    beqz a4, .LBB21_6
+; RV32IZHINXMIN-NEXT:  # %bb.5:
+; RV32IZHINXMIN-NEXT:    addi a3, a5, -1
+; RV32IZHINXMIN-NEXT:  .LBB21_6:
+; RV32IZHINXMIN-NEXT:    and a1, a2, a3
+; RV32IZHINXMIN-NEXT:    ret
+;
+; RV64IZHINXMIN-LABEL: test_rint_si64:
+; RV64IZHINXMIN:       # %bb.0:
+; RV64IZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; RV64IZHINXMIN-NEXT:    lui a1, 307200
+; RV64IZHINXMIN-NEXT:    fabs.s a2, a0
+; RV64IZHINXMIN-NEXT:    flt.s a1, a2, a1
+; RV64IZHINXMIN-NEXT:    beqz a1, .LBB21_2
+; RV64IZHINXMIN-NEXT:  # %bb.1:
+; RV64IZHINXMIN-NEXT:    fcvt.w.s a1, a0
+; RV64IZHINXMIN-NEXT:    fcvt.s.w a1, a1
+; RV64IZHINXMIN-NEXT:    fsgnj.s a0, a1, a0
+; RV64IZHINXMIN-NEXT:  .LBB21_2:
+; RV64IZHINXMIN-NEXT:    fcvt.h.s a0, a0
+; RV64IZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; RV64IZHINXMIN-NEXT:    fcvt.l.s a1, a0, rtz
+; RV64IZHINXMIN-NEXT:    feq.s a0, a0, a0
+; RV64IZHINXMIN-NEXT:    seqz a0, a0
+; RV64IZHINXMIN-NEXT:    addi a0, a0, -1
+; RV64IZHINXMIN-NEXT:    and a0, a0, a1
+; RV64IZHINXMIN-NEXT:    ret
+  %a = call half @llvm.rint.f16(half %x)
+  %b = call i64 @llvm.fptosi.sat.i64.f16(half %a)
+  ret i64 %b
+}
+
+define signext i32 @test_rint_ui32(half %x) {
+; CHECKIZFH-LABEL: test_rint_ui32:
+; CHECKIZFH:       # %bb.0:
+; CHECKIZFH-NEXT:    fcvt.wu.h a0, fa0
+; CHECKIZFH-NEXT:    feq.h a1, fa0, fa0
+; CHECKIZFH-NEXT:    seqz a1, a1
+; CHECKIZFH-NEXT:    addi a1, a1, -1
+; CHECKIZFH-NEXT:    and a0, a1, a0
+; CHECKIZFH-NEXT:    ret
+;
+; RV32IZHINX-LABEL: test_rint_ui32:
+; RV32IZHINX:       # %bb.0:
+; RV32IZHINX-NEXT:    lui a1, %hi(.LCPI22_0)
+; RV32IZHINX-NEXT:    lh a1, %lo(.LCPI22_0)(a1)
+; RV32IZHINX-NEXT:    fabs.h a2, a0
+; RV32IZHINX-NEXT:    flt.h a1, a2, a1
+; RV32IZHINX-NEXT:    beqz a1, .LBB22_2
+; RV32IZHINX-NEXT:  # %bb.1:
+; RV32IZHINX-NEXT:    fcvt.w.h a1, a0
+; RV32IZHINX-NEXT:    fcvt.h.w a1, a1
+; RV32IZHINX-NEXT:    fsgnj.h a0, a1, a0
+; RV32IZHINX-NEXT:  .LBB22_2:
+; RV32IZHINX-NEXT:    fcvt.wu.h a1, a0, rtz
+; RV32IZHINX-NEXT:    feq.h a0, a0, a0
+; RV32IZHINX-NEXT:    seqz a0, a0
+; RV32IZHINX-NEXT:    addi a0, a0, -1
+; RV32IZHINX-NEXT:    and a0, a0, a1
+; RV32IZHINX-NEXT:    ret
+;
+; RV64IZHINX-LABEL: test_rint_ui32:
+; RV64IZHINX:       # %bb.0:
+; RV64IZHINX-NEXT:    lui a1, %hi(.LCPI22_0)
+; RV64IZHINX-NEXT:    lh a1, %lo(.LCPI22_0)(a1)
+; RV64IZHINX-NEXT:    fabs.h a2, a0
+; RV64IZHINX-NEXT:    flt.h a1, a2, a1
+; RV64IZHINX-NEXT:    beqz a1, .LBB22_2
+; RV64IZHINX-NEXT:  # %bb.1:
+; RV64IZHINX-NEXT:    fcvt.w.h a1, a0
+; RV64IZHINX-NEXT:    fcvt.h.w a1, a1
+; RV64IZHINX-NEXT:    fsgnj.h a0, a1, a0
+; RV64IZHINX-NEXT:  .LBB22_2:
+; RV64IZHINX-NEXT:    fcvt.wu.h a1, a0, rtz
+; RV64IZHINX-NEXT:    feq.h a0, a0, a0
+; RV64IZHINX-NEXT:    seqz a0, a0
+; RV64IZHINX-NEXT:    addi a0, a0, -1
+; RV64IZHINX-NEXT:    and a0, a1, a0
+; RV64IZHINX-NEXT:    ret
+;
+; RV32IZFHMIN-LABEL: test_rint_ui32:
+; RV32IZFHMIN:       # %bb.0:
+; RV32IZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; RV32IZFHMIN-NEXT:    lui a0, 307200
+; RV32IZFHMIN-NEXT:    fmv.w.x fa4, a0
+; RV32IZFHMIN-NEXT:    fabs.s fa3, fa5
+; RV32IZFHMIN-NEXT:    flt.s a0, fa3, fa4
+; RV32IZFHMIN-NEXT:    beqz a0, .LBB22_2
+; RV32IZFHMIN-NEXT:  # %bb.1:
+; RV32IZFHMIN-NEXT:    fcvt.w.s a0, fa5
+; RV32IZFHMIN-NEXT:    fcvt.s.w fa4, a0
+; RV32IZFHMIN-NEXT:    fsgnj.s fa5, fa4, fa5
+; RV32IZFHMIN-NEXT:  .LBB22_2:
+; RV32IZFHMIN-NEXT:    fcvt.h.s fa5, fa5
+; RV32IZFHMIN-NEXT:    fcvt.s.h fa5, fa5
+; RV32IZFHMIN-NEXT:    fcvt.wu.s a0, fa5, rtz
+; RV32IZFHMIN-NEXT:    feq.s a1, fa5, fa5
+; RV32IZFHMIN-NEXT:    seqz a1, a1
+; RV32IZFHMIN-NEXT:    addi a1, a1, -1
+; RV32IZFHMIN-NEXT:    and a0, a1, a0
+; RV32IZFHMIN-NEXT:    ret
+;
+; RV64IZFHMIN-LABEL: test_rint_ui32:
+; RV64IZFHMIN:       # %bb.0:
+; RV64IZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; RV64IZFHMIN-NEXT:    lui a0, 307200
+; RV64IZFHMIN-NEXT:    fmv.w.x fa4, a0
+; RV64IZFHMIN-NEXT:    fabs.s fa3, fa5
+; RV64IZFHMIN-NEXT:    flt.s a0, fa3, fa4
+; RV64IZFHMIN-NEXT:    beqz a0, .LBB22_2
+; RV64IZFHMIN-NEXT:  # %bb.1:
+; RV64IZFHMIN-NEXT:    fcvt.w.s a0, fa5
+; RV64IZFHMIN-NEXT:    fcvt.s.w fa4, a0
+; RV64IZFHMIN-NEXT:    fsgnj.s fa5, fa4, fa5
+; RV64IZFHMIN-NEXT:  .LBB22_2:
+; RV64IZFHMIN-NEXT:    fcvt.h.s fa5, fa5
+; RV64IZFHMIN-NEXT:    fcvt.s.h fa5, fa5
+; RV64IZFHMIN-NEXT:    fcvt.wu.s a0, fa5, rtz
+; RV64IZFHMIN-NEXT:    feq.s a1, fa5, fa5
+; RV64IZFHMIN-NEXT:    seqz a1, a1
+; RV64IZFHMIN-NEXT:    addi a1, a1, -1
+; RV64IZFHMIN-NEXT:    and a0, a0, a1
+; RV64IZFHMIN-NEXT:    ret
+;
+; RV32IZHINXMIN-LABEL: test_rint_ui32:
+; RV32IZHINXMIN:       # %bb.0:
+; RV32IZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; RV32IZHINXMIN-NEXT:    lui a1, 307200
+; RV32IZHINXMIN-NEXT:    fabs.s a2, a0
+; RV32IZHINXMIN-NEXT:    flt.s a1, a2, a1
+; RV32IZHINXMIN-NEXT:    beqz a1, .LBB22_2
+; RV32IZHINXMIN-NEXT:  # %bb.1:
+; RV32IZHINXMIN-NEXT:    fcvt.w.s a1, a0
+; RV32IZHINXMIN-NEXT:    fcvt.s.w a1, a1
+; RV32IZHINXMIN-NEXT:    fsgnj.s a0, a1, a0
+; RV32IZHINXMIN-NEXT:  .LBB22_2:
+; RV32IZHINXMIN-NEXT:    fcvt.h.s a0, a0
+; RV32IZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; RV32IZHINXMIN-NEXT:    fcvt.wu.s a1, a0, rtz
+; RV32IZHINXMIN-NEXT:    feq.s a0, a0, a0
+; RV32IZHINXMIN-NEXT:    seqz a0, a0
+; RV32IZHINXMIN-NEXT:    addi a0, a0, -1
+; RV32IZHINXMIN-NEXT:    and a0, a0, a1
+; RV32IZHINXMIN-NEXT:    ret
+;
+; RV64IZHINXMIN-LABEL: test_rint_ui32:
+; RV64IZHINXMIN:       # %bb.0:
+; RV64IZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; RV64IZHINXMIN-NEXT:    lui a1, 307200
+; RV64IZHINXMIN-NEXT:    fabs.s a2, a0
+; RV64IZHINXMIN-NEXT:    flt.s a1, a2, a1
+; RV64IZHINXMIN-NEXT:    beqz a1, .LBB22_2
+; RV64IZHINXMIN-NEXT:  # %bb.1:
+; RV64IZHINXMIN-NEXT:    fcvt.w.s a1, a0
+; RV64IZHINXMIN-NEXT:    fcvt.s.w a1, a1
+; RV64IZHINXMIN-NEXT:    fsgnj.s a0, a1, a0
+; RV64IZHINXMIN-NEXT:  .LBB22_2:
+; RV64IZHINXMIN-NEXT:    fcvt.h.s a0, a0
+; RV64IZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; RV64IZHINXMIN-NEXT:    fcvt.wu.s a1, a0, rtz
+; RV64IZHINXMIN-NEXT:    feq.s a0, a0, a0
+; RV64IZHINXMIN-NEXT:    seqz a0, a0
+; RV64IZHINXMIN-NEXT:    addi a0, a0, -1
+; RV64IZHINXMIN-NEXT:    and a0, a1, a0
+; RV64IZHINXMIN-NEXT:    ret
+  %a = call half @llvm.rint.f16(half %x)
+  %b = call i32 @llvm.fptoui.sat.i32.f16(half %a)
+  ret i32 %b
+}
+
+define i64 @test_rint_ui64(half %x) nounwind {
+; RV32IZFH-LABEL: test_rint_ui64:
+; RV32IZFH:       # %bb.0:
+; RV32IZFH-NEXT:    lui a0, %hi(.LCPI23_0)
+; RV32IZFH-NEXT:    flh fa5, %lo(.LCPI23_0)(a0)
+; RV32IZFH-NEXT:    fabs.h fa4, fa0
+; RV32IZFH-NEXT:    flt.h a0, fa4, fa5
+; RV32IZFH-NEXT:    beqz a0, .LBB23_2
+; RV32IZFH-NEXT:  # %bb.1:
+; RV32IZFH-NEXT:    fcvt.w.h a0, fa0
+; RV32IZFH-NEXT:    fcvt.h.w fa5, a0
+; RV32IZFH-NEXT:    fsgnj.h fa0, fa5, fa0
+; RV32IZFH-NEXT:  .LBB23_2:
+; RV32IZFH-NEXT:    addi sp, sp, -16
+; RV32IZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZFH-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IZFH-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
+; RV32IZFH-NEXT:    fcvt.s.h fs0, fa0
+; RV32IZFH-NEXT:    fmv.w.x fa5, zero
+; RV32IZFH-NEXT:    fle.s a0, fa5, fs0
+; RV32IZFH-NEXT:    neg s0, a0
+; RV32IZFH-NEXT:    fmv.s fa0, fs0
+; RV32IZFH-NEXT:    call __fixunssfdi at plt
+; RV32IZFH-NEXT:    lui a2, %hi(.LCPI23_1)
+; RV32IZFH-NEXT:    flw fa5, %lo(.LCPI23_1)(a2)
+; RV32IZFH-NEXT:    and a0, s0, a0
+; RV32IZFH-NEXT:    flt.s a2, fa5, fs0
+; RV32IZFH-NEXT:    neg a2, a2
+; RV32IZFH-NEXT:    or a0, a2, a0
+; RV32IZFH-NEXT:    and a1, s0, a1
+; RV32IZFH-NEXT:    or a1, a2, a1
+; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZFH-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IZFH-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
+; RV32IZFH-NEXT:    addi sp, sp, 16
+; RV32IZFH-NEXT:    ret
+;
+; RV64IZFH-LABEL: test_rint_ui64:
+; RV64IZFH:       # %bb.0:
+; RV64IZFH-NEXT:    fcvt.lu.h a0, fa0
+; RV64IZFH-NEXT:    feq.h a1, fa0, fa0
+; RV64IZFH-NEXT:    seqz a1, a1
+; RV64IZFH-NEXT:    addi a1, a1, -1
+; RV64IZFH-NEXT:    and a0, a1, a0
+; RV64IZFH-NEXT:    ret
+;
+; RV32IZHINX-LABEL: test_rint_ui64:
+; RV32IZHINX:       # %bb.0:
+; RV32IZHINX-NEXT:    lui a1, %hi(.LCPI23_0)
+; RV32IZHINX-NEXT:    lh a1, %lo(.LCPI23_0)(a1)
+; RV32IZHINX-NEXT:    fabs.h a2, a0
+; RV32IZHINX-NEXT:    flt.h a1, a2, a1
+; RV32IZHINX-NEXT:    beqz a1, .LBB23_2
+; RV32IZHINX-NEXT:  # %bb.1:
+; RV32IZHINX-NEXT:    fcvt.w.h a1, a0
+; RV32IZHINX-NEXT:    fcvt.h.w a1, a1
+; RV32IZHINX-NEXT:    fsgnj.h a0, a1, a0
+; RV32IZHINX-NEXT:  .LBB23_2:
+; RV32IZHINX-NEXT:    addi sp, sp, -16
+; RV32IZHINX-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZHINX-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IZHINX-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
+; RV32IZHINX-NEXT:    fcvt.s.h s0, a0
+; RV32IZHINX-NEXT:    fle.s a0, zero, s0
+; RV32IZHINX-NEXT:    neg s1, a0
+; RV32IZHINX-NEXT:    mv a0, s0
+; RV32IZHINX-NEXT:    call __fixunssfdi at plt
+; RV32IZHINX-NEXT:    lui a2, %hi(.LCPI23_1)
+; RV32IZHINX-NEXT:    lw a2, %lo(.LCPI23_1)(a2)
+; RV32IZHINX-NEXT:    and a0, s1, a0
+; RV32IZHINX-NEXT:    flt.s a2, a2, s0
+; RV32IZHINX-NEXT:    neg a2, a2
+; RV32IZHINX-NEXT:    or a0, a2, a0
+; RV32IZHINX-NEXT:    and a1, s1, a1
+; RV32IZHINX-NEXT:    or a1, a2, a1
+; RV32IZHINX-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZHINX-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IZHINX-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
+; RV32IZHINX-NEXT:    addi sp, sp, 16
+; RV32IZHINX-NEXT:    ret
+;
+; RV64IZHINX-LABEL: test_rint_ui64:
+; RV64IZHINX:       # %bb.0:
+; RV64IZHINX-NEXT:    lui a1, %hi(.LCPI23_0)
+; RV64IZHINX-NEXT:    lh a1, %lo(.LCPI23_0)(a1)
+; RV64IZHINX-NEXT:    fabs.h a2, a0
+; RV64IZHINX-NEXT:    flt.h a1, a2, a1
+; RV64IZHINX-NEXT:    beqz a1, .LBB23_2
+; RV64IZHINX-NEXT:  # %bb.1:
+; RV64IZHINX-NEXT:    fcvt.w.h a1, a0
+; RV64IZHINX-NEXT:    fcvt.h.w a1, a1
+; RV64IZHINX-NEXT:    fsgnj.h a0, a1, a0
+; RV64IZHINX-NEXT:  .LBB23_2:
+; RV64IZHINX-NEXT:    fcvt.lu.h a1, a0, rtz
+; RV64IZHINX-NEXT:    feq.h a0, a0, a0
+; RV64IZHINX-NEXT:    seqz a0, a0
+; RV64IZHINX-NEXT:    addi a0, a0, -1
+; RV64IZHINX-NEXT:    and a0, a0, a1
+; RV64IZHINX-NEXT:    ret
+;
+; RV32IZFHMIN-LABEL: test_rint_ui64:
+; RV32IZFHMIN:       # %bb.0:
+; RV32IZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; RV32IZFHMIN-NEXT:    lui a0, 307200
+; RV32IZFHMIN-NEXT:    fmv.w.x fa4, a0
+; RV32IZFHMIN-NEXT:    fabs.s fa3, fa5
+; RV32IZFHMIN-NEXT:    flt.s a0, fa3, fa4
+; RV32IZFHMIN-NEXT:    beqz a0, .LBB23_2
+; RV32IZFHMIN-NEXT:  # %bb.1:
+; RV32IZFHMIN-NEXT:    fcvt.w.s a0, fa5
+; RV32IZFHMIN-NEXT:    fcvt.s.w fa4, a0
+; RV32IZFHMIN-NEXT:    fsgnj.s fa5, fa4, fa5
+; RV32IZFHMIN-NEXT:  .LBB23_2:
+; RV32IZFHMIN-NEXT:    addi sp, sp, -16
+; RV32IZFHMIN-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZFHMIN-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IZFHMIN-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
+; RV32IZFHMIN-NEXT:    fcvt.h.s fa5, fa5
+; RV32IZFHMIN-NEXT:    fcvt.s.h fs0, fa5
+; RV32IZFHMIN-NEXT:    fmv.w.x fa5, zero
+; RV32IZFHMIN-NEXT:    fle.s a0, fa5, fs0
+; RV32IZFHMIN-NEXT:    neg s0, a0
+; RV32IZFHMIN-NEXT:    fmv.s fa0, fs0
+; RV32IZFHMIN-NEXT:    call __fixunssfdi at plt
+; RV32IZFHMIN-NEXT:    lui a2, %hi(.LCPI23_0)
+; RV32IZFHMIN-NEXT:    flw fa5, %lo(.LCPI23_0)(a2)
+; RV32IZFHMIN-NEXT:    and a0, s0, a0
+; RV32IZFHMIN-NEXT:    flt.s a2, fa5, fs0
+; RV32IZFHMIN-NEXT:    neg a2, a2
+; RV32IZFHMIN-NEXT:    or a0, a2, a0
+; RV32IZFHMIN-NEXT:    and a1, s0, a1
+; RV32IZFHMIN-NEXT:    or a1, a2, a1
+; RV32IZFHMIN-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZFHMIN-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IZFHMIN-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
+; RV32IZFHMIN-NEXT:    addi sp, sp, 16
+; RV32IZFHMIN-NEXT:    ret
+;
+; RV64IZFHMIN-LABEL: test_rint_ui64:
+; RV64IZFHMIN:       # %bb.0:
+; RV64IZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; RV64IZFHMIN-NEXT:    lui a0, 307200
+; RV64IZFHMIN-NEXT:    fmv.w.x fa4, a0
+; RV64IZFHMIN-NEXT:    fabs.s fa3, fa5
+; RV64IZFHMIN-NEXT:    flt.s a0, fa3, fa4
+; RV64IZFHMIN-NEXT:    beqz a0, .LBB23_2
+; RV64IZFHMIN-NEXT:  # %bb.1:
+; RV64IZFHMIN-NEXT:    fcvt.w.s a0, fa5
+; RV64IZFHMIN-NEXT:    fcvt.s.w fa4, a0
+; RV64IZFHMIN-NEXT:    fsgnj.s fa5, fa4, fa5
+; RV64IZFHMIN-NEXT:  .LBB23_2:
+; RV64IZFHMIN-NEXT:    fcvt.h.s fa5, fa5
+; RV64IZFHMIN-NEXT:    fcvt.s.h fa5, fa5
+; RV64IZFHMIN-NEXT:    fcvt.lu.s a0, fa5, rtz
+; RV64IZFHMIN-NEXT:    feq.s a1, fa5, fa5
+; RV64IZFHMIN-NEXT:    seqz a1, a1
+; RV64IZFHMIN-NEXT:    addi a1, a1, -1
+; RV64IZFHMIN-NEXT:    and a0, a1, a0
+; RV64IZFHMIN-NEXT:    ret
+;
+; RV32IZHINXMIN-LABEL: test_rint_ui64:
+; RV32IZHINXMIN:       # %bb.0:
+; RV32IZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; RV32IZHINXMIN-NEXT:    lui a1, 307200
+; RV32IZHINXMIN-NEXT:    fabs.s a2, a0
+; RV32IZHINXMIN-NEXT:    flt.s a1, a2, a1
+; RV32IZHINXMIN-NEXT:    beqz a1, .LBB23_2
+; RV32IZHINXMIN-NEXT:  # %bb.1:
+; RV32IZHINXMIN-NEXT:    fcvt.w.s a1, a0
+; RV32IZHINXMIN-NEXT:    fcvt.s.w a1, a1
+; RV32IZHINXMIN-NEXT:    fsgnj.s a0, a1, a0
+; RV32IZHINXMIN-NEXT:  .LBB23_2:
+; RV32IZHINXMIN-NEXT:    addi sp, sp, -16
+; RV32IZHINXMIN-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZHINXMIN-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IZHINXMIN-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
+; RV32IZHINXMIN-NEXT:    fcvt.h.s a0, a0
+; RV32IZHINXMIN-NEXT:    fcvt.s.h s0, a0
+; RV32IZHINXMIN-NEXT:    fle.s a0, zero, s0
+; RV32IZHINXMIN-NEXT:    neg s1, a0
+; RV32IZHINXMIN-NEXT:    mv a0, s0
+; RV32IZHINXMIN-NEXT:    call __fixunssfdi at plt
+; RV32IZHINXMIN-NEXT:    lui a2, %hi(.LCPI23_0)
+; RV32IZHINXMIN-NEXT:    lw a2, %lo(.LCPI23_0)(a2)
+; RV32IZHINXMIN-NEXT:    and a0, s1, a0
+; RV32IZHINXMIN-NEXT:    flt.s a2, a2, s0
+; RV32IZHINXMIN-NEXT:    neg a2, a2
+; RV32IZHINXMIN-NEXT:    or a0, a2, a0
+; RV32IZHINXMIN-NEXT:    and a1, s1, a1
+; RV32IZHINXMIN-NEXT:    or a1, a2, a1
+; RV32IZHINXMIN-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZHINXMIN-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IZHINXMIN-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
+; RV32IZHINXMIN-NEXT:    addi sp, sp, 16
+; RV32IZHINXMIN-NEXT:    ret
+;
+; RV64IZHINXMIN-LABEL: test_rint_ui64:
+; RV64IZHINXMIN:       # %bb.0:
+; RV64IZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; RV64IZHINXMIN-NEXT:    lui a1, 307200
+; RV64IZHINXMIN-NEXT:    fabs.s a2, a0
+; RV64IZHINXMIN-NEXT:    flt.s a1, a2, a1
+; RV64IZHINXMIN-NEXT:    beqz a1, .LBB23_2
+; RV64IZHINXMIN-NEXT:  # %bb.1:
+; RV64IZHINXMIN-NEXT:    fcvt.w.s a1, a0
+; RV64IZHINXMIN-NEXT:    fcvt.s.w a1, a1
+; RV64IZHINXMIN-NEXT:    fsgnj.s a0, a1, a0
+; RV64IZHINXMIN-NEXT:  .LBB23_2:
+; RV64IZHINXMIN-NEXT:    fcvt.h.s a0, a0
+; RV64IZHINXMIN-NEXT:    fcvt.s.h a0, a0
+; RV64IZHINXMIN-NEXT:    fcvt.lu.s a1, a0, rtz
+; RV64IZHINXMIN-NEXT:    feq.s a0, a0, a0
+; RV64IZHINXMIN-NEXT:    seqz a0, a0
+; RV64IZHINXMIN-NEXT:    addi a0, a0, -1
+; RV64IZHINXMIN-NEXT:    and a0, a0, a1
+; RV64IZHINXMIN-NEXT:    ret
+  %a = call half @llvm.rint.f16(half %x)
+  %b = call i64 @llvm.fptoui.sat.i64.f16(half %a)
+  ret i64 %b
+}
+
 declare half @llvm.floor.f16(half)
 declare half @llvm.ceil.f16(half)
 declare half @llvm.trunc.f16(half)
 declare half @llvm.round.f16(half)
 declare half @llvm.roundeven.f16(half)
+declare half @llvm.rint.f16(half)
 declare i32 @llvm.fptosi.sat.i32.f16(half)
 declare i64 @llvm.fptosi.sat.i64.f16(half)
 declare i32 @llvm.fptoui.sat.i32.f16(half)


        


More information about the llvm-commits mailing list