Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVInstrInfoZfh.td
blob19d467f3b344c2a519e874534b00d5508984d1ae
1 //===-- RISCVInstrInfoZfh.td - RISC-V 'Zfh' instructions ---*- tablegen -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file describes the RISC-V instructions from the standard 'Zfh'
10 // half-precision floating-point extension, version 1.0.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // RISC-V specific DAG Nodes.
16 //===----------------------------------------------------------------------===//
18 def SDT_RISCVFMV_H_X
19     : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, XLenVT>]>;
20 def SDT_RISCVFMV_X_EXTH
21     : SDTypeProfile<1, 1, [SDTCisVT<0, XLenVT>, SDTCisFP<1>]>;
23 def riscv_fmv_h_x
24     : SDNode<"RISCVISD::FMV_H_X", SDT_RISCVFMV_H_X>;
25 def riscv_fmv_x_anyexth
26     : SDNode<"RISCVISD::FMV_X_ANYEXTH", SDT_RISCVFMV_X_EXTH>;
27 def riscv_fmv_x_signexth
28     : SDNode<"RISCVISD::FMV_X_SIGNEXTH", SDT_RISCVFMV_X_EXTH>;
30 //===----------------------------------------------------------------------===//
31 // Operand and SDNode transformation definitions.
32 //===----------------------------------------------------------------------===//
34 // Zhinxmin and Zhinx
36 def FPR16INX : RegisterOperand<GPRF16> {
37   let ParserMatchClass = GPRAsFPR;
38   let DecoderMethod = "DecodeGPRRegisterClass";
41 def ZfhExt     : ExtInfo<"", "", [HasStdExtZfh],
42                          f16, FPR16, FPR32, ?, FPR16>;
43 def ZfhminExt  : ExtInfo<"", "", [HasStdExtZfhOrZfhmin],
44                          f16, FPR16, FPR32, ?, FPR16>;
45 def ZfhDExt    : ExtInfo<"", "", [HasStdExtZfh, HasStdExtD],
46                          ?, ?, FPR32, FPR64, FPR16>;
47 def ZfhminDExt : ExtInfo<"", "", [HasStdExtZfhOrZfhmin, HasStdExtD],
48                          ?, ?, FPR32, FPR64, FPR16>;
50 def ZhinxExt            : ExtInfo<"_INX", "RVZfinx",
51                                   [HasStdExtZhinx],
52                                   f16, FPR16INX, FPR32INX, ?, FPR16INX>;
53 def ZhinxminExt         : ExtInfo<"_INX", "RVZfinx",
54                                   [HasStdExtZhinxOrZhinxmin],
55                                   f16, FPR16INX, FPR32INX, ?, FPR16INX>;
56 def ZhinxZdinxExt       : ExtInfo<"_INX", "RVZfinx",
57                                   [HasStdExtZhinx, HasStdExtZdinx, IsRV64],
58                                   ?, ?, FPR32INX, FPR64INX, FPR16INX>;
59 def ZhinxminZdinxExt    : ExtInfo<"_INX", "RVZfinx",
60                                   [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV64],
61                                   ?, ?, FPR32INX, FPR64INX, FPR16INX>;
62 def ZhinxZdinx32Ext     : ExtInfo<"_IN32X", "RV32Zdinx",
63                                   [HasStdExtZhinx, HasStdExtZdinx, IsRV32],
64                                   ?, ?, FPR32INX, FPR64IN32X, FPR16INX >;
65 def ZhinxminZdinx32Ext  : ExtInfo<"_IN32X", "RV32Zdinx",
66                                   [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV32],
67                                   ?, ?, FPR32INX, FPR64IN32X, FPR16INX>;
69 defvar ZfhExts = [ZfhExt, ZhinxExt];
70 defvar ZfhminExts = [ZfhminExt, ZhinxminExt];
71 defvar ZfhDExts = [ZfhDExt, ZhinxZdinxExt, ZhinxZdinx32Ext];
72 defvar ZfhminDExts = [ZfhminDExt, ZhinxminZdinxExt, ZhinxminZdinx32Ext];
74 //===----------------------------------------------------------------------===//
75 // Instructions
76 //===----------------------------------------------------------------------===//
78 let Predicates = [HasHalfFPLoadStoreMove] in {
79 def FLH : FPLoad_r<0b001, "flh", FPR16, WriteFLD16>;
81 // Operands for stores are in the order srcreg, base, offset rather than
82 // reflecting the order these fields are specified in the instruction
83 // encoding.
84 def FSH : FPStore_r<0b001, "fsh", FPR16, WriteFST16>;
85 } // Predicates = [HasHalfFPLoadStoreMove]
87 foreach Ext = ZfhExts in {
88   let SchedRW = [WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16Addend] in {
89     defm FMADD_H  : FPFMA_rrr_frm_m<OPC_MADD,  0b10, "fmadd.h",  Ext>;
90     defm FMSUB_H  : FPFMA_rrr_frm_m<OPC_MSUB,  0b10, "fmsub.h",  Ext>;
91     defm FNMSUB_H : FPFMA_rrr_frm_m<OPC_NMSUB, 0b10, "fnmsub.h", Ext>;
92     defm FNMADD_H : FPFMA_rrr_frm_m<OPC_NMADD, 0b10, "fnmadd.h", Ext>;
93   }
95   let SchedRW = [WriteFAdd16, ReadFAdd16, ReadFAdd16] in {
96     defm FADD_H : FPALU_rr_frm_m<0b0000010, "fadd.h", Ext, Commutable=1>;
97     defm FSUB_H : FPALU_rr_frm_m<0b0000110, "fsub.h", Ext>;
98   }
99   let SchedRW = [WriteFMul16, ReadFMul16, ReadFMul16] in
100   defm FMUL_H : FPALU_rr_frm_m<0b0001010, "fmul.h", Ext, Commutable=1>;
102   let SchedRW = [WriteFDiv16, ReadFDiv16, ReadFDiv16] in
103   defm FDIV_H : FPALU_rr_frm_m<0b0001110, "fdiv.h", Ext>;
105   defm FSQRT_H : FPUnaryOp_r_frm_m<0b0101110, 0b00000, Ext, Ext.PrimaryTy,
106                                    Ext.PrimaryTy, "fsqrt.h">,
107                  Sched<[WriteFSqrt16, ReadFSqrt16]>;
109   let SchedRW = [WriteFSGNJ16, ReadFSGNJ16, ReadFSGNJ16],
110       mayRaiseFPException = 0 in {
111     defm FSGNJ_H  : FPALU_rr_m<0b0010010, 0b000, "fsgnj.h",  Ext>;
112     defm FSGNJN_H : FPALU_rr_m<0b0010010, 0b001, "fsgnjn.h", Ext>;
113     defm FSGNJX_H : FPALU_rr_m<0b0010010, 0b010, "fsgnjx.h", Ext>;
114   }
116   let SchedRW = [WriteFMinMax16, ReadFMinMax16, ReadFMinMax16] in {
117     defm FMIN_H   : FPALU_rr_m<0b0010110, 0b000, "fmin.h", Ext, Commutable=1>;
118     defm FMAX_H   : FPALU_rr_m<0b0010110, 0b001, "fmax.h", Ext, Commutable=1>;
119   }
121   let IsSignExtendingOpW = 1 in
122   defm FCVT_W_H : FPUnaryOp_r_frm_m<0b1100010, 0b00000, Ext, GPR, Ext.PrimaryTy,
123                                     "fcvt.w.h">,
124                   Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
126   let IsSignExtendingOpW = 1 in
127   defm FCVT_WU_H : FPUnaryOp_r_frm_m<0b1100010, 0b00001, Ext, GPR, Ext.PrimaryTy,
128                                      "fcvt.wu.h">,
129                    Sched<[WriteFCvtF16ToI32, ReadFCvtF16ToI32]>;
131   defm FCVT_H_W : FPUnaryOp_r_frm_m<0b1101010, 0b00000, Ext, Ext.PrimaryTy, GPR,
132                                     "fcvt.h.w">,
133                   Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
135   defm FCVT_H_WU : FPUnaryOp_r_frm_m<0b1101010, 0b00001, Ext, Ext.PrimaryTy, GPR,
136                                      "fcvt.h.wu">,
137                    Sched<[WriteFCvtI32ToF16, ReadFCvtI32ToF16]>;
138 } // foreach Ext = ZfhExts
140 foreach Ext = ZfhminExts in {
141   defm FCVT_H_S : FPUnaryOp_r_frm_m<0b0100010, 0b00000, Ext, Ext.PrimaryTy,
142                                     Ext.F32Ty, "fcvt.h.s">,
143                   Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
145   defm FCVT_S_H : FPUnaryOp_r_frmlegacy_m<0b0100000, 0b00010,Ext, Ext.F32Ty,
146                                           Ext.PrimaryTy, "fcvt.s.h">,
147                  Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]>;
148 } // foreach Ext = ZfhminExts
150 let Predicates = [HasHalfFPLoadStoreMove] in {
151 let mayRaiseFPException = 0, IsSignExtendingOpW = 1 in
152 def FMV_X_H : FPUnaryOp_r<0b1110010, 0b00000, 0b000, GPR, FPR16, "fmv.x.h">,
153               Sched<[WriteFMovF16ToI16, ReadFMovF16ToI16]>;
155 let mayRaiseFPException = 0 in
156 def FMV_H_X : FPUnaryOp_r<0b1111010, 0b00000, 0b000, FPR16, GPR, "fmv.h.x">,
157               Sched<[WriteFMovI16ToF16, ReadFMovI16ToF16]>;
158 } // Predicates = [HasHalfFPLoadStoreMove]
160 foreach Ext = ZfhExts in {
161   let SchedRW = [WriteFCmp16, ReadFCmp16, ReadFCmp16] in {
162     defm FEQ_H : FPCmp_rr_m<0b1010010, 0b010, "feq.h", Ext, Commutable=1>;
163     defm FLT_H : FPCmp_rr_m<0b1010010, 0b001, "flt.h", Ext>;
164     defm FLE_H : FPCmp_rr_m<0b1010010, 0b000, "fle.h", Ext>;
165   }
167   let mayRaiseFPException = 0 in
168   defm FCLASS_H : FPUnaryOp_r_m<0b1110010, 0b00000, 0b001, Ext, GPR, Ext.PrimaryTy,
169                                 "fclass.h">,
170                   Sched<[WriteFClass16, ReadFClass16]>;
172   defm FCVT_L_H  : FPUnaryOp_r_frm_m<0b1100010, 0b00010, Ext, GPR, Ext.PrimaryTy,
173                                      "fcvt.l.h", [IsRV64]>,
174                    Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
176   defm FCVT_LU_H  : FPUnaryOp_r_frm_m<0b1100010, 0b00011, Ext, GPR, Ext.PrimaryTy,
177                                       "fcvt.lu.h", [IsRV64]>,
178                     Sched<[WriteFCvtF16ToI64, ReadFCvtF16ToI64]>;
180   defm FCVT_H_L : FPUnaryOp_r_frm_m<0b1101010, 0b00010, Ext, Ext.PrimaryTy, GPR,
181                                     "fcvt.h.l", [IsRV64]>,
182                   Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
184   defm FCVT_H_LU : FPUnaryOp_r_frm_m<0b1101010, 0b00011, Ext, Ext.PrimaryTy, GPR,
185                                      "fcvt.h.lu", [IsRV64]>,
186                    Sched<[WriteFCvtI64ToF16, ReadFCvtI64ToF16]>;
187 } // foreach Ext = ZfhExts
189 foreach Ext = ZfhminDExts in {
190   defm FCVT_H_D : FPUnaryOp_r_frm_m<0b0100010, 0b00001, Ext, Ext.F16Ty,
191                                    Ext.F64Ty, "fcvt.h.d">,
192                   Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>;
194   defm FCVT_D_H : FPUnaryOp_r_frmlegacy_m<0b0100001, 0b00010, Ext, Ext.F64Ty,
195                                           Ext.F16Ty, "fcvt.d.h">,
196                   Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>;
197 } // foreach Ext = ZfhminDExts
199 //===----------------------------------------------------------------------===//
200 // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
201 //===----------------------------------------------------------------------===//
203 let Predicates = [HasStdExtZfhOrZfhmin] in {
204 def : InstAlias<"flh $rd, (${rs1})",  (FLH FPR16:$rd,  GPR:$rs1, 0), 0>;
205 def : InstAlias<"fsh $rs2, (${rs1})", (FSH FPR16:$rs2, GPR:$rs1, 0), 0>;
206 } // Predicates = [HasStdExtZfhOrZfhmin]
208 let Predicates = [HasStdExtZfh] in {
209 def : InstAlias<"fmv.h $rd, $rs",  (FSGNJ_H  FPR16:$rd, FPR16:$rs, FPR16:$rs)>;
210 def : InstAlias<"fabs.h $rd, $rs", (FSGNJX_H FPR16:$rd, FPR16:$rs, FPR16:$rs)>;
211 def : InstAlias<"fneg.h $rd, $rs", (FSGNJN_H FPR16:$rd, FPR16:$rs, FPR16:$rs)>;
213 // fgt.h/fge.h are recognised by the GNU assembler but the canonical
214 // flt.h/fle.h forms will always be printed. Therefore, set a zero weight.
215 def : InstAlias<"fgt.h $rd, $rs, $rt",
216                 (FLT_H GPR:$rd, FPR16:$rt, FPR16:$rs), 0>;
217 def : InstAlias<"fge.h $rd, $rs, $rt",
218                 (FLE_H GPR:$rd, FPR16:$rt, FPR16:$rs), 0>;
220 let usesCustomInserter = 1 in {
221 def PseudoQuietFLE_H : PseudoQuietFCMP<FPR16>;
222 def PseudoQuietFLT_H : PseudoQuietFCMP<FPR16>;
224 } // Predicates = [HasStdExtZfh]
226 let Predicates = [HasStdExtZfhOrZfhmin] in {
227 def PseudoFLH  : PseudoFloatLoad<"flh", FPR16>;
228 def PseudoFSH  : PseudoStore<"fsh", FPR16>;
229 } // Predicates = [HasStdExtZfhOrZfhmin]
231 let Predicates = [HasStdExtZhinx] in {
232 def : InstAlias<"fmv.h $rd, $rs",  (FSGNJ_H_INX  FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>;
233 def : InstAlias<"fabs.h $rd, $rs", (FSGNJX_H_INX FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>;
234 def : InstAlias<"fneg.h $rd, $rs", (FSGNJN_H_INX FPR16INX:$rd, FPR16INX:$rs, FPR16INX:$rs)>;
236 def : InstAlias<"fgt.h $rd, $rs, $rt",
237                 (FLT_H_INX GPR:$rd, FPR16INX:$rt, FPR16INX:$rs), 0>;
238 def : InstAlias<"fge.h $rd, $rs, $rt",
239                 (FLE_H_INX GPR:$rd, FPR16INX:$rt, FPR16INX:$rs), 0>;
241 let usesCustomInserter = 1 in {
242 def PseudoQuietFLE_H_INX : PseudoQuietFCMP<FPR16INX>;
243 def PseudoQuietFLT_H_INX : PseudoQuietFCMP<FPR16INX>;
245 } // Predicates = [HasStdExtZhinxOrZhinxmin]
247 //===----------------------------------------------------------------------===//
248 // Pseudo-instructions and codegen patterns
249 //===----------------------------------------------------------------------===//
252 /// Float conversion operations
254 // [u]int32<->float conversion patterns must be gated on IsRV32 or IsRV64, so
255 // are defined later.
257 /// Float arithmetic operations
259 foreach Ext = ZfhExts in {
260   defm : PatFprFprDynFrm_m<any_fadd, FADD_H, Ext>;
261   defm : PatFprFprDynFrm_m<any_fsub, FSUB_H, Ext>;
262   defm : PatFprFprDynFrm_m<any_fmul, FMUL_H, Ext>;
263   defm : PatFprFprDynFrm_m<any_fdiv, FDIV_H, Ext>;
266 let Predicates = [HasStdExtZfh] in {
267 def : Pat<(f16 (any_fsqrt FPR16:$rs1)), (FSQRT_H FPR16:$rs1, FRM_DYN)>;
269 def : Pat<(f16 (fneg FPR16:$rs1)), (FSGNJN_H $rs1, $rs1)>;
270 def : Pat<(f16 (fabs FPR16:$rs1)), (FSGNJX_H $rs1, $rs1)>;
272 def : Pat<(riscv_fpclass (f16 FPR16:$rs1)), (FCLASS_H $rs1)>;
274 def : PatFprFpr<fcopysign, FSGNJ_H, FPR16, f16>;
275 def : Pat<(f16 (fcopysign FPR16:$rs1, (f16 (fneg FPR16:$rs2)))), (FSGNJN_H $rs1, $rs2)>;
276 def : Pat<(f16 (fcopysign FPR16:$rs1, FPR32:$rs2)),
277           (FSGNJ_H $rs1, (FCVT_H_S $rs2, FRM_DYN))>;
279 // fmadd: rs1 * rs2 + rs3
280 def : Pat<(f16 (any_fma FPR16:$rs1, FPR16:$rs2, FPR16:$rs3)),
281           (FMADD_H $rs1, $rs2, $rs3, FRM_DYN)>;
283 // fmsub: rs1 * rs2 - rs3
284 def : Pat<(f16 (any_fma FPR16:$rs1, FPR16:$rs2, (fneg FPR16:$rs3))),
285           (FMSUB_H FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, FRM_DYN)>;
287 // fnmsub: -rs1 * rs2 + rs3
288 def : Pat<(f16 (any_fma (fneg FPR16:$rs1), FPR16:$rs2, FPR16:$rs3)),
289           (FNMSUB_H FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, FRM_DYN)>;
291 // fnmadd: -rs1 * rs2 - rs3
292 def : Pat<(f16 (any_fma (fneg FPR16:$rs1), FPR16:$rs2, (fneg FPR16:$rs3))),
293           (FNMADD_H FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, FRM_DYN)>;
295 // fnmadd: -(rs1 * rs2 + rs3) (the nsz flag on the FMA)
296 def : Pat<(f16 (fneg (any_fma_nsz FPR16:$rs1, FPR16:$rs2, FPR16:$rs3))),
297           (FNMADD_H FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, FRM_DYN)>;
298 } // Predicates = [HasStdExtZfh]
300 let Predicates = [HasStdExtZhinx] in {
302 /// Float conversion operations
304 // [u]int32<->float conversion patterns must be gated on IsRV32 or IsRV64, so
305 // are defined later.
307 /// Float arithmetic operations
309 def : Pat<(any_fsqrt FPR16INX:$rs1), (FSQRT_H_INX FPR16INX:$rs1, FRM_DYN)>;
311 def : Pat<(fneg FPR16INX:$rs1), (FSGNJN_H_INX $rs1, $rs1)>;
312 def : Pat<(fabs FPR16INX:$rs1), (FSGNJX_H_INX $rs1, $rs1)>;
314 def : Pat<(riscv_fpclass FPR16INX:$rs1), (FCLASS_H_INX $rs1)>;
316 def : PatFprFpr<fcopysign, FSGNJ_H_INX, FPR16INX, f16>;
317 def : Pat<(fcopysign FPR16INX:$rs1, (fneg FPR16INX:$rs2)), (FSGNJN_H_INX $rs1, $rs2)>;
318 def : Pat<(fcopysign FPR16INX:$rs1, FPR32INX:$rs2),
319           (FSGNJ_H_INX $rs1, (FCVT_H_S_INX $rs2, FRM_DYN))>;
321 // fmadd: rs1 * rs2 + rs3
322 def : Pat<(any_fma FPR16INX:$rs1, FPR16INX:$rs2, FPR16INX:$rs3),
323           (FMADD_H_INX $rs1, $rs2, $rs3, FRM_DYN)>;
325 // fmsub: rs1 * rs2 - rs3
326 def : Pat<(any_fma FPR16INX:$rs1, FPR16INX:$rs2, (fneg FPR16INX:$rs3)),
327           (FMSUB_H_INX FPR16INX:$rs1, FPR16INX:$rs2, FPR16INX:$rs3, FRM_DYN)>;
329 // fnmsub: -rs1 * rs2 + rs3
330 def : Pat<(any_fma (fneg FPR16INX:$rs1), FPR16INX:$rs2, FPR16INX:$rs3),
331           (FNMSUB_H_INX FPR16INX:$rs1, FPR16INX:$rs2, FPR16INX:$rs3, FRM_DYN)>;
333 // fnmadd: -rs1 * rs2 - rs3
334 def : Pat<(any_fma (fneg FPR16INX:$rs1), FPR16INX:$rs2, (fneg FPR16INX:$rs3)),
335           (FNMADD_H_INX FPR16INX:$rs1, FPR16INX:$rs2, FPR16INX:$rs3, FRM_DYN)>;
337 // fnmadd: -(rs1 * rs2 + rs3) (the nsz flag on the FMA)
338 def : Pat<(fneg (any_fma_nsz FPR16INX:$rs1, FPR16INX:$rs2, FPR16INX:$rs3)),
339           (FNMADD_H_INX FPR16INX:$rs1, FPR16INX:$rs2, FPR16INX:$rs3, FRM_DYN)>;
340 } // Predicates = [HasStdExtZhinx]
342 // The ratified 20191213 ISA spec defines fmin and fmax in a way that matches
343 // LLVM's fminnum and fmaxnum
344 // <https://github.com/riscv/riscv-isa-manual/commit/cd20cee7efd9bac7c5aa127ec3b451749d2b3cce>.
345 foreach Ext = ZfhExts in {
346   defm : PatFprFpr_m<fminnum, FMIN_H, Ext>;
347   defm : PatFprFpr_m<fmaxnum, FMAX_H, Ext>;
348   defm : PatFprFpr_m<riscv_fmin, FMIN_H, Ext>;
349   defm : PatFprFpr_m<riscv_fmax, FMAX_H, Ext>;
352 /// Setcc
353 // FIXME: SETEQ/SETLT/SETLE imply nonans, can we pick better instructions for
354 // strict versions of those.
356 // Match non-signaling FEQ_D
357 foreach Ext = ZfhExts in {
358   defm : PatSetCC_m<any_fsetcc,    SETEQ,  FEQ_H,            Ext>;
359   defm : PatSetCC_m<any_fsetcc,    SETOEQ, FEQ_H,            Ext>;
360   defm : PatSetCC_m<strict_fsetcc, SETLT,  PseudoQuietFLT_H, Ext>;
361   defm : PatSetCC_m<strict_fsetcc, SETOLT, PseudoQuietFLT_H, Ext>;
362   defm : PatSetCC_m<strict_fsetcc, SETLE,  PseudoQuietFLE_H, Ext>;
363   defm : PatSetCC_m<strict_fsetcc, SETOLE, PseudoQuietFLE_H, Ext>;
366 let Predicates = [HasStdExtZfh] in {
367 // Match signaling FEQ_H
368 def : Pat<(XLenVT (strict_fsetccs (f16 FPR16:$rs1), FPR16:$rs2, SETEQ)),
369           (AND (FLE_H $rs1, $rs2),
370                (FLE_H $rs2, $rs1))>;
371 def : Pat<(XLenVT (strict_fsetccs (f16 FPR16:$rs1), FPR16:$rs2, SETOEQ)),
372           (AND (FLE_H $rs1, $rs2),
373                (FLE_H $rs2, $rs1))>;
374 // If both operands are the same, use a single FLE.
375 def : Pat<(XLenVT (strict_fsetccs (f16 FPR16:$rs1), (f16 FPR16:$rs1), SETEQ)),
376           (FLE_H $rs1, $rs1)>;
377 def : Pat<(XLenVT (strict_fsetccs (f16 FPR16:$rs1), (f16 FPR16:$rs1), SETOEQ)),
378           (FLE_H $rs1, $rs1)>;
379 } // Predicates = [HasStdExtZfh]
381 let Predicates = [HasStdExtZhinx] in {
382 // Match signaling FEQ_H
383 def : Pat<(XLenVT (strict_fsetccs FPR16INX:$rs1, FPR16INX:$rs2, SETEQ)),
384           (AND (FLE_H_INX $rs1, $rs2),
385                (FLE_H_INX $rs2, $rs1))>;
386 def : Pat<(XLenVT (strict_fsetccs FPR16INX:$rs1, FPR16INX:$rs2, SETOEQ)),
387           (AND (FLE_H_INX $rs1, $rs2),
388                (FLE_H_INX $rs2, $rs1))>;
389 // If both operands are the same, use a single FLE.
390 def : Pat<(XLenVT (strict_fsetccs FPR16INX:$rs1, FPR16INX:$rs1, SETEQ)),
391           (FLE_H_INX $rs1, $rs1)>;
392 def : Pat<(XLenVT (strict_fsetccs FPR16INX:$rs1, FPR16INX:$rs1, SETOEQ)),
393           (FLE_H_INX $rs1, $rs1)>;
394 } // Predicates = [HasStdExtZhinx]
396 foreach Ext = ZfhExts in {
397   defm : PatSetCC_m<any_fsetccs, SETLT,  FLT_H, Ext>;
398   defm : PatSetCC_m<any_fsetccs, SETOLT, FLT_H, Ext>;
399   defm : PatSetCC_m<any_fsetccs, SETLE,  FLE_H, Ext>;
400   defm : PatSetCC_m<any_fsetccs, SETOLE, FLE_H, Ext>;
403 let Predicates = [HasStdExtZfh] in {
404 defm Select_FPR16 : SelectCC_GPR_rrirr<FPR16, f16>;
406 def PseudoFROUND_H : PseudoFROUND<FPR16, f16>;
407 } // Predicates = [HasStdExtZfh]
409 let Predicates = [HasStdExtZhinx] in {
410 defm Select_FPR16INX : SelectCC_GPR_rrirr<FPR16INX, f16>;
412 def PseudoFROUND_H_INX : PseudoFROUND<FPR16INX, f16>;
413 } // Predicates = [HasStdExtZhinx]
415 let Predicates = [HasStdExtZfhOrZfhmin] in {
416 /// Loads
417 def : LdPat<load, FLH, f16>;
419 /// Stores
420 def : StPat<store, FSH, FPR16, f16>;
421 } // Predicates = [HasStdExtZfhOrZfhmin]
423 let Predicates = [HasStdExtZhinxOrZhinxmin] in {
424 /// Loads
425 def : Pat<(f16 (load (AddrRegImm (XLenVT GPR:$rs1), simm12:$imm12))),
426           (COPY_TO_REGCLASS (LH GPR:$rs1, simm12:$imm12), GPRF16)>;
428 /// Stores
429 def : Pat<(store (f16 FPR16INX:$rs2),
430                  (AddrRegImm (XLenVT GPR:$rs1), simm12:$imm12)),
431           (SH (COPY_TO_REGCLASS FPR16INX:$rs2, GPR), GPR:$rs1, simm12:$imm12)>;
432 } // Predicates = [HasStdExtZhinxOrZhinxmin]
434 let Predicates = [HasStdExtZfhOrZfhmin] in {
435 /// Float conversion operations
437 // f32 -> f16, f16 -> f32
438 def : Pat<(f16 (any_fpround FPR32:$rs1)), (FCVT_H_S FPR32:$rs1, FRM_DYN)>;
439 def : Pat<(any_fpextend (f16 FPR16:$rs1)), (FCVT_S_H FPR16:$rs1, FRM_RNE)>;
441 // Moves (no conversion)
442 def : Pat<(f16 (riscv_fmv_h_x GPR:$src)), (FMV_H_X GPR:$src)>;
443 def : Pat<(riscv_fmv_x_anyexth (f16 FPR16:$src)), (FMV_X_H FPR16:$src)>;
444 def : Pat<(riscv_fmv_x_signexth (f16 FPR16:$src)), (FMV_X_H FPR16:$src)>;
446 def : Pat<(fcopysign FPR32:$rs1, (f16 FPR16:$rs2)), (FSGNJ_S $rs1, (FCVT_S_H $rs2, FRM_RNE))>;
447 } // Predicates = [HasStdExtZfhOrZfhmin]
449 let Predicates = [HasStdExtZhinxOrZhinxmin] in {
450 /// Float conversion operations
452 // f32 -> f16, f16 -> f32
453 def : Pat<(any_fpround FPR32INX:$rs1), (FCVT_H_S_INX FPR32INX:$rs1, FRM_DYN)>;
454 def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_S_H_INX FPR16INX:$rs1, FRM_RNE)>;
456 // Moves (no conversion)
457 def : Pat<(f16 (riscv_fmv_h_x GPR:$src)), (COPY_TO_REGCLASS GPR:$src, GPR)>;
458 def : Pat<(riscv_fmv_x_anyexth FPR16INX:$src), (COPY_TO_REGCLASS FPR16INX:$src, GPR)>;
459 def : Pat<(riscv_fmv_x_signexth FPR16INX:$src), (COPY_TO_REGCLASS FPR16INX:$src, GPR)>;
461 def : Pat<(fcopysign FPR32INX:$rs1, FPR16INX:$rs2), (FSGNJ_S_INX $rs1, (FCVT_S_H_INX $rs2, FRM_RNE))>;
462 } // Predicates = [HasStdExtZhinxOrZhinxmin]
464 let Predicates = [HasStdExtZfh] in {
465 // half->[u]int. Round-to-zero must be used.
466 def : Pat<(i32 (any_fp_to_sint (f16 FPR16:$rs1))), (FCVT_W_H $rs1, 0b001)>;
467 def : Pat<(i32 (any_fp_to_uint (f16 FPR16:$rs1))), (FCVT_WU_H $rs1, 0b001)>;
469 // Saturating half->[u]int32.
470 def : Pat<(i32 (riscv_fcvt_x (f16 FPR16:$rs1), timm:$frm)), (FCVT_W_H $rs1, timm:$frm)>;
471 def : Pat<(i32 (riscv_fcvt_xu (f16 FPR16:$rs1), timm:$frm)), (FCVT_WU_H $rs1, timm:$frm)>;
473 // half->int32 with current rounding mode.
474 def : Pat<(i32 (any_lrint (f16 FPR16:$rs1))), (FCVT_W_H $rs1, FRM_DYN)>;
476 // half->int32 rounded to nearest with ties rounded away from zero.
477 def : Pat<(i32 (any_lround (f16 FPR16:$rs1))), (FCVT_W_H $rs1, FRM_RMM)>;
479 // [u]int->half. Match GCC and default to using dynamic rounding mode.
480 def : Pat<(f16 (any_sint_to_fp (i32 GPR:$rs1))), (FCVT_H_W $rs1, FRM_DYN)>;
481 def : Pat<(f16 (any_uint_to_fp (i32 GPR:$rs1))), (FCVT_H_WU $rs1, FRM_DYN)>;
482 } // Predicates = [HasStdExtZfh]
484 let Predicates = [HasStdExtZhinx] in {
485 // half->[u]int. Round-to-zero must be used.
486 def : Pat<(i32 (any_fp_to_sint FPR16INX:$rs1)), (FCVT_W_H_INX $rs1, 0b001)>;
487 def : Pat<(i32 (any_fp_to_uint FPR16INX:$rs1)), (FCVT_WU_H_INX $rs1, 0b001)>;
489 // Saturating float->[u]int32.
490 def : Pat<(i32 (riscv_fcvt_x FPR16INX:$rs1, timm:$frm)), (FCVT_W_H_INX $rs1, timm:$frm)>;
491 def : Pat<(i32 (riscv_fcvt_xu FPR16INX:$rs1, timm:$frm)), (FCVT_WU_H_INX $rs1, timm:$frm)>;
493 // half->int32 with current rounding mode.
494 def : Pat<(i32 (any_lrint FPR16INX:$rs1)), (FCVT_W_H_INX $rs1, FRM_DYN)>;
496 // half->int32 rounded to nearest with ties rounded away from zero.
497 def : Pat<(i32 (any_lround FPR16INX:$rs1)), (FCVT_W_H_INX $rs1, FRM_RMM)>;
499 // [u]int->half. Match GCC and default to using dynamic rounding mode.
500 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_H_W_INX $rs1, FRM_DYN)>;
501 def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_H_WU_INX $rs1, FRM_DYN)>;
502 } // Predicates = [HasStdExtZhinx]
504 let Predicates = [HasStdExtZfh, IsRV64] in {
505 // Use target specific isd nodes to help us remember the result is sign
506 // extended. Matching sext_inreg+fptoui/fptosi may cause the conversion to be
507 // duplicated if it has another user that didn't need the sign_extend.
508 def : Pat<(riscv_any_fcvt_w_rv64 (f16 FPR16:$rs1), timm:$frm),  (FCVT_W_H $rs1, timm:$frm)>;
509 def : Pat<(riscv_any_fcvt_wu_rv64 (f16 FPR16:$rs1), timm:$frm), (FCVT_WU_H $rs1, timm:$frm)>;
511 // half->[u]int64. Round-to-zero must be used.
512 def : Pat<(i64 (any_fp_to_sint (f16 FPR16:$rs1))), (FCVT_L_H $rs1, 0b001)>;
513 def : Pat<(i64 (any_fp_to_uint (f16 FPR16:$rs1))), (FCVT_LU_H $rs1, 0b001)>;
515 // Saturating half->[u]int64.
516 def : Pat<(i64 (riscv_fcvt_x (f16 FPR16:$rs1), timm:$frm)), (FCVT_L_H $rs1, timm:$frm)>;
517 def : Pat<(i64 (riscv_fcvt_xu (f16 FPR16:$rs1), timm:$frm)), (FCVT_LU_H $rs1, timm:$frm)>;
519 // half->int64 with current rounding mode.
520 def : Pat<(i64 (any_lrint (f16 FPR16:$rs1))), (FCVT_L_H $rs1, FRM_DYN)>;
521 def : Pat<(i64 (any_llrint (f16 FPR16:$rs1))), (FCVT_L_H $rs1, FRM_DYN)>;
523 // half->int64 rounded to nearest with ties rounded away from zero.
524 def : Pat<(i64 (any_lround (f16 FPR16:$rs1))), (FCVT_L_H $rs1, FRM_RMM)>;
525 def : Pat<(i64 (any_llround (f16 FPR16:$rs1))), (FCVT_L_H $rs1, FRM_RMM)>;
527 // [u]int->fp. Match GCC and default to using dynamic rounding mode.
528 def : Pat<(f16 (any_sint_to_fp (i64 (sexti32 (i64 GPR:$rs1))))), (FCVT_H_W $rs1, FRM_DYN)>;
529 def : Pat<(f16 (any_uint_to_fp (i64 (zexti32 (i64 GPR:$rs1))))), (FCVT_H_WU $rs1, FRM_DYN)>;
530 def : Pat<(f16 (any_sint_to_fp (i64 GPR:$rs1))), (FCVT_H_L $rs1, FRM_DYN)>;
531 def : Pat<(f16 (any_uint_to_fp (i64 GPR:$rs1))), (FCVT_H_LU $rs1, FRM_DYN)>;
532 } // Predicates = [HasStdExtZfh, IsRV64]
534 let Predicates = [HasStdExtZhinx, IsRV64] in {
535 // Use target specific isd nodes to help us remember the result is sign
536 // extended. Matching sext_inreg+fptoui/fptosi may cause the conversion to be
537 // duplicated if it has another user that didn't need the sign_extend.
538 def : Pat<(riscv_any_fcvt_w_rv64 FPR16INX:$rs1, timm:$frm),  (FCVT_W_H_INX $rs1, timm:$frm)>;
539 def : Pat<(riscv_any_fcvt_wu_rv64 FPR16INX:$rs1, timm:$frm), (FCVT_WU_H_INX $rs1, timm:$frm)>;
541 // half->[u]int64. Round-to-zero must be used.
542 def : Pat<(i64 (any_fp_to_sint FPR16INX:$rs1)), (FCVT_L_H_INX $rs1, 0b001)>;
543 def : Pat<(i64 (any_fp_to_uint FPR16INX:$rs1)), (FCVT_LU_H_INX $rs1, 0b001)>;
545 // Saturating float->[u]int64.
546 def : Pat<(i64 (riscv_fcvt_x FPR16INX:$rs1, timm:$frm)), (FCVT_L_H_INX $rs1, timm:$frm)>;
547 def : Pat<(i64 (riscv_fcvt_xu FPR16INX:$rs1, timm:$frm)), (FCVT_LU_H_INX $rs1, timm:$frm)>;
549 // half->int64 with current rounding mode.
550 def : Pat<(i64 (any_lrint FPR16INX:$rs1)), (FCVT_L_H_INX $rs1, FRM_DYN)>;
551 def : Pat<(i64 (any_llrint FPR16INX:$rs1)), (FCVT_L_H_INX $rs1, FRM_DYN)>;
553 // half->int64 rounded to nearest with ties rounded away from zero.
554 def : Pat<(i64 (any_lround FPR16INX:$rs1)), (FCVT_L_H_INX $rs1, FRM_RMM)>;
555 def : Pat<(i64 (any_llround FPR16INX:$rs1)), (FCVT_L_H_INX $rs1, FRM_RMM)>;
557 // [u]int->fp. Match GCC and default to using dynamic rounding mode.
558 def : Pat<(any_sint_to_fp (i64 (sexti32 (i64 GPR:$rs1)))), (FCVT_H_W_INX $rs1, FRM_DYN)>;
559 def : Pat<(any_uint_to_fp (i64 (zexti32 (i64 GPR:$rs1)))), (FCVT_H_WU_INX $rs1, FRM_DYN)>;
560 def : Pat<(any_sint_to_fp (i64 GPR:$rs1)), (FCVT_H_L_INX $rs1, FRM_DYN)>;
561 def : Pat<(any_uint_to_fp (i64 GPR:$rs1)), (FCVT_H_LU_INX $rs1, FRM_DYN)>;
562 } // Predicates = [HasStdExtZhinx, IsRV64]
564 let Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD] in {
565 /// Float conversion operations
566 // f64 -> f16, f16 -> f64
567 def : Pat<(f16 (any_fpround FPR64:$rs1)), (FCVT_H_D FPR64:$rs1, FRM_DYN)>;
568 def : Pat<(any_fpextend (f16 FPR16:$rs1)), (FCVT_D_H FPR16:$rs1, FRM_RNE)>;
570 /// Float arithmetic operations
571 def : Pat<(f16 (fcopysign FPR16:$rs1, FPR64:$rs2)),
572           (FSGNJ_H $rs1, (FCVT_H_D $rs2, FRM_DYN))>;
573 def : Pat<(fcopysign FPR64:$rs1, (f16 FPR16:$rs2)), (FSGNJ_D $rs1, (FCVT_D_H $rs2, FRM_RNE))>;
574 } // Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD]
576 let Predicates = [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV32] in {
577 /// Float conversion operations
578 // f64 -> f16, f16 -> f64
579 def : Pat<(any_fpround FPR64IN32X:$rs1), (FCVT_H_D_IN32X FPR64IN32X:$rs1, FRM_DYN)>;
580 def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_D_H_IN32X FPR16INX:$rs1, FRM_RNE)>;
582 /// Float arithmetic operations
583 def : Pat<(fcopysign FPR16INX:$rs1, FPR64IN32X:$rs2),
584           (FSGNJ_H_INX $rs1, (FCVT_H_D_IN32X $rs2, 0b111))>;
585 def : Pat<(fcopysign FPR64IN32X:$rs1, FPR16INX:$rs2), (FSGNJ_D_IN32X $rs1, (FCVT_D_H_IN32X $rs2, FRM_RNE))>;
586 } // Predicates = [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV32]
588 let Predicates = [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV64] in {
589 /// Float conversion operations
590 // f64 -> f16, f16 -> f64
591 def : Pat<(any_fpround FPR64INX:$rs1), (FCVT_H_D_INX FPR64INX:$rs1, FRM_DYN)>;
592 def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_D_H_INX FPR16INX:$rs1, FRM_RNE)>;
594 /// Float arithmetic operations
595 def : Pat<(fcopysign FPR16INX:$rs1, FPR64INX:$rs2),
596           (FSGNJ_H_INX $rs1, (FCVT_H_D_INX $rs2, 0b111))>;
597 def : Pat<(fcopysign FPR64INX:$rs1, FPR16INX:$rs2), (FSGNJ_D_INX $rs1, (FCVT_D_H_INX $rs2, FRM_RNE))>;
598 } // Predicates = [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV64]
600 let Predicates = [HasStdExtZfhmin, NoStdExtZfh] in {
601 // half->[u]int. Round-to-zero must be used.
602 def : Pat<(i32 (any_fp_to_sint (f16 FPR16:$rs1))), (FCVT_W_S (FCVT_S_H $rs1, FRM_RNE), FRM_RTZ)>;
603 def : Pat<(i32 (any_fp_to_uint (f16 FPR16:$rs1))), (FCVT_WU_S (FCVT_S_H $rs1, FRM_RNE), FRM_RTZ)>;
605 // half->int32 with current rounding mode.
606 def : Pat<(i32 (any_lrint (f16 FPR16:$rs1))), (FCVT_W_S (FCVT_S_H $rs1, FRM_RNE), FRM_DYN)>;
608 // half->int32 rounded to nearest with ties rounded away from zero.
609 def : Pat<(i32 (any_lround (f16 FPR16:$rs1))), (FCVT_W_S (FCVT_S_H $rs1, FRM_RNE), FRM_RMM)>;
611 // [u]int->half. Match GCC and default to using dynamic rounding mode.
612 def : Pat<(f16 (any_sint_to_fp (i32 GPR:$rs1))), (FCVT_H_S (FCVT_S_W $rs1, FRM_DYN), FRM_DYN)>;
613 def : Pat<(f16 (any_uint_to_fp (i32 GPR:$rs1))), (FCVT_H_S (FCVT_S_WU $rs1, FRM_DYN), FRM_DYN)>;
614 } // Predicates = [HasStdExtZfhmin, NoStdExtZfh]
616 let Predicates = [HasStdExtZhinxmin, NoStdExtZhinx] in {
617 // half->[u]int. Round-to-zero must be used.
618 def : Pat<(i32 (any_fp_to_sint FPR16INX:$rs1)), (FCVT_W_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RTZ)>;
619 def : Pat<(i32 (any_fp_to_uint FPR16INX:$rs1)), (FCVT_WU_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RTZ)>;
621 // half->int32 with current rounding mode.
622 def : Pat<(i32 (any_lrint FPR16INX:$rs1)), (FCVT_W_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_DYN)>;
624 // half->int32 rounded to nearest with ties rounded away from zero.
625 def : Pat<(i32 (any_lround FPR16INX:$rs1)), (FCVT_W_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RMM)>;
627 // [u]int->half. Match GCC and default to using dynamic rounding mode.
628 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_H_S_INX (FCVT_S_W_INX $rs1, FRM_DYN), FRM_DYN)>;
629 def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_H_S_INX (FCVT_S_WU_INX $rs1, FRM_DYN), FRM_DYN)>;
630 } // Predicates = [HasStdExtZhinxmin, NoStdExtZhinx]
632 let Predicates = [HasStdExtZfhmin, NoStdExtZfh, IsRV64] in {
633 // half->[u]int64. Round-to-zero must be used.
634 def : Pat<(i64 (any_fp_to_sint (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1, FRM_RNE), FRM_RTZ)>;
635 def : Pat<(i64 (any_fp_to_uint (f16 FPR16:$rs1))), (FCVT_LU_S (FCVT_S_H $rs1, FRM_RNE), FRM_RTZ)>;
637 // half->int64 with current rounding mode.
638 def : Pat<(i64 (any_lrint (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1, FRM_RNE), FRM_DYN)>;
639 def : Pat<(i64 (any_llrint (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1, FRM_RNE), FRM_DYN)>;
641 // half->int64 rounded to nearest with ties rounded away from zero.
642 def : Pat<(i64 (any_lround (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1, FRM_RNE), FRM_RMM)>;
643 def : Pat<(i64 (any_llround (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1, FRM_RNE), FRM_RMM)>;
645 // [u]int->fp. Match GCC and default to using dynamic rounding mode.
646 def : Pat<(f16 (any_sint_to_fp (i64 GPR:$rs1))), (FCVT_H_S (FCVT_S_L $rs1, FRM_DYN), FRM_DYN)>;
647 def : Pat<(f16 (any_uint_to_fp (i64 GPR:$rs1))), (FCVT_H_S (FCVT_S_LU $rs1, FRM_DYN), FRM_DYN)>;
648 } // Predicates = [HasStdExtZfhmin, NoStdExtZfh, IsRV64]
650 let Predicates = [HasStdExtZhinxmin, NoStdExtZhinx, IsRV64] in {
651 // half->[u]int64. Round-to-zero must be used.
652 def : Pat<(i64 (any_fp_to_sint FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RTZ)>;
653 def : Pat<(i64 (any_fp_to_uint FPR16INX:$rs1)), (FCVT_LU_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RTZ)>;
655 // half->int64 with current rounding mode.
656 def : Pat<(i64 (any_lrint FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_DYN)>;
657 def : Pat<(i64 (any_llrint FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_DYN)>;
659 // half->int64 rounded to nearest with ties rounded away from zero.
660 def : Pat<(i64 (any_lround FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RMM)>;
661 def : Pat<(i64 (any_llround FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RMM)>;
663 // [u]int->fp. Match GCC and default to using dynamic rounding mode.
664 def : Pat<(any_sint_to_fp (i64 GPR:$rs1)), (FCVT_H_S_INX (FCVT_S_L_INX $rs1, FRM_DYN), FRM_DYN)>;
665 def : Pat<(any_uint_to_fp (i64 GPR:$rs1)), (FCVT_H_S_INX (FCVT_S_LU_INX $rs1, FRM_DYN), FRM_DYN)>;
666 } // Predicates = [HasStdExtZhinxmin, NoStdExtZhinx, IsRV64]