From 8914c54170fd41149c5f8865bb99d94a65564186 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Mon, 2 Dec 2024 21:56:05 +0800 Subject: [PATCH 1/3] [LoongArch] Supports FP_TO_SINT operation for fp16 Fixes #118301 --- .../LoongArch/LoongArchISelLowering.cpp | 11 +++++--- llvm/test/CodeGen/LoongArch/fp16-promote.ll | 27 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 16bceacfaa222..bb6800a8493cd 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -1669,16 +1669,19 @@ SDValue LoongArchTargetLowering::lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); + SDValue Op0 = Op.getOperand(0); + + if (Op0.getValueType() == MVT::f16) + Op0 = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Op0); if (Op.getValueSizeInBits() > 32 && Subtarget.hasBasicF() && !Subtarget.hasBasicD()) { - SDValue Dst = - DAG.getNode(LoongArchISD::FTINT, DL, MVT::f32, Op.getOperand(0)); + SDValue Dst = DAG.getNode(LoongArchISD::FTINT, DL, MVT::f32, Op0); return DAG.getNode(LoongArchISD::MOVFR2GR_S_LA64, DL, MVT::i64, Dst); } EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits()); - SDValue Trunc = DAG.getNode(LoongArchISD::FTINT, DL, FPTy, Op.getOperand(0)); + SDValue Trunc = DAG.getNode(LoongArchISD::FTINT, DL, FPTy, Op0); return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Trunc); } @@ -2872,6 +2875,8 @@ void LoongArchTargetLowering::ReplaceNodeResults( EVT FVT = EVT::getFloatingPointVT(N->getValueSizeInBits(0)); if (getTypeAction(*DAG.getContext(), Src.getValueType()) != TargetLowering::TypeSoftenFloat) { + if (Src.getValueType() == MVT::f16) + Src = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Src); SDValue Dst = DAG.getNode(LoongArchISD::FTINT, DL, FVT, Src); Results.push_back(DAG.getNode(ISD::BITCAST, DL, VT, Dst)); return; diff --git a/llvm/test/CodeGen/LoongArch/fp16-promote.ll b/llvm/test/CodeGen/LoongArch/fp16-promote.ll index 03965ac81f376..ac9b0dc42aa88 100644 --- a/llvm/test/CodeGen/LoongArch/fp16-promote.ll +++ b/llvm/test/CodeGen/LoongArch/fp16-promote.ll @@ -378,3 +378,30 @@ define half @freeze_half_poison(half %maybe.poison) nounwind { %t1 = fadd half %y1, %y1 ret half %t1 } + +define signext i32 @test_half_to_i32(half %a) nounwind { +; LA32-LABEL: test_half_to_i32: +; LA32: # %bb.0: # %entry +; LA32-NEXT: addi.w $sp, $sp, -16 +; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +; LA32-NEXT: bl %plt(__gnu_h2f_ieee) +; LA32-NEXT: ftintrz.w.s $fa0, $fa0 +; LA32-NEXT: movfr2gr.s $a0, $fa0 +; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 16 +; LA32-NEXT: ret +; +; LA64-LABEL: test_half_to_i32: +; LA64: # %bb.0: # %entry +; LA64-NEXT: addi.d $sp, $sp, -16 +; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +; LA64-NEXT: bl %plt(__gnu_h2f_ieee) +; LA64-NEXT: ftintrz.w.s $fa0, $fa0 +; LA64-NEXT: movfr2gr.s $a0, $fa0 +; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 16 +; LA64-NEXT: ret +entry: + %conv = fptosi half %a to i32 + ret i32 %conv +} From 57d8632b3f4f57735a7fb0727090091effc0859d Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Tue, 3 Dec 2024 17:16:36 +0800 Subject: [PATCH 2/3] Update test case --- llvm/test/CodeGen/LoongArch/fp16-promote.ll | 60 +++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/llvm/test/CodeGen/LoongArch/fp16-promote.ll b/llvm/test/CodeGen/LoongArch/fp16-promote.ll index ac9b0dc42aa88..63d76f742a428 100644 --- a/llvm/test/CodeGen/LoongArch/fp16-promote.ll +++ b/llvm/test/CodeGen/LoongArch/fp16-promote.ll @@ -379,8 +379,8 @@ define half @freeze_half_poison(half %maybe.poison) nounwind { ret half %t1 } -define signext i32 @test_half_to_i32(half %a) nounwind { -; LA32-LABEL: test_half_to_i32: +define signext i32 @test_half_to_s32(half %a) nounwind { +; LA32-LABEL: test_half_to_s32: ; LA32: # %bb.0: # %entry ; LA32-NEXT: addi.w $sp, $sp, -16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill @@ -391,7 +391,7 @@ define signext i32 @test_half_to_i32(half %a) nounwind { ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret ; -; LA64-LABEL: test_half_to_i32: +; LA64-LABEL: test_half_to_s32: ; LA64: # %bb.0: # %entry ; LA64-NEXT: addi.d $sp, $sp, -16 ; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill @@ -405,3 +405,57 @@ entry: %conv = fptosi half %a to i32 ret i32 %conv } + +define zeroext i32 @test_half_to_u32(half %a) nounwind { +; LA32-LABEL: test_half_to_u32: +; LA32: # %bb.0: # %entry +; LA32-NEXT: addi.w $sp, $sp, -16 +; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +; LA32-NEXT: bl %plt(__gnu_h2f_ieee) +; LA32-NEXT: ftintrz.w.s $fa0, $fa0 +; LA32-NEXT: movfr2gr.s $a0, $fa0 +; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload +; LA32-NEXT: addi.w $sp, $sp, 16 +; LA32-NEXT: ret +; +; LA64-LABEL: test_half_to_u32: +; LA64: # %bb.0: # %entry +; LA64-NEXT: addi.d $sp, $sp, -16 +; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +; LA64-NEXT: bl %plt(__gnu_h2f_ieee) +; LA64-NEXT: ftintrz.w.s $fa0, $fa0 +; LA64-NEXT: movfr2gr.s $a0, $fa0 +; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 +; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 16 +; LA64-NEXT: ret +entry: + %conv = fptosi half %a to i32 + ret i32 %conv +} + +define i64 @test_half_to_i64(half %a) nounwind { +; LA32-LABEL: test_half_to_i64: +; LA32: # %bb.0: # %entry +; LA32-NEXT: addi.w $sp, $sp, -16 +; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill +; LA32-NEXT: bl %plt(__gnu_h2f_ieee) +; 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: test_half_to_i64: +; LA64: # %bb.0: # %entry +; LA64-NEXT: addi.d $sp, $sp, -16 +; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill +; LA64-NEXT: bl %plt(__gnu_h2f_ieee) +; LA64-NEXT: ftintrz.l.s $fa0, $fa0 +; LA64-NEXT: movfr2gr.d $a0, $fa0 +; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload +; LA64-NEXT: addi.d $sp, $sp, 16 +; LA64-NEXT: ret +entry: + %conv = fptosi half %a to i64 + ret i64 %conv +} From 998a308e399a6e653ef329cb0700eec4bcf1f5bc Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Tue, 3 Dec 2024 19:37:00 +0800 Subject: [PATCH 3/3] Rename test case test_half_to_s32_u32 --- llvm/test/CodeGen/LoongArch/fp16-promote.ll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/test/CodeGen/LoongArch/fp16-promote.ll b/llvm/test/CodeGen/LoongArch/fp16-promote.ll index 63d76f742a428..c5a27a7011278 100644 --- a/llvm/test/CodeGen/LoongArch/fp16-promote.ll +++ b/llvm/test/CodeGen/LoongArch/fp16-promote.ll @@ -406,8 +406,8 @@ entry: ret i32 %conv } -define zeroext i32 @test_half_to_u32(half %a) nounwind { -; LA32-LABEL: test_half_to_u32: +define zeroext i32 @test_half_to_s32_u32(half %a) nounwind { +; LA32-LABEL: test_half_to_s32_u32: ; LA32: # %bb.0: # %entry ; LA32-NEXT: addi.w $sp, $sp, -16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill @@ -418,7 +418,7 @@ define zeroext i32 @test_half_to_u32(half %a) nounwind { ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret ; -; LA64-LABEL: test_half_to_u32: +; LA64-LABEL: test_half_to_s32_u32: ; LA64: # %bb.0: # %entry ; LA64-NEXT: addi.d $sp, $sp, -16 ; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill