Skip to content

Commit 00d8ea3

Browse files
authored
[LoongArch] Supports FP_TO_SINT operation for fp16 (#118303)
Fixes #118301
1 parent 7d1c661 commit 00d8ea3

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,16 +1669,19 @@ SDValue LoongArchTargetLowering::lowerFP_TO_SINT(SDValue Op,
16691669
SelectionDAG &DAG) const {
16701670

16711671
SDLoc DL(Op);
1672+
SDValue Op0 = Op.getOperand(0);
1673+
1674+
if (Op0.getValueType() == MVT::f16)
1675+
Op0 = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Op0);
16721676

16731677
if (Op.getValueSizeInBits() > 32 && Subtarget.hasBasicF() &&
16741678
!Subtarget.hasBasicD()) {
1675-
SDValue Dst =
1676-
DAG.getNode(LoongArchISD::FTINT, DL, MVT::f32, Op.getOperand(0));
1679+
SDValue Dst = DAG.getNode(LoongArchISD::FTINT, DL, MVT::f32, Op0);
16771680
return DAG.getNode(LoongArchISD::MOVFR2GR_S_LA64, DL, MVT::i64, Dst);
16781681
}
16791682

16801683
EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits());
1681-
SDValue Trunc = DAG.getNode(LoongArchISD::FTINT, DL, FPTy, Op.getOperand(0));
1684+
SDValue Trunc = DAG.getNode(LoongArchISD::FTINT, DL, FPTy, Op0);
16821685
return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Trunc);
16831686
}
16841687

@@ -2872,6 +2875,8 @@ void LoongArchTargetLowering::ReplaceNodeResults(
28722875
EVT FVT = EVT::getFloatingPointVT(N->getValueSizeInBits(0));
28732876
if (getTypeAction(*DAG.getContext(), Src.getValueType()) !=
28742877
TargetLowering::TypeSoftenFloat) {
2878+
if (Src.getValueType() == MVT::f16)
2879+
Src = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Src);
28752880
SDValue Dst = DAG.getNode(LoongArchISD::FTINT, DL, FVT, Src);
28762881
Results.push_back(DAG.getNode(ISD::BITCAST, DL, VT, Dst));
28772882
return;

llvm/test/CodeGen/LoongArch/fp16-promote.ll

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,84 @@ define half @freeze_half_poison(half %maybe.poison) nounwind {
378378
%t1 = fadd half %y1, %y1
379379
ret half %t1
380380
}
381+
382+
define signext i32 @test_half_to_s32(half %a) nounwind {
383+
; LA32-LABEL: test_half_to_s32:
384+
; LA32: # %bb.0: # %entry
385+
; LA32-NEXT: addi.w $sp, $sp, -16
386+
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
387+
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
388+
; LA32-NEXT: ftintrz.w.s $fa0, $fa0
389+
; LA32-NEXT: movfr2gr.s $a0, $fa0
390+
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
391+
; LA32-NEXT: addi.w $sp, $sp, 16
392+
; LA32-NEXT: ret
393+
;
394+
; LA64-LABEL: test_half_to_s32:
395+
; LA64: # %bb.0: # %entry
396+
; LA64-NEXT: addi.d $sp, $sp, -16
397+
; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
398+
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
399+
; LA64-NEXT: ftintrz.w.s $fa0, $fa0
400+
; LA64-NEXT: movfr2gr.s $a0, $fa0
401+
; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
402+
; LA64-NEXT: addi.d $sp, $sp, 16
403+
; LA64-NEXT: ret
404+
entry:
405+
%conv = fptosi half %a to i32
406+
ret i32 %conv
407+
}
408+
409+
define zeroext i32 @test_half_to_s32_u32(half %a) nounwind {
410+
; LA32-LABEL: test_half_to_s32_u32:
411+
; LA32: # %bb.0: # %entry
412+
; LA32-NEXT: addi.w $sp, $sp, -16
413+
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
414+
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
415+
; LA32-NEXT: ftintrz.w.s $fa0, $fa0
416+
; LA32-NEXT: movfr2gr.s $a0, $fa0
417+
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
418+
; LA32-NEXT: addi.w $sp, $sp, 16
419+
; LA32-NEXT: ret
420+
;
421+
; LA64-LABEL: test_half_to_s32_u32:
422+
; LA64: # %bb.0: # %entry
423+
; LA64-NEXT: addi.d $sp, $sp, -16
424+
; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
425+
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
426+
; LA64-NEXT: ftintrz.w.s $fa0, $fa0
427+
; LA64-NEXT: movfr2gr.s $a0, $fa0
428+
; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0
429+
; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
430+
; LA64-NEXT: addi.d $sp, $sp, 16
431+
; LA64-NEXT: ret
432+
entry:
433+
%conv = fptosi half %a to i32
434+
ret i32 %conv
435+
}
436+
437+
define i64 @test_half_to_i64(half %a) nounwind {
438+
; LA32-LABEL: test_half_to_i64:
439+
; LA32: # %bb.0: # %entry
440+
; LA32-NEXT: addi.w $sp, $sp, -16
441+
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
442+
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
443+
; LA32-NEXT: bl %plt(__fixsfdi)
444+
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
445+
; LA32-NEXT: addi.w $sp, $sp, 16
446+
; LA32-NEXT: ret
447+
;
448+
; LA64-LABEL: test_half_to_i64:
449+
; LA64: # %bb.0: # %entry
450+
; LA64-NEXT: addi.d $sp, $sp, -16
451+
; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
452+
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
453+
; LA64-NEXT: ftintrz.l.s $fa0, $fa0
454+
; LA64-NEXT: movfr2gr.d $a0, $fa0
455+
; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
456+
; LA64-NEXT: addi.d $sp, $sp, 16
457+
; LA64-NEXT: ret
458+
entry:
459+
%conv = fptosi half %a to i64
460+
ret i64 %conv
461+
}

0 commit comments

Comments
 (0)