Skip to content

Commit c2bb056

Browse files
authored
[SelectionDAG][RISCV][AArch64] Allow f16 STRICT_FLDEXP to be promoted. Fix integer promotion of STRICT_FLDEXP in type legalizer. (#117633)
A special case in type legalization wasn't accounting for different operand numbering between FLDEXP and STRICT_FLDEXP. AArch64 already asked STRICT_FLDEXP to be promoted, but had no test for it.
1 parent cac9783 commit c2bb056

File tree

8 files changed

+290
-4
lines changed

8 files changed

+290
-4
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5472,6 +5472,19 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
54725472
DAG.getIntPtrConstant(isTrunc, dl, /*isTarget=*/true)));
54735473
break;
54745474
}
5475+
case ISD::STRICT_FLDEXP: {
5476+
Tmp1 = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {NVT, MVT::Other},
5477+
{Node->getOperand(0), Node->getOperand(1)});
5478+
Tmp2 = Node->getOperand(2);
5479+
Tmp3 = DAG.getNode(ISD::STRICT_FLDEXP, dl, {NVT, MVT::Other},
5480+
{Tmp1.getValue(1), Tmp1, Tmp2});
5481+
Tmp4 = DAG.getNode(ISD::STRICT_FP_ROUND, dl, {OVT, MVT::Other},
5482+
{Tmp3.getValue(1), Tmp3,
5483+
DAG.getIntPtrConstant(0, dl, /*isTarget=*/true)});
5484+
Results.push_back(Tmp4);
5485+
Results.push_back(Tmp4.getValue(1));
5486+
break;
5487+
}
54755488
case ISD::STRICT_FPOWI:
54765489
Tmp1 = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {NVT, MVT::Other},
54775490
{Node->getOperand(0), Node->getOperand(1)});

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,15 +2577,17 @@ SDValue DAGTypeLegalizer::PromoteIntOp_ExpOp(SDNode *N) {
25772577

25782578
bool IsPowI =
25792579
N->getOpcode() == ISD::FPOWI || N->getOpcode() == ISD::STRICT_FPOWI;
2580+
unsigned OpOffset = IsStrict ? 1 : 0;
25802581

25812582
// The integer operand is the last operand in FPOWI (or FLDEXP) (so the result
25822583
// and floating point operand is already type legalized).
25832584
RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(N->getValueType(0))
25842585
: RTLIB::getLDEXP(N->getValueType(0));
25852586

25862587
if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC)) {
2587-
SDValue Op = SExtPromotedInteger(N->getOperand(1));
2588-
return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Op), 0);
2588+
SmallVector<SDValue, 3> NewOps(N->ops());
2589+
NewOps[1 + OpOffset] = SExtPromotedInteger(N->getOperand(1 + OpOffset));
2590+
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
25892591
}
25902592

25912593
// We can't just promote the exponent type in FPOWI, since we want to lower
@@ -2594,7 +2596,6 @@ SDValue DAGTypeLegalizer::PromoteIntOp_ExpOp(SDNode *N) {
25942596
// we rewrite to a libcall here directly, letting makeLibCall handle promotion
25952597
// if the target accepts it according to shouldSignExtendTypeInLibCall.
25962598

2597-
unsigned OpOffset = IsStrict ? 1 : 0;
25982599
// The exponent should fit in a sizeof(int) type for the libcall to be valid.
25992600
assert(DAG.getLibInfo().getIntSize() ==
26002601
N->getOperand(1 + OpOffset).getValueType().getSizeInBits() &&

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
506506
setOperationAction({ISD::STRICT_FCEIL, ISD::STRICT_FFLOOR,
507507
ISD::STRICT_FNEARBYINT, ISD::STRICT_FRINT,
508508
ISD::STRICT_FROUND, ISD::STRICT_FROUNDEVEN,
509-
ISD::STRICT_FTRUNC},
509+
ISD::STRICT_FTRUNC, ISD::STRICT_FLDEXP},
510510
MVT::f16, Promote);
511511

512512
// We need to custom promote this.

llvm/test/CodeGen/AArch64/fp-intrinsics-fp16.ll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for round_f16
5454
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for roundeven_f16
5555
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for trunc_f16
56+
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for ldexp_f16
5657
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for fcmp_olt_f16
5758
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for fcmp_ole_f16
5859
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for fcmp_ogt_f16
@@ -833,6 +834,21 @@ define half @trunc_f16(half %x) #0 {
833834
ret half %val
834835
}
835836

837+
define half @ldexp_f16(half %x, i32 %y) #0 {
838+
; CHECK-LABEL: ldexp_f16:
839+
; CHECK: // %bb.0:
840+
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
841+
; CHECK-NEXT: .cfi_def_cfa_offset 16
842+
; CHECK-NEXT: .cfi_offset w30, -16
843+
; CHECK-NEXT: fcvt s0, h0
844+
; CHECK-NEXT: bl ldexpf
845+
; CHECK-NEXT: fcvt h0, s0
846+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
847+
; CHECK-NEXT: ret
848+
%val = call half @llvm.experimental.constrained.ldexp.f16.i32(half %x, i32 %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
849+
ret half %val
850+
}
851+
836852
define i32 @fcmp_olt_f16(half %a, half %b) #0 {
837853
; CHECK-NOFP16-LABEL: fcmp_olt_f16:
838854
; CHECK-NOFP16: // %bb.0:

llvm/test/CodeGen/RISCV/double-intrinsics-strict.ll

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,3 +1695,61 @@ define double @atan2_f64(double %a, double %b) nounwind strictfp {
16951695
%1 = call double @llvm.experimental.constrained.atan2.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
16961696
ret double %1
16971697
}
1698+
1699+
define double @ldexp_f64(double %x, i32 signext %y) nounwind {
1700+
; RV32IFD-LABEL: ldexp_f64:
1701+
; RV32IFD: # %bb.0:
1702+
; RV32IFD-NEXT: addi sp, sp, -16
1703+
; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1704+
; RV32IFD-NEXT: call ldexp
1705+
; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1706+
; RV32IFD-NEXT: addi sp, sp, 16
1707+
; RV32IFD-NEXT: ret
1708+
;
1709+
; RV64IFD-LABEL: ldexp_f64:
1710+
; RV64IFD: # %bb.0:
1711+
; RV64IFD-NEXT: addi sp, sp, -16
1712+
; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1713+
; RV64IFD-NEXT: call ldexp
1714+
; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1715+
; RV64IFD-NEXT: addi sp, sp, 16
1716+
; RV64IFD-NEXT: ret
1717+
;
1718+
; RV32IZFINXZDINX-LABEL: ldexp_f64:
1719+
; RV32IZFINXZDINX: # %bb.0:
1720+
; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1721+
; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1722+
; RV32IZFINXZDINX-NEXT: call ldexp
1723+
; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1724+
; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1725+
; RV32IZFINXZDINX-NEXT: ret
1726+
;
1727+
; RV64IZFINXZDINX-LABEL: ldexp_f64:
1728+
; RV64IZFINXZDINX: # %bb.0:
1729+
; RV64IZFINXZDINX-NEXT: addi sp, sp, -16
1730+
; RV64IZFINXZDINX-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1731+
; RV64IZFINXZDINX-NEXT: call ldexp
1732+
; RV64IZFINXZDINX-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1733+
; RV64IZFINXZDINX-NEXT: addi sp, sp, 16
1734+
; RV64IZFINXZDINX-NEXT: ret
1735+
;
1736+
; RV32I-LABEL: ldexp_f64:
1737+
; RV32I: # %bb.0:
1738+
; RV32I-NEXT: addi sp, sp, -16
1739+
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1740+
; RV32I-NEXT: call ldexp
1741+
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1742+
; RV32I-NEXT: addi sp, sp, 16
1743+
; RV32I-NEXT: ret
1744+
;
1745+
; RV64I-LABEL: ldexp_f64:
1746+
; RV64I: # %bb.0:
1747+
; RV64I-NEXT: addi sp, sp, -16
1748+
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1749+
; RV64I-NEXT: call ldexp
1750+
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1751+
; RV64I-NEXT: addi sp, sp, 16
1752+
; RV64I-NEXT: ret
1753+
%z = call double @llvm.experimental.constrained.ldexp.f64.i32(double %x, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
1754+
ret double %z
1755+
}

llvm/test/CodeGen/RISCV/float-intrinsics-strict.ll

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,3 +1660,61 @@ define i64 @llround_f32(float %a) nounwind strictfp {
16601660
%1 = call i64 @llvm.experimental.constrained.llround.i64.f32(float %a, metadata !"fpexcept.strict") strictfp
16611661
ret i64 %1
16621662
}
1663+
1664+
define float @ldexp_f32(float %x, i32 signext %y) nounwind {
1665+
; RV32IF-LABEL: ldexp_f32:
1666+
; RV32IF: # %bb.0:
1667+
; RV32IF-NEXT: addi sp, sp, -16
1668+
; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1669+
; RV32IF-NEXT: call ldexpf
1670+
; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1671+
; RV32IF-NEXT: addi sp, sp, 16
1672+
; RV32IF-NEXT: ret
1673+
;
1674+
; RV64IF-LABEL: ldexp_f32:
1675+
; RV64IF: # %bb.0:
1676+
; RV64IF-NEXT: addi sp, sp, -16
1677+
; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1678+
; RV64IF-NEXT: call ldexpf
1679+
; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1680+
; RV64IF-NEXT: addi sp, sp, 16
1681+
; RV64IF-NEXT: ret
1682+
;
1683+
; RV32IZFINX-LABEL: ldexp_f32:
1684+
; RV32IZFINX: # %bb.0:
1685+
; RV32IZFINX-NEXT: addi sp, sp, -16
1686+
; RV32IZFINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1687+
; RV32IZFINX-NEXT: call ldexpf
1688+
; RV32IZFINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1689+
; RV32IZFINX-NEXT: addi sp, sp, 16
1690+
; RV32IZFINX-NEXT: ret
1691+
;
1692+
; RV64IZFINX-LABEL: ldexp_f32:
1693+
; RV64IZFINX: # %bb.0:
1694+
; RV64IZFINX-NEXT: addi sp, sp, -16
1695+
; RV64IZFINX-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1696+
; RV64IZFINX-NEXT: call ldexpf
1697+
; RV64IZFINX-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1698+
; RV64IZFINX-NEXT: addi sp, sp, 16
1699+
; RV64IZFINX-NEXT: ret
1700+
;
1701+
; RV32I-LABEL: ldexp_f32:
1702+
; RV32I: # %bb.0:
1703+
; RV32I-NEXT: addi sp, sp, -16
1704+
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1705+
; RV32I-NEXT: call ldexpf
1706+
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1707+
; RV32I-NEXT: addi sp, sp, 16
1708+
; RV32I-NEXT: ret
1709+
;
1710+
; RV64I-LABEL: ldexp_f32:
1711+
; RV64I: # %bb.0:
1712+
; RV64I-NEXT: addi sp, sp, -16
1713+
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1714+
; RV64I-NEXT: call ldexpf
1715+
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1716+
; RV64I-NEXT: addi sp, sp, 16
1717+
; RV64I-NEXT: ret
1718+
%z = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
1719+
ret float %z
1720+
}

llvm/test/CodeGen/RISCV/zfh-half-intrinsics-strict.ll

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,3 +737,73 @@ define i64 @llround_f16(half %a) nounwind strictfp {
737737
%1 = call i64 @llvm.experimental.constrained.llround.i64.f16(half %a, metadata !"fpexcept.strict") strictfp
738738
ret i64 %1
739739
}
740+
741+
define half @ldexp_f16(half %x, i32 signext %y) nounwind {
742+
; RV32IZFH-LABEL: ldexp_f16:
743+
; RV32IZFH: # %bb.0:
744+
; RV32IZFH-NEXT: addi sp, sp, -16
745+
; RV32IZFH-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
746+
; RV32IZFH-NEXT: fcvt.s.h fa0, fa0
747+
; RV32IZFH-NEXT: call ldexpf
748+
; RV32IZFH-NEXT: fcvt.h.s fa0, fa0
749+
; RV32IZFH-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
750+
; RV32IZFH-NEXT: addi sp, sp, 16
751+
; RV32IZFH-NEXT: ret
752+
;
753+
; RV64IZFH-LABEL: ldexp_f16:
754+
; RV64IZFH: # %bb.0:
755+
; RV64IZFH-NEXT: addi sp, sp, -16
756+
; RV64IZFH-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
757+
; RV64IZFH-NEXT: fcvt.s.h fa0, fa0
758+
; RV64IZFH-NEXT: call ldexpf
759+
; RV64IZFH-NEXT: fcvt.h.s fa0, fa0
760+
; RV64IZFH-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
761+
; RV64IZFH-NEXT: addi sp, sp, 16
762+
; RV64IZFH-NEXT: ret
763+
;
764+
; RV32IZHINX-LABEL: ldexp_f16:
765+
; RV32IZHINX: # %bb.0:
766+
; RV32IZHINX-NEXT: addi sp, sp, -16
767+
; RV32IZHINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
768+
; RV32IZHINX-NEXT: fcvt.s.h a0, a0
769+
; RV32IZHINX-NEXT: call ldexpf
770+
; RV32IZHINX-NEXT: fcvt.h.s a0, a0
771+
; RV32IZHINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
772+
; RV32IZHINX-NEXT: addi sp, sp, 16
773+
; RV32IZHINX-NEXT: ret
774+
;
775+
; RV64IZHINX-LABEL: ldexp_f16:
776+
; RV64IZHINX: # %bb.0:
777+
; RV64IZHINX-NEXT: addi sp, sp, -16
778+
; RV64IZHINX-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
779+
; RV64IZHINX-NEXT: fcvt.s.h a0, a0
780+
; RV64IZHINX-NEXT: call ldexpf
781+
; RV64IZHINX-NEXT: fcvt.h.s a0, a0
782+
; RV64IZHINX-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
783+
; RV64IZHINX-NEXT: addi sp, sp, 16
784+
; RV64IZHINX-NEXT: ret
785+
;
786+
; RV32IZDINXZHINX-LABEL: ldexp_f16:
787+
; RV32IZDINXZHINX: # %bb.0:
788+
; RV32IZDINXZHINX-NEXT: addi sp, sp, -16
789+
; RV32IZDINXZHINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
790+
; RV32IZDINXZHINX-NEXT: fcvt.s.h a0, a0
791+
; RV32IZDINXZHINX-NEXT: call ldexpf
792+
; RV32IZDINXZHINX-NEXT: fcvt.h.s a0, a0
793+
; RV32IZDINXZHINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
794+
; RV32IZDINXZHINX-NEXT: addi sp, sp, 16
795+
; RV32IZDINXZHINX-NEXT: ret
796+
;
797+
; RV64IZDINXZHINX-LABEL: ldexp_f16:
798+
; RV64IZDINXZHINX: # %bb.0:
799+
; RV64IZDINXZHINX-NEXT: addi sp, sp, -16
800+
; RV64IZDINXZHINX-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
801+
; RV64IZDINXZHINX-NEXT: fcvt.s.h a0, a0
802+
; RV64IZDINXZHINX-NEXT: call ldexpf
803+
; RV64IZDINXZHINX-NEXT: fcvt.h.s a0, a0
804+
; RV64IZDINXZHINX-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
805+
; RV64IZDINXZHINX-NEXT: addi sp, sp, 16
806+
; RV64IZDINXZHINX-NEXT: ret
807+
%z = call half @llvm.experimental.constrained.ldexp.f16.i32(half %x, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
808+
ret half %z
809+
}

llvm/test/CodeGen/RISCV/zfhmin-half-intrinsics-strict.ll

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,3 +767,73 @@ define i64 @llround_f16(half %a) nounwind strictfp {
767767
%1 = call i64 @llvm.experimental.constrained.llround.i64.f16(half %a, metadata !"fpexcept.strict") strictfp
768768
ret i64 %1
769769
}
770+
771+
define half @ldexp_f16(half %x, i32 signext %y) nounwind {
772+
; RV32IZFHMIN-LABEL: ldexp_f16:
773+
; RV32IZFHMIN: # %bb.0:
774+
; RV32IZFHMIN-NEXT: addi sp, sp, -16
775+
; RV32IZFHMIN-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
776+
; RV32IZFHMIN-NEXT: fcvt.s.h fa0, fa0
777+
; RV32IZFHMIN-NEXT: call ldexpf
778+
; RV32IZFHMIN-NEXT: fcvt.h.s fa0, fa0
779+
; RV32IZFHMIN-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
780+
; RV32IZFHMIN-NEXT: addi sp, sp, 16
781+
; RV32IZFHMIN-NEXT: ret
782+
;
783+
; RV64IZFHMIN-LABEL: ldexp_f16:
784+
; RV64IZFHMIN: # %bb.0:
785+
; RV64IZFHMIN-NEXT: addi sp, sp, -16
786+
; RV64IZFHMIN-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
787+
; RV64IZFHMIN-NEXT: fcvt.s.h fa0, fa0
788+
; RV64IZFHMIN-NEXT: call ldexpf
789+
; RV64IZFHMIN-NEXT: fcvt.h.s fa0, fa0
790+
; RV64IZFHMIN-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
791+
; RV64IZFHMIN-NEXT: addi sp, sp, 16
792+
; RV64IZFHMIN-NEXT: ret
793+
;
794+
; RV32IZHINXMIN-STRICT-LABEL: ldexp_f16:
795+
; RV32IZHINXMIN-STRICT: # %bb.0:
796+
; RV32IZHINXMIN-STRICT-NEXT: addi sp, sp, -16
797+
; RV32IZHINXMIN-STRICT-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
798+
; RV32IZHINXMIN-STRICT-NEXT: fcvt.s.h a0, a0
799+
; RV32IZHINXMIN-STRICT-NEXT: call ldexpf
800+
; RV32IZHINXMIN-STRICT-NEXT: fcvt.h.s a0, a0
801+
; RV32IZHINXMIN-STRICT-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
802+
; RV32IZHINXMIN-STRICT-NEXT: addi sp, sp, 16
803+
; RV32IZHINXMIN-STRICT-NEXT: ret
804+
;
805+
; RV64IZHINXMIN-STRICT-LABEL: ldexp_f16:
806+
; RV64IZHINXMIN-STRICT: # %bb.0:
807+
; RV64IZHINXMIN-STRICT-NEXT: addi sp, sp, -16
808+
; RV64IZHINXMIN-STRICT-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
809+
; RV64IZHINXMIN-STRICT-NEXT: fcvt.s.h a0, a0
810+
; RV64IZHINXMIN-STRICT-NEXT: call ldexpf
811+
; RV64IZHINXMIN-STRICT-NEXT: fcvt.h.s a0, a0
812+
; RV64IZHINXMIN-STRICT-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
813+
; RV64IZHINXMIN-STRICT-NEXT: addi sp, sp, 16
814+
; RV64IZHINXMIN-STRICT-NEXT: ret
815+
;
816+
; RV32IZDINXZHINXMIN-LABEL: ldexp_f16:
817+
; RV32IZDINXZHINXMIN: # %bb.0:
818+
; RV32IZDINXZHINXMIN-NEXT: addi sp, sp, -16
819+
; RV32IZDINXZHINXMIN-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
820+
; RV32IZDINXZHINXMIN-NEXT: fcvt.s.h a0, a0
821+
; RV32IZDINXZHINXMIN-NEXT: call ldexpf
822+
; RV32IZDINXZHINXMIN-NEXT: fcvt.h.s a0, a0
823+
; RV32IZDINXZHINXMIN-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
824+
; RV32IZDINXZHINXMIN-NEXT: addi sp, sp, 16
825+
; RV32IZDINXZHINXMIN-NEXT: ret
826+
;
827+
; RV64IZDINXZHINXMIN-LABEL: ldexp_f16:
828+
; RV64IZDINXZHINXMIN: # %bb.0:
829+
; RV64IZDINXZHINXMIN-NEXT: addi sp, sp, -16
830+
; RV64IZDINXZHINXMIN-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
831+
; RV64IZDINXZHINXMIN-NEXT: fcvt.s.h a0, a0
832+
; RV64IZDINXZHINXMIN-NEXT: call ldexpf
833+
; RV64IZDINXZHINXMIN-NEXT: fcvt.h.s a0, a0
834+
; RV64IZDINXZHINXMIN-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
835+
; RV64IZDINXZHINXMIN-NEXT: addi sp, sp, 16
836+
; RV64IZDINXZHINXMIN-NEXT: ret
837+
%z = call half @llvm.experimental.constrained.ldexp.f16.i32(half %x, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
838+
ret half %z
839+
}

0 commit comments

Comments
 (0)