[llvm] [LoongArch] Supports FP_TO_SINT operation for fp16 (PR #118303)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 3 03:36:23 PST 2024
https://github.com/heiher updated https://github.com/llvm/llvm-project/pull/118303
>From 8914c54170fd41149c5f8865bb99d94a65564186 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
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 16bceacfaa222c..bb6800a8493cd3 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 03965ac81f3763..ac9b0dc42aa887 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 <wangrui at loongson.cn>
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 ac9b0dc42aa887..63d76f742a4289 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 <wangrui at loongson.cn>
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 63d76f742a4289..c5a27a70112787 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
More information about the llvm-commits
mailing list