From dc3c5a78f20f5d5e075453754d74021844e780a5 Mon Sep 17 00:00:00 2001 From: gonglingqin Date: Thu, 29 Sep 2022 10:05:58 +0800 Subject: [PATCH] [LoongArch] Add fp_to_sint support for soft floating point Differential Revision: https://reviews.llvm.org/D134692 --- .../lib/Target/LoongArch/LoongArchISelLowering.cpp | 20 ++- llvm/test/CodeGen/LoongArch/soft-fp-to-int.ll | 155 +++++++++++++++++++++ 2 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/LoongArch/soft-fp-to-int.ll diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index e157ed8..9c443ba 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -544,8 +544,24 @@ void LoongArchTargetLowering::ReplaceNodeResults( "Unexpected custom legalisation"); SDValue Src = N->getOperand(0); EVT VT = EVT::getFloatingPointVT(N->getValueSizeInBits(0)); - SDValue Dst = DAG.getNode(LoongArchISD::FTINT, DL, VT, Src); - Results.push_back(DAG.getNode(ISD::BITCAST, DL, N->getValueType(0), Dst)); + if (getTypeAction(*DAG.getContext(), Src.getValueType()) != + TargetLowering::TypeSoftenFloat) { + SDValue Dst = DAG.getNode(LoongArchISD::FTINT, DL, VT, Src); + Results.push_back(DAG.getNode(ISD::BITCAST, DL, N->getValueType(0), Dst)); + return; + } + // If the FP type needs to be softened, emit a library call using the 'si' + // version. If we left it to default legalization we'd end up with 'di'. + RTLIB::Libcall LC; + LC = RTLIB::getFPTOSINT(Src.getValueType(), N->getValueType(0)); + MakeLibCallOptions CallOptions; + EVT OpVT = Src.getValueType(); + CallOptions.setTypeListBeforeSoften(OpVT, N->getValueType(0), true); + SDValue Chain = SDValue(); + SDValue Result; + std::tie(Result, Chain) = + makeLibCall(DAG, LC, N->getValueType(0), Src, CallOptions, DL, Chain); + Results.push_back(Result); break; } case ISD::BITCAST: { diff --git a/llvm/test/CodeGen/LoongArch/soft-fp-to-int.ll b/llvm/test/CodeGen/LoongArch/soft-fp-to-int.ll new file mode 100644 index 0000000..d12cbaa --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/soft-fp-to-int.ll @@ -0,0 +1,155 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32 +; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64 + +define i32 @fptosi_i32_fp128(fp128 %X) nounwind { +; LA32-LABEL: fptosi_i32_fp128: +; LA32: # %bb.0: +; LA32-NEXT: addi.w $sp, $sp, -32 +; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +; LA32-NEXT: ld.w $a1, $a0, 12 +; LA32-NEXT: st.w $a1, $sp, 20 +; LA32-NEXT: ld.w $a1, $a0, 8 +; LA32-NEXT: st.w $a1, $sp, 16 +; LA32-NEXT: ld.w $a1, $a0, 4 +; LA32-NEXT: st.w $a1, $sp, 12 +; LA32-NEXT: ld.w $a0, $a0, 0 +; LA32-NEXT: st.w $a0, $sp, 8 +; LA32-NEXT: addi.w $a0, $sp, 8 +; LA32-NEXT: bl %plt(__fixtfsi) +; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 32 +; LA32-NEXT: ret +; +; LA64-LABEL: fptosi_i32_fp128: +; LA64: # %bb.0: +; LA64-NEXT: addi.d $sp, $sp, -16 +; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +; LA64-NEXT: bl %plt(__fixtfsi) +; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 16 +; LA64-NEXT: ret + %tmp = fptosi fp128 %X to i32 + ret i32 %tmp +} + +define i32 @fptosi_i32_double(double %X) nounwind { +; LA32-LABEL: fptosi_i32_double: +; LA32: # %bb.0: +; LA32-NEXT: addi.w $sp, $sp, -16 +; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +; LA32-NEXT: bl %plt(__fixdfsi) +; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 16 +; LA32-NEXT: ret +; +; LA64-LABEL: fptosi_i32_double: +; LA64: # %bb.0: +; LA64-NEXT: addi.d $sp, $sp, -16 +; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +; LA64-NEXT: bl %plt(__fixdfsi) +; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 16 +; LA64-NEXT: ret + %tmp = fptosi double %X to i32 + ret i32 %tmp +} + +define i32 @fptosi_i32_float(float %X) nounwind { +; LA32-LABEL: fptosi_i32_float: +; LA32: # %bb.0: +; LA32-NEXT: addi.w $sp, $sp, -16 +; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +; LA32-NEXT: bl %plt(__fixsfsi) +; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 16 +; LA32-NEXT: ret +; +; LA64-LABEL: fptosi_i32_float: +; LA64: # %bb.0: +; LA64-NEXT: addi.d $sp, $sp, -16 +; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +; LA64-NEXT: bl %plt(__fixsfsi) +; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 16 +; LA64-NEXT: ret + %tmp = fptosi float %X to i32 + ret i32 %tmp +} + +define i64 @fptosi_i64_fp128(fp128 %X) nounwind { +; LA32-LABEL: fptosi_i64_fp128: +; LA32: # %bb.0: +; LA32-NEXT: addi.w $sp, $sp, -32 +; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +; LA32-NEXT: ld.w $a1, $a0, 12 +; LA32-NEXT: st.w $a1, $sp, 12 +; LA32-NEXT: ld.w $a1, $a0, 8 +; LA32-NEXT: st.w $a1, $sp, 8 +; LA32-NEXT: ld.w $a1, $a0, 4 +; LA32-NEXT: st.w $a1, $sp, 4 +; LA32-NEXT: ld.w $a0, $a0, 0 +; LA32-NEXT: st.w $a0, $sp, 0 +; LA32-NEXT: addi.w $a0, $sp, 0 +; LA32-NEXT: bl %plt(__fixtfdi) +; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 32 +; LA32-NEXT: ret +; +; LA64-LABEL: fptosi_i64_fp128: +; LA64: # %bb.0: +; LA64-NEXT: addi.d $sp, $sp, -16 +; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +; LA64-NEXT: bl %plt(__fixtfdi) +; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 16 +; LA64-NEXT: ret + %tmp = fptosi fp128 %X to i64 + ret i64 %tmp +} + +define i64 @fptosi_i64_double(double %X) nounwind { +; LA32-LABEL: fptosi_i64_double: +; LA32: # %bb.0: +; LA32-NEXT: addi.w $sp, $sp, -16 +; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +; LA32-NEXT: bl %plt(__fixdfdi) +; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 16 +; LA32-NEXT: ret +; +; LA64-LABEL: fptosi_i64_double: +; LA64: # %bb.0: +; LA64-NEXT: addi.d $sp, $sp, -16 +; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +; LA64-NEXT: bl %plt(__fixdfdi) +; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 16 +; LA64-NEXT: ret + %tmp = fptosi double %X to i64 + ret i64 %tmp +} + +define i64 @fptosi_i64_float(float %X) nounwind { +; LA32-LABEL: fptosi_i64_float: +; LA32: # %bb.0: +; LA32-NEXT: addi.w $sp, $sp, -16 +; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +; LA32-NEXT: bl %plt(__fixsfdi) +; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 16 +; LA32-NEXT: ret +; +; LA64-LABEL: fptosi_i64_float: +; LA64: # %bb.0: +; LA64-NEXT: addi.d $sp, $sp, -16 +; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +; LA64-NEXT: bl %plt(__fixsfdi) +; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 16 +; LA64-NEXT: ret + %tmp = fptosi float %X to i64 + ret i64 %tmp +} -- 2.7.4