[llvm] Support STRICT_UINT_TO_FP and STRICT_SINT_TO_FP (PR #102503)
Mikhail R. Gadelha via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 13 07:41:49 PDT 2024
https://github.com/mikhailramalho updated https://github.com/llvm/llvm-project/pull/102503
>From d3a4c180ef70d5a492141ccaca6e573d9fc79a1b Mon Sep 17 00:00:00 2001
From: "Mikhail R. Gadelha" <mikhail at igalia.com>
Date: Thu, 8 Aug 2024 21:01:15 -0300
Subject: [PATCH 1/3] Fix support for strict version of fp to (u)int and (u)int
to fp
---
.../SelectionDAG/LegalizeFloatTypes.cpp | 21 ++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index edebb5ee87001b..fa877c3f348dca 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -3090,6 +3090,8 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
break;
case ISD::SELECT: R = SoftPromoteHalfRes_SELECT(N); break;
case ISD::SELECT_CC: R = SoftPromoteHalfRes_SELECT_CC(N); break;
+ case ISD::STRICT_SINT_TO_FP:
+ case ISD::STRICT_UINT_TO_FP:
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP: R = SoftPromoteHalfRes_XINT_TO_FP(N); break;
case ISD::UNDEF: R = SoftPromoteHalfRes_UNDEF(N); break;
@@ -3311,7 +3313,12 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(SDNode *N) {
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
SDLoc dl(N);
- SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
+ SDValue Op = N->getOperand(N->isStrictFPOpcode() ? 1 : 0);
+
+ bool Signed = N->getOpcode() == ISD::SINT_TO_FP ||
+ N->getOpcode() == ISD::STRICT_SINT_TO_FP;
+ SDValue Res =
+ DAG.getNode(Signed ? ISD::SINT_TO_FP : ISD::UINT_TO_FP, dl, NVT, Op);
// Round the value to the softened type.
return DAG.getNode(GetPromotionOpcode(NVT, OVT), dl, MVT::i16, Res);
@@ -3396,6 +3403,8 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(N); break;
case ISD::FCOPYSIGN: Res = SoftPromoteHalfOp_FCOPYSIGN(N, OpNo); break;
+ case ISD::STRICT_FP_TO_SINT:
+ case ISD::STRICT_FP_TO_UINT:
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT: Res = SoftPromoteHalfOp_FP_TO_XINT(N); break;
case ISD::FP_TO_SINT_SAT:
@@ -3422,8 +3431,7 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
assert(Res.getNode() != N && "Expected a new node!");
- assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
- "Invalid operand expansion");
+ assert(Res.getValueType() == N->getValueType(0) && "Invalid operand expansion");
ReplaceValueWith(SDValue(N, 0), Res);
return false;
@@ -3479,7 +3487,7 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(SDNode *N) {
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT(SDNode *N) {
EVT RVT = N->getValueType(0);
- SDValue Op = N->getOperand(0);
+ SDValue Op = N->getOperand(N->isStrictFPOpcode() ? 1 : 0);
EVT SVT = Op.getValueType();
SDLoc dl(N);
@@ -3489,7 +3497,10 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT(SDNode *N) {
SDValue Res = DAG.getNode(GetPromotionOpcode(SVT, RVT), dl, NVT, Op);
- return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), Res);
+ bool Signed = N->getOpcode() == ISD::FP_TO_SINT ||
+ N->getOpcode() == ISD::STRICT_FP_TO_SINT;
+ return DAG.getNode(Signed ? ISD::FP_TO_SINT : ISD::FP_TO_UINT, dl,
+ N->getValueType(0), Res);
}
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N) {
>From c9d47ffd8c5d1ace87bca23e7b5b0cc80cb4342f Mon Sep 17 00:00:00 2001
From: "Mikhail R. Gadelha" <mikhail at igalia.com>
Date: Thu, 8 Aug 2024 21:32:49 -0300
Subject: [PATCH 2/3] Format
---
llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index fa877c3f348dca..3f13d4a6242328 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -3431,7 +3431,8 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
assert(Res.getNode() != N && "Expected a new node!");
- assert(Res.getValueType() == N->getValueType(0) && "Invalid operand expansion");
+ assert(Res.getValueType() == N->getValueType(0) &&
+ "Invalid operand expansion");
ReplaceValueWith(SDValue(N, 0), Res);
return false;
>From ac36c4f61fa46381086ef0c926489d6fa1d24779 Mon Sep 17 00:00:00 2001
From: "Mikhail R. Gadelha" <mikhail at igalia.com>
Date: Tue, 13 Aug 2024 11:41:14 -0300
Subject: [PATCH 3/3] Added testcase
---
.../test/CodeGen/RISCV/half-convert-strict.ll | 360 ++++++++++++++++++
1 file changed, 360 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/half-convert-strict.ll b/llvm/test/CodeGen/RISCV/half-convert-strict.ll
index 8f88a4c570ea05..4505d335f95560 100644
--- a/llvm/test/CodeGen/RISCV/half-convert-strict.ll
+++ b/llvm/test/CodeGen/RISCV/half-convert-strict.ll
@@ -2165,3 +2165,363 @@ define signext i32 @fcvt_h_wu_demanded_bits(i32 signext %0, ptr %1) strictfp {
store half %4, ptr %1, align 2
ret i32 %3
}
+
+define dso_local void @int_uint_to_half(i32 noundef %p1, i32 noundef %p2) {
+; CHECKIZFH-LABEL: int_uint_to_half:
+; CHECKIZFH: # %bb.0: # %entry
+; CHECKIZFH-NEXT: addi sp, sp, -16
+; CHECKIZFH-NEXT: .cfi_def_cfa_offset 16
+; CHECKIZFH-NEXT: sw a0, 12(sp)
+; CHECKIZFH-NEXT: sw a1, 8(sp)
+; CHECKIZFH-NEXT: fcvt.h.w fa5, a0
+; CHECKIZFH-NEXT: fsh fa5, 6(sp)
+; CHECKIZFH-NEXT: fcvt.h.wu fa5, a1
+; CHECKIZFH-NEXT: fsh fa5, 4(sp)
+; CHECKIZFH-NEXT: addi sp, sp, 16
+; CHECKIZFH-NEXT: ret
+;
+; CHECKIZHINX-LABEL: int_uint_to_half:
+; CHECKIZHINX: # %bb.0: # %entry
+; CHECKIZHINX-NEXT: addi sp, sp, -16
+; CHECKIZHINX-NEXT: .cfi_def_cfa_offset 16
+; CHECKIZHINX-NEXT: sw a0, 12(sp)
+; CHECKIZHINX-NEXT: sw a1, 8(sp)
+; CHECKIZHINX-NEXT: fcvt.h.w a0, a0
+; CHECKIZHINX-NEXT: sh a0, 6(sp)
+; CHECKIZHINX-NEXT: fcvt.h.wu a0, a1
+; CHECKIZHINX-NEXT: sh a0, 4(sp)
+; CHECKIZHINX-NEXT: addi sp, sp, 16
+; CHECKIZHINX-NEXT: ret
+;
+; RV32IDZFH-LABEL: int_uint_to_half:
+; RV32IDZFH: # %bb.0: # %entry
+; RV32IDZFH-NEXT: addi sp, sp, -16
+; RV32IDZFH-NEXT: .cfi_def_cfa_offset 16
+; RV32IDZFH-NEXT: sw a0, 12(sp)
+; RV32IDZFH-NEXT: sw a1, 8(sp)
+; RV32IDZFH-NEXT: fcvt.h.w fa5, a0
+; RV32IDZFH-NEXT: fsh fa5, 6(sp)
+; RV32IDZFH-NEXT: fcvt.h.wu fa5, a1
+; RV32IDZFH-NEXT: fsh fa5, 4(sp)
+; RV32IDZFH-NEXT: addi sp, sp, 16
+; RV32IDZFH-NEXT: ret
+;
+; RV64IDZFH-LABEL: int_uint_to_half:
+; RV64IDZFH: # %bb.0: # %entry
+; RV64IDZFH-NEXT: addi sp, sp, -16
+; RV64IDZFH-NEXT: .cfi_def_cfa_offset 16
+; RV64IDZFH-NEXT: sw a0, 12(sp)
+; RV64IDZFH-NEXT: sw a1, 8(sp)
+; RV64IDZFH-NEXT: fcvt.h.w fa5, a0
+; RV64IDZFH-NEXT: fsh fa5, 6(sp)
+; RV64IDZFH-NEXT: fcvt.h.wu fa5, a1
+; RV64IDZFH-NEXT: fsh fa5, 4(sp)
+; RV64IDZFH-NEXT: addi sp, sp, 16
+; RV64IDZFH-NEXT: ret
+;
+; RV32IZDINXZHINX-LABEL: int_uint_to_half:
+; RV32IZDINXZHINX: # %bb.0: # %entry
+; RV32IZDINXZHINX-NEXT: addi sp, sp, -16
+; RV32IZDINXZHINX-NEXT: .cfi_def_cfa_offset 16
+; RV32IZDINXZHINX-NEXT: sw a0, 12(sp)
+; RV32IZDINXZHINX-NEXT: sw a1, 8(sp)
+; RV32IZDINXZHINX-NEXT: fcvt.h.w a0, a0
+; RV32IZDINXZHINX-NEXT: sh a0, 6(sp)
+; RV32IZDINXZHINX-NEXT: fcvt.h.wu a0, a1
+; RV32IZDINXZHINX-NEXT: sh a0, 4(sp)
+; RV32IZDINXZHINX-NEXT: addi sp, sp, 16
+; RV32IZDINXZHINX-NEXT: ret
+;
+; RV64IZDINXZHINX-LABEL: int_uint_to_half:
+; RV64IZDINXZHINX: # %bb.0: # %entry
+; RV64IZDINXZHINX-NEXT: addi sp, sp, -16
+; RV64IZDINXZHINX-NEXT: .cfi_def_cfa_offset 16
+; RV64IZDINXZHINX-NEXT: sw a0, 12(sp)
+; RV64IZDINXZHINX-NEXT: sw a1, 8(sp)
+; RV64IZDINXZHINX-NEXT: fcvt.h.w a0, a0
+; RV64IZDINXZHINX-NEXT: sh a0, 6(sp)
+; RV64IZDINXZHINX-NEXT: fcvt.h.wu a0, a1
+; RV64IZDINXZHINX-NEXT: sh a0, 4(sp)
+; RV64IZDINXZHINX-NEXT: addi sp, sp, 16
+; RV64IZDINXZHINX-NEXT: ret
+;
+; CHECK32-IZFHMIN-LABEL: int_uint_to_half:
+; CHECK32-IZFHMIN: # %bb.0: # %entry
+; CHECK32-IZFHMIN-NEXT: addi sp, sp, -16
+; CHECK32-IZFHMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK32-IZFHMIN-NEXT: sw a0, 12(sp)
+; CHECK32-IZFHMIN-NEXT: sw a1, 8(sp)
+; CHECK32-IZFHMIN-NEXT: fcvt.s.w fa5, a0
+; CHECK32-IZFHMIN-NEXT: fcvt.h.s fa5, fa5
+; CHECK32-IZFHMIN-NEXT: fsh fa5, 6(sp)
+; CHECK32-IZFHMIN-NEXT: fcvt.s.wu fa5, a1
+; CHECK32-IZFHMIN-NEXT: fcvt.h.s fa5, fa5
+; CHECK32-IZFHMIN-NEXT: fsh fa5, 4(sp)
+; CHECK32-IZFHMIN-NEXT: addi sp, sp, 16
+; CHECK32-IZFHMIN-NEXT: ret
+;
+; CHECK64-IZFHMIN-LABEL: int_uint_to_half:
+; CHECK64-IZFHMIN: # %bb.0: # %entry
+; CHECK64-IZFHMIN-NEXT: addi sp, sp, -16
+; CHECK64-IZFHMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK64-IZFHMIN-NEXT: slli a2, a1, 32
+; CHECK64-IZFHMIN-NEXT: srli a2, a2, 32
+; CHECK64-IZFHMIN-NEXT: sext.w a3, a0
+; CHECK64-IZFHMIN-NEXT: sw a0, 12(sp)
+; CHECK64-IZFHMIN-NEXT: sw a1, 8(sp)
+; CHECK64-IZFHMIN-NEXT: fcvt.s.l fa5, a3
+; CHECK64-IZFHMIN-NEXT: fcvt.h.s fa5, fa5
+; CHECK64-IZFHMIN-NEXT: fsh fa5, 6(sp)
+; CHECK64-IZFHMIN-NEXT: fcvt.s.lu fa5, a2
+; CHECK64-IZFHMIN-NEXT: fcvt.h.s fa5, fa5
+; CHECK64-IZFHMIN-NEXT: fsh fa5, 4(sp)
+; CHECK64-IZFHMIN-NEXT: addi sp, sp, 16
+; CHECK64-IZFHMIN-NEXT: ret
+;
+; CHECK32-IZHINXMIN-LABEL: int_uint_to_half:
+; CHECK32-IZHINXMIN: # %bb.0: # %entry
+; CHECK32-IZHINXMIN-NEXT: addi sp, sp, -16
+; CHECK32-IZHINXMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK32-IZHINXMIN-NEXT: sw a0, 12(sp)
+; CHECK32-IZHINXMIN-NEXT: sw a1, 8(sp)
+; CHECK32-IZHINXMIN-NEXT: fcvt.s.w a0, a0
+; CHECK32-IZHINXMIN-NEXT: fcvt.h.s a0, a0
+; CHECK32-IZHINXMIN-NEXT: sh a0, 6(sp)
+; CHECK32-IZHINXMIN-NEXT: fcvt.s.wu a0, a1
+; CHECK32-IZHINXMIN-NEXT: fcvt.h.s a0, a0
+; CHECK32-IZHINXMIN-NEXT: sh a0, 4(sp)
+; CHECK32-IZHINXMIN-NEXT: addi sp, sp, 16
+; CHECK32-IZHINXMIN-NEXT: ret
+;
+; CHECK64-IZHINXMIN-LABEL: int_uint_to_half:
+; CHECK64-IZHINXMIN: # %bb.0: # %entry
+; CHECK64-IZHINXMIN-NEXT: addi sp, sp, -16
+; CHECK64-IZHINXMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK64-IZHINXMIN-NEXT: slli a2, a1, 32
+; CHECK64-IZHINXMIN-NEXT: srli a2, a2, 32
+; CHECK64-IZHINXMIN-NEXT: sext.w a3, a0
+; CHECK64-IZHINXMIN-NEXT: sw a0, 12(sp)
+; CHECK64-IZHINXMIN-NEXT: sw a1, 8(sp)
+; CHECK64-IZHINXMIN-NEXT: fcvt.s.l a0, a3
+; CHECK64-IZHINXMIN-NEXT: fcvt.h.s a0, a0
+; CHECK64-IZHINXMIN-NEXT: sh a0, 6(sp)
+; CHECK64-IZHINXMIN-NEXT: fcvt.s.lu a0, a2
+; CHECK64-IZHINXMIN-NEXT: fcvt.h.s a0, a0
+; CHECK64-IZHINXMIN-NEXT: sh a0, 4(sp)
+; CHECK64-IZHINXMIN-NEXT: addi sp, sp, 16
+; CHECK64-IZHINXMIN-NEXT: ret
+;
+; CHECK32-IZDINXZHINXMIN-LABEL: int_uint_to_half:
+; CHECK32-IZDINXZHINXMIN: # %bb.0: # %entry
+; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, -16
+; CHECK32-IZDINXZHINXMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK32-IZDINXZHINXMIN-NEXT: sw a0, 12(sp)
+; CHECK32-IZDINXZHINXMIN-NEXT: sw a1, 8(sp)
+; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.s.w a0, a0
+; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.h.s a0, a0
+; CHECK32-IZDINXZHINXMIN-NEXT: sh a0, 6(sp)
+; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.s.wu a0, a1
+; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.h.s a0, a0
+; CHECK32-IZDINXZHINXMIN-NEXT: sh a0, 4(sp)
+; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, 16
+; CHECK32-IZDINXZHINXMIN-NEXT: ret
+;
+; CHECK64-IZDINXZHINXMIN-LABEL: int_uint_to_half:
+; CHECK64-IZDINXZHINXMIN: # %bb.0: # %entry
+; CHECK64-IZDINXZHINXMIN-NEXT: addi sp, sp, -16
+; CHECK64-IZDINXZHINXMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK64-IZDINXZHINXMIN-NEXT: slli a2, a1, 32
+; CHECK64-IZDINXZHINXMIN-NEXT: srli a2, a2, 32
+; CHECK64-IZDINXZHINXMIN-NEXT: sext.w a3, a0
+; CHECK64-IZDINXZHINXMIN-NEXT: sw a0, 12(sp)
+; CHECK64-IZDINXZHINXMIN-NEXT: sw a1, 8(sp)
+; CHECK64-IZDINXZHINXMIN-NEXT: fcvt.s.l a0, a3
+; CHECK64-IZDINXZHINXMIN-NEXT: fcvt.h.s a0, a0
+; CHECK64-IZDINXZHINXMIN-NEXT: sh a0, 6(sp)
+; CHECK64-IZDINXZHINXMIN-NEXT: fcvt.s.lu a0, a2
+; CHECK64-IZDINXZHINXMIN-NEXT: fcvt.h.s a0, a0
+; CHECK64-IZDINXZHINXMIN-NEXT: sh a0, 4(sp)
+; CHECK64-IZDINXZHINXMIN-NEXT: addi sp, sp, 16
+; CHECK64-IZDINXZHINXMIN-NEXT: ret
+entry:
+ %p1.addr = alloca i32, align 4
+ %p2.addr = alloca i32, align 4
+ %f1 = alloca half, align 2
+ %f2 = alloca half, align 2
+ store i32 %p1, ptr %p1.addr, align 4
+ store i32 %p2, ptr %p2.addr, align 4
+ %0 = load i32, ptr %p1.addr, align 4
+ %conv = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #2
+ store half %conv, ptr %f1, align 2
+ %1 = load i32, ptr %p2.addr, align 4
+ %conv1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %1, metadata !"round.dynamic", metadata !"fpexcept.ignore") #2
+ store half %conv1, ptr %f2, align 2
+ ret void
+}
+
+define dso_local void @half_to_int_uint(half noundef %p1) {
+; CHECKIZFH-LABEL: half_to_int_uint:
+; CHECKIZFH: # %bb.0: # %entry
+; CHECKIZFH-NEXT: addi sp, sp, -16
+; CHECKIZFH-NEXT: .cfi_def_cfa_offset 16
+; CHECKIZFH-NEXT: fsh fa0, 14(sp)
+; CHECKIZFH-NEXT: fcvt.w.h a0, fa0, rtz
+; CHECKIZFH-NEXT: sw a0, 8(sp)
+; CHECKIZFH-NEXT: fcvt.wu.h a0, fa0, rtz
+; CHECKIZFH-NEXT: sw a0, 4(sp)
+; CHECKIZFH-NEXT: addi sp, sp, 16
+; CHECKIZFH-NEXT: ret
+;
+; CHECKIZHINX-LABEL: half_to_int_uint:
+; CHECKIZHINX: # %bb.0: # %entry
+; CHECKIZHINX-NEXT: addi sp, sp, -16
+; CHECKIZHINX-NEXT: .cfi_def_cfa_offset 16
+; CHECKIZHINX-NEXT: sh a0, 14(sp)
+; CHECKIZHINX-NEXT: fcvt.w.h a1, a0, rtz
+; CHECKIZHINX-NEXT: sw a1, 8(sp)
+; CHECKIZHINX-NEXT: fcvt.wu.h a0, a0, rtz
+; CHECKIZHINX-NEXT: sw a0, 4(sp)
+; CHECKIZHINX-NEXT: addi sp, sp, 16
+; CHECKIZHINX-NEXT: ret
+;
+; RV32IDZFH-LABEL: half_to_int_uint:
+; RV32IDZFH: # %bb.0: # %entry
+; RV32IDZFH-NEXT: addi sp, sp, -16
+; RV32IDZFH-NEXT: .cfi_def_cfa_offset 16
+; RV32IDZFH-NEXT: fsh fa0, 14(sp)
+; RV32IDZFH-NEXT: fcvt.w.h a0, fa0, rtz
+; RV32IDZFH-NEXT: sw a0, 8(sp)
+; RV32IDZFH-NEXT: fcvt.wu.h a0, fa0, rtz
+; RV32IDZFH-NEXT: sw a0, 4(sp)
+; RV32IDZFH-NEXT: addi sp, sp, 16
+; RV32IDZFH-NEXT: ret
+;
+; RV64IDZFH-LABEL: half_to_int_uint:
+; RV64IDZFH: # %bb.0: # %entry
+; RV64IDZFH-NEXT: addi sp, sp, -16
+; RV64IDZFH-NEXT: .cfi_def_cfa_offset 16
+; RV64IDZFH-NEXT: fsh fa0, 14(sp)
+; RV64IDZFH-NEXT: fcvt.w.h a0, fa0, rtz
+; RV64IDZFH-NEXT: sw a0, 8(sp)
+; RV64IDZFH-NEXT: fcvt.wu.h a0, fa0, rtz
+; RV64IDZFH-NEXT: sw a0, 4(sp)
+; RV64IDZFH-NEXT: addi sp, sp, 16
+; RV64IDZFH-NEXT: ret
+;
+; RV32IZDINXZHINX-LABEL: half_to_int_uint:
+; RV32IZDINXZHINX: # %bb.0: # %entry
+; RV32IZDINXZHINX-NEXT: addi sp, sp, -16
+; RV32IZDINXZHINX-NEXT: .cfi_def_cfa_offset 16
+; RV32IZDINXZHINX-NEXT: sh a0, 14(sp)
+; RV32IZDINXZHINX-NEXT: fcvt.w.h a1, a0, rtz
+; RV32IZDINXZHINX-NEXT: sw a1, 8(sp)
+; RV32IZDINXZHINX-NEXT: fcvt.wu.h a0, a0, rtz
+; RV32IZDINXZHINX-NEXT: sw a0, 4(sp)
+; RV32IZDINXZHINX-NEXT: addi sp, sp, 16
+; RV32IZDINXZHINX-NEXT: ret
+;
+; RV64IZDINXZHINX-LABEL: half_to_int_uint:
+; RV64IZDINXZHINX: # %bb.0: # %entry
+; RV64IZDINXZHINX-NEXT: addi sp, sp, -16
+; RV64IZDINXZHINX-NEXT: .cfi_def_cfa_offset 16
+; RV64IZDINXZHINX-NEXT: sh a0, 14(sp)
+; RV64IZDINXZHINX-NEXT: fcvt.w.h a1, a0, rtz
+; RV64IZDINXZHINX-NEXT: sw a1, 8(sp)
+; RV64IZDINXZHINX-NEXT: fcvt.wu.h a0, a0, rtz
+; RV64IZDINXZHINX-NEXT: sw a0, 4(sp)
+; RV64IZDINXZHINX-NEXT: addi sp, sp, 16
+; RV64IZDINXZHINX-NEXT: ret
+;
+; CHECK32-IZFHMIN-LABEL: half_to_int_uint:
+; CHECK32-IZFHMIN: # %bb.0: # %entry
+; CHECK32-IZFHMIN-NEXT: addi sp, sp, -16
+; CHECK32-IZFHMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK32-IZFHMIN-NEXT: fsh fa0, 14(sp)
+; CHECK32-IZFHMIN-NEXT: fcvt.s.h fa5, fa0
+; CHECK32-IZFHMIN-NEXT: fcvt.w.s a0, fa5, rtz
+; CHECK32-IZFHMIN-NEXT: sw a0, 8(sp)
+; CHECK32-IZFHMIN-NEXT: fcvt.wu.s a0, fa5, rtz
+; CHECK32-IZFHMIN-NEXT: sw a0, 4(sp)
+; CHECK32-IZFHMIN-NEXT: addi sp, sp, 16
+; CHECK32-IZFHMIN-NEXT: ret
+;
+; CHECK64-IZFHMIN-LABEL: half_to_int_uint:
+; CHECK64-IZFHMIN: # %bb.0: # %entry
+; CHECK64-IZFHMIN-NEXT: addi sp, sp, -16
+; CHECK64-IZFHMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK64-IZFHMIN-NEXT: fsh fa0, 14(sp)
+; CHECK64-IZFHMIN-NEXT: fcvt.s.h fa5, fa0
+; CHECK64-IZFHMIN-NEXT: fcvt.w.s a0, fa5, rtz
+; CHECK64-IZFHMIN-NEXT: sw a0, 8(sp)
+; CHECK64-IZFHMIN-NEXT: fcvt.s.h fa5, fa0
+; CHECK64-IZFHMIN-NEXT: fcvt.wu.s a0, fa5, rtz
+; CHECK64-IZFHMIN-NEXT: sw a0, 4(sp)
+; CHECK64-IZFHMIN-NEXT: addi sp, sp, 16
+; CHECK64-IZFHMIN-NEXT: ret
+;
+; CHECK32-IZHINXMIN-LABEL: half_to_int_uint:
+; CHECK32-IZHINXMIN: # %bb.0: # %entry
+; CHECK32-IZHINXMIN-NEXT: addi sp, sp, -16
+; CHECK32-IZHINXMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK32-IZHINXMIN-NEXT: sh a0, 14(sp)
+; CHECK32-IZHINXMIN-NEXT: fcvt.s.h a0, a0
+; CHECK32-IZHINXMIN-NEXT: fcvt.w.s a1, a0, rtz
+; CHECK32-IZHINXMIN-NEXT: sw a1, 8(sp)
+; CHECK32-IZHINXMIN-NEXT: fcvt.wu.s a0, a0, rtz
+; CHECK32-IZHINXMIN-NEXT: sw a0, 4(sp)
+; CHECK32-IZHINXMIN-NEXT: addi sp, sp, 16
+; CHECK32-IZHINXMIN-NEXT: ret
+;
+; CHECK64-IZHINXMIN-LABEL: half_to_int_uint:
+; CHECK64-IZHINXMIN: # %bb.0: # %entry
+; CHECK64-IZHINXMIN-NEXT: addi sp, sp, -16
+; CHECK64-IZHINXMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK64-IZHINXMIN-NEXT: sh a0, 14(sp)
+; CHECK64-IZHINXMIN-NEXT: fcvt.s.h a1, a0
+; CHECK64-IZHINXMIN-NEXT: fcvt.w.s a1, a1, rtz
+; CHECK64-IZHINXMIN-NEXT: sw a1, 8(sp)
+; CHECK64-IZHINXMIN-NEXT: fcvt.s.h a0, a0
+; CHECK64-IZHINXMIN-NEXT: fcvt.wu.s a0, a0, rtz
+; CHECK64-IZHINXMIN-NEXT: sw a0, 4(sp)
+; CHECK64-IZHINXMIN-NEXT: addi sp, sp, 16
+; CHECK64-IZHINXMIN-NEXT: ret
+;
+; CHECK32-IZDINXZHINXMIN-LABEL: half_to_int_uint:
+; CHECK32-IZDINXZHINXMIN: # %bb.0: # %entry
+; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, -16
+; CHECK32-IZDINXZHINXMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK32-IZDINXZHINXMIN-NEXT: sh a0, 14(sp)
+; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.s.h a0, a0
+; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.w.s a1, a0, rtz
+; CHECK32-IZDINXZHINXMIN-NEXT: sw a1, 8(sp)
+; CHECK32-IZDINXZHINXMIN-NEXT: fcvt.wu.s a0, a0, rtz
+; CHECK32-IZDINXZHINXMIN-NEXT: sw a0, 4(sp)
+; CHECK32-IZDINXZHINXMIN-NEXT: addi sp, sp, 16
+; CHECK32-IZDINXZHINXMIN-NEXT: ret
+;
+; CHECK64-IZDINXZHINXMIN-LABEL: half_to_int_uint:
+; CHECK64-IZDINXZHINXMIN: # %bb.0: # %entry
+; CHECK64-IZDINXZHINXMIN-NEXT: addi sp, sp, -16
+; CHECK64-IZDINXZHINXMIN-NEXT: .cfi_def_cfa_offset 16
+; CHECK64-IZDINXZHINXMIN-NEXT: sh a0, 14(sp)
+; CHECK64-IZDINXZHINXMIN-NEXT: fcvt.s.h a1, a0
+; CHECK64-IZDINXZHINXMIN-NEXT: fcvt.w.s a1, a1, rtz
+; CHECK64-IZDINXZHINXMIN-NEXT: sw a1, 8(sp)
+; CHECK64-IZDINXZHINXMIN-NEXT: fcvt.s.h a0, a0
+; CHECK64-IZDINXZHINXMIN-NEXT: fcvt.wu.s a0, a0, rtz
+; CHECK64-IZDINXZHINXMIN-NEXT: sw a0, 4(sp)
+; CHECK64-IZDINXZHINXMIN-NEXT: addi sp, sp, 16
+; CHECK64-IZDINXZHINXMIN-NEXT: ret
+entry:
+ %p1.addr = alloca half, align 2
+ %i1 = alloca i32, align 4
+ %i2 = alloca i32, align 4
+ store half %p1, ptr %p1.addr, align 2
+ %0 = load half, ptr %p1.addr, align 2
+ %conv = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %0, metadata !"fpexcept.ignore") #2
+ store i32 %conv, ptr %i1, align 4
+ %1 = load half, ptr %p1.addr, align 2
+ %conv1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %1, metadata !"fpexcept.ignore") #2
+ store i32 %conv1, ptr %i2, align 4
+ ret void
+}
More information about the llvm-commits
mailing list