1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+zfh -verify-machineinstrs \
3; RUN:   -target-abi ilp32f -disable-strictnode-mutation < %s \
4; RUN:   | FileCheck -check-prefix=RV32IZFH %s
5; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \
6; RUN:   -target-abi lp64f -disable-strictnode-mutation < %s \
7; RUN:   | FileCheck -check-prefix=RV64IZFH %s
8; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh -verify-machineinstrs \
9; RUN:   -target-abi ilp32d -disable-strictnode-mutation < %s \
10; RUN:   | FileCheck -check-prefix=RV32IDZFH %s
11; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh -verify-machineinstrs \
12; RUN:   -target-abi lp64d -disable-strictnode-mutation < %s \
13; RUN:   | FileCheck -check-prefix=RV64IDZFH %s
14
15; NOTE: The rounding mode metadata does not effect which instruction is
16; selected. Dynamic rounding mode is always used for operations that
17; support rounding mode.
18
19define i16 @fcvt_si_h(half %a) nounwind strictfp {
20; RV32IZFH-LABEL: fcvt_si_h:
21; RV32IZFH:       # %bb.0:
22; RV32IZFH-NEXT:    fcvt.w.h a0, fa0, rtz
23; RV32IZFH-NEXT:    ret
24;
25; RV64IZFH-LABEL: fcvt_si_h:
26; RV64IZFH:       # %bb.0:
27; RV64IZFH-NEXT:    fcvt.l.h a0, fa0, rtz
28; RV64IZFH-NEXT:    ret
29;
30; RV32IDZFH-LABEL: fcvt_si_h:
31; RV32IDZFH:       # %bb.0:
32; RV32IDZFH-NEXT:    fcvt.w.h a0, fa0, rtz
33; RV32IDZFH-NEXT:    ret
34;
35; RV64IDZFH-LABEL: fcvt_si_h:
36; RV64IDZFH:       # %bb.0:
37; RV64IDZFH-NEXT:    fcvt.l.h a0, fa0, rtz
38; RV64IDZFH-NEXT:    ret
39  %1 = call i16 @llvm.experimental.constrained.fptosi.i16.f16(half %a, metadata !"fpexcept.strict") strictfp
40  ret i16 %1
41}
42declare i16 @llvm.experimental.constrained.fptosi.i16.f16(half, metadata)
43
44define i16 @fcvt_ui_h(half %a) nounwind strictfp {
45; RV32IZFH-LABEL: fcvt_ui_h:
46; RV32IZFH:       # %bb.0:
47; RV32IZFH-NEXT:    fcvt.wu.h a0, fa0, rtz
48; RV32IZFH-NEXT:    ret
49;
50; RV64IZFH-LABEL: fcvt_ui_h:
51; RV64IZFH:       # %bb.0:
52; RV64IZFH-NEXT:    fcvt.lu.h a0, fa0, rtz
53; RV64IZFH-NEXT:    ret
54;
55; RV32IDZFH-LABEL: fcvt_ui_h:
56; RV32IDZFH:       # %bb.0:
57; RV32IDZFH-NEXT:    fcvt.wu.h a0, fa0, rtz
58; RV32IDZFH-NEXT:    ret
59;
60; RV64IDZFH-LABEL: fcvt_ui_h:
61; RV64IDZFH:       # %bb.0:
62; RV64IDZFH-NEXT:    fcvt.lu.h a0, fa0, rtz
63; RV64IDZFH-NEXT:    ret
64  %1 = call i16 @llvm.experimental.constrained.fptoui.i16.f16(half %a, metadata !"fpexcept.strict") strictfp
65  ret i16 %1
66}
67declare i16 @llvm.experimental.constrained.fptoui.i16.f16(half, metadata)
68
69define i32 @fcvt_w_h(half %a) nounwind strictfp {
70; RV32IZFH-LABEL: fcvt_w_h:
71; RV32IZFH:       # %bb.0:
72; RV32IZFH-NEXT:    fcvt.w.h a0, fa0, rtz
73; RV32IZFH-NEXT:    ret
74;
75; RV64IZFH-LABEL: fcvt_w_h:
76; RV64IZFH:       # %bb.0:
77; RV64IZFH-NEXT:    fcvt.w.h a0, fa0, rtz
78; RV64IZFH-NEXT:    ret
79;
80; RV32IDZFH-LABEL: fcvt_w_h:
81; RV32IDZFH:       # %bb.0:
82; RV32IDZFH-NEXT:    fcvt.w.h a0, fa0, rtz
83; RV32IDZFH-NEXT:    ret
84;
85; RV64IDZFH-LABEL: fcvt_w_h:
86; RV64IDZFH:       # %bb.0:
87; RV64IDZFH-NEXT:    fcvt.w.h a0, fa0, rtz
88; RV64IDZFH-NEXT:    ret
89  %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict") strictfp
90  ret i32 %1
91}
92declare i32 @llvm.experimental.constrained.fptosi.i32.f16(half, metadata)
93
94define i32 @fcvt_wu_h(half %a) nounwind strictfp {
95; RV32IZFH-LABEL: fcvt_wu_h:
96; RV32IZFH:       # %bb.0:
97; RV32IZFH-NEXT:    fcvt.wu.h a0, fa0, rtz
98; RV32IZFH-NEXT:    ret
99;
100; RV64IZFH-LABEL: fcvt_wu_h:
101; RV64IZFH:       # %bb.0:
102; RV64IZFH-NEXT:    fcvt.wu.h a0, fa0, rtz
103; RV64IZFH-NEXT:    ret
104;
105; RV32IDZFH-LABEL: fcvt_wu_h:
106; RV32IDZFH:       # %bb.0:
107; RV32IDZFH-NEXT:    fcvt.wu.h a0, fa0, rtz
108; RV32IDZFH-NEXT:    ret
109;
110; RV64IDZFH-LABEL: fcvt_wu_h:
111; RV64IDZFH:       # %bb.0:
112; RV64IDZFH-NEXT:    fcvt.wu.h a0, fa0, rtz
113; RV64IDZFH-NEXT:    ret
114  %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict") strictfp
115  ret i32 %1
116}
117declare i32 @llvm.experimental.constrained.fptoui.i32.f16(half, metadata)
118
119; Test where the fptoui has multiple uses, one of which causes a sext to be
120; inserted on RV64.
121; FIXME: We should not have an fcvt.wu.h and an fcvt.lu.h.
122define i32 @fcvt_wu_h_multiple_use(half %x, i32* %y) {
123; RV32IZFH-LABEL: fcvt_wu_h_multiple_use:
124; RV32IZFH:       # %bb.0:
125; RV32IZFH-NEXT:    fcvt.wu.h a1, fa0, rtz
126; RV32IZFH-NEXT:    li a0, 1
127; RV32IZFH-NEXT:    beqz a1, .LBB4_2
128; RV32IZFH-NEXT:  # %bb.1:
129; RV32IZFH-NEXT:    mv a0, a1
130; RV32IZFH-NEXT:  .LBB4_2:
131; RV32IZFH-NEXT:    ret
132;
133; RV64IZFH-LABEL: fcvt_wu_h_multiple_use:
134; RV64IZFH:       # %bb.0:
135; RV64IZFH-NEXT:    fcvt.wu.h a1, fa0, rtz
136; RV64IZFH-NEXT:    li a0, 1
137; RV64IZFH-NEXT:    beqz a1, .LBB4_2
138; RV64IZFH-NEXT:  # %bb.1:
139; RV64IZFH-NEXT:    mv a0, a1
140; RV64IZFH-NEXT:  .LBB4_2:
141; RV64IZFH-NEXT:    ret
142;
143; RV32IDZFH-LABEL: fcvt_wu_h_multiple_use:
144; RV32IDZFH:       # %bb.0:
145; RV32IDZFH-NEXT:    fcvt.wu.h a1, fa0, rtz
146; RV32IDZFH-NEXT:    li a0, 1
147; RV32IDZFH-NEXT:    beqz a1, .LBB4_2
148; RV32IDZFH-NEXT:  # %bb.1:
149; RV32IDZFH-NEXT:    mv a0, a1
150; RV32IDZFH-NEXT:  .LBB4_2:
151; RV32IDZFH-NEXT:    ret
152;
153; RV64IDZFH-LABEL: fcvt_wu_h_multiple_use:
154; RV64IDZFH:       # %bb.0:
155; RV64IDZFH-NEXT:    fcvt.wu.h a1, fa0, rtz
156; RV64IDZFH-NEXT:    li a0, 1
157; RV64IDZFH-NEXT:    beqz a1, .LBB4_2
158; RV64IDZFH-NEXT:  # %bb.1:
159; RV64IDZFH-NEXT:    mv a0, a1
160; RV64IDZFH-NEXT:  .LBB4_2:
161; RV64IDZFH-NEXT:    ret
162  %a = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %x, metadata !"fpexcept.strict") strictfp
163  %b = icmp eq i32 %a, 0
164  %c = select i1 %b, i32 1, i32 %a
165  ret i32 %c
166}
167
168define i64 @fcvt_l_h(half %a) nounwind strictfp {
169; RV32IZFH-LABEL: fcvt_l_h:
170; RV32IZFH:       # %bb.0:
171; RV32IZFH-NEXT:    addi sp, sp, -16
172; RV32IZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
173; RV32IZFH-NEXT:    call __fixhfdi@plt
174; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
175; RV32IZFH-NEXT:    addi sp, sp, 16
176; RV32IZFH-NEXT:    ret
177;
178; RV64IZFH-LABEL: fcvt_l_h:
179; RV64IZFH:       # %bb.0:
180; RV64IZFH-NEXT:    fcvt.l.h a0, fa0, rtz
181; RV64IZFH-NEXT:    ret
182;
183; RV32IDZFH-LABEL: fcvt_l_h:
184; RV32IDZFH:       # %bb.0:
185; RV32IDZFH-NEXT:    addi sp, sp, -16
186; RV32IDZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
187; RV32IDZFH-NEXT:    call __fixhfdi@plt
188; RV32IDZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
189; RV32IDZFH-NEXT:    addi sp, sp, 16
190; RV32IDZFH-NEXT:    ret
191;
192; RV64IDZFH-LABEL: fcvt_l_h:
193; RV64IDZFH:       # %bb.0:
194; RV64IDZFH-NEXT:    fcvt.l.h a0, fa0, rtz
195; RV64IDZFH-NEXT:    ret
196  %1 = call i64 @llvm.experimental.constrained.fptosi.i64.f16(half %a, metadata !"fpexcept.strict") strictfp
197  ret i64 %1
198}
199declare i64 @llvm.experimental.constrained.fptosi.i64.f16(half, metadata)
200
201define i64 @fcvt_lu_h(half %a) nounwind strictfp {
202; RV32IZFH-LABEL: fcvt_lu_h:
203; RV32IZFH:       # %bb.0:
204; RV32IZFH-NEXT:    addi sp, sp, -16
205; RV32IZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
206; RV32IZFH-NEXT:    call __fixunshfdi@plt
207; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
208; RV32IZFH-NEXT:    addi sp, sp, 16
209; RV32IZFH-NEXT:    ret
210;
211; RV64IZFH-LABEL: fcvt_lu_h:
212; RV64IZFH:       # %bb.0:
213; RV64IZFH-NEXT:    fcvt.lu.h a0, fa0, rtz
214; RV64IZFH-NEXT:    ret
215;
216; RV32IDZFH-LABEL: fcvt_lu_h:
217; RV32IDZFH:       # %bb.0:
218; RV32IDZFH-NEXT:    addi sp, sp, -16
219; RV32IDZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
220; RV32IDZFH-NEXT:    call __fixunshfdi@plt
221; RV32IDZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
222; RV32IDZFH-NEXT:    addi sp, sp, 16
223; RV32IDZFH-NEXT:    ret
224;
225; RV64IDZFH-LABEL: fcvt_lu_h:
226; RV64IDZFH:       # %bb.0:
227; RV64IDZFH-NEXT:    fcvt.lu.h a0, fa0, rtz
228; RV64IDZFH-NEXT:    ret
229  %1 = call i64 @llvm.experimental.constrained.fptoui.i64.f16(half %a, metadata !"fpexcept.strict") strictfp
230  ret i64 %1
231}
232declare i64 @llvm.experimental.constrained.fptoui.i64.f16(half, metadata)
233
234define half @fcvt_h_si(i16 %a) nounwind strictfp {
235; RV32IZFH-LABEL: fcvt_h_si:
236; RV32IZFH:       # %bb.0:
237; RV32IZFH-NEXT:    slli a0, a0, 16
238; RV32IZFH-NEXT:    srai a0, a0, 16
239; RV32IZFH-NEXT:    fcvt.h.w fa0, a0
240; RV32IZFH-NEXT:    ret
241;
242; RV64IZFH-LABEL: fcvt_h_si:
243; RV64IZFH:       # %bb.0:
244; RV64IZFH-NEXT:    slli a0, a0, 48
245; RV64IZFH-NEXT:    srai a0, a0, 48
246; RV64IZFH-NEXT:    fcvt.h.w fa0, a0
247; RV64IZFH-NEXT:    ret
248;
249; RV32IDZFH-LABEL: fcvt_h_si:
250; RV32IDZFH:       # %bb.0:
251; RV32IDZFH-NEXT:    slli a0, a0, 16
252; RV32IDZFH-NEXT:    srai a0, a0, 16
253; RV32IDZFH-NEXT:    fcvt.h.w fa0, a0
254; RV32IDZFH-NEXT:    ret
255;
256; RV64IDZFH-LABEL: fcvt_h_si:
257; RV64IDZFH:       # %bb.0:
258; RV64IDZFH-NEXT:    slli a0, a0, 48
259; RV64IDZFH-NEXT:    srai a0, a0, 48
260; RV64IDZFH-NEXT:    fcvt.h.w fa0, a0
261; RV64IDZFH-NEXT:    ret
262  %1 = call half @llvm.experimental.constrained.sitofp.f16.i16(i16 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
263  ret half %1
264}
265declare half @llvm.experimental.constrained.sitofp.f16.i16(i16, metadata, metadata)
266
267define half @fcvt_h_si_signext(i16 signext %a) nounwind strictfp {
268; RV32IZFH-LABEL: fcvt_h_si_signext:
269; RV32IZFH:       # %bb.0:
270; RV32IZFH-NEXT:    fcvt.h.w fa0, a0
271; RV32IZFH-NEXT:    ret
272;
273; RV64IZFH-LABEL: fcvt_h_si_signext:
274; RV64IZFH:       # %bb.0:
275; RV64IZFH-NEXT:    fcvt.h.w fa0, a0
276; RV64IZFH-NEXT:    ret
277;
278; RV32IDZFH-LABEL: fcvt_h_si_signext:
279; RV32IDZFH:       # %bb.0:
280; RV32IDZFH-NEXT:    fcvt.h.w fa0, a0
281; RV32IDZFH-NEXT:    ret
282;
283; RV64IDZFH-LABEL: fcvt_h_si_signext:
284; RV64IDZFH:       # %bb.0:
285; RV64IDZFH-NEXT:    fcvt.h.w fa0, a0
286; RV64IDZFH-NEXT:    ret
287  %1 = call half @llvm.experimental.constrained.sitofp.f16.i16(i16 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
288  ret half %1
289}
290
291define half @fcvt_h_ui(i16 %a) nounwind strictfp {
292; RV32IZFH-LABEL: fcvt_h_ui:
293; RV32IZFH:       # %bb.0:
294; RV32IZFH-NEXT:    slli a0, a0, 16
295; RV32IZFH-NEXT:    srli a0, a0, 16
296; RV32IZFH-NEXT:    fcvt.h.wu fa0, a0
297; RV32IZFH-NEXT:    ret
298;
299; RV64IZFH-LABEL: fcvt_h_ui:
300; RV64IZFH:       # %bb.0:
301; RV64IZFH-NEXT:    slli a0, a0, 48
302; RV64IZFH-NEXT:    srli a0, a0, 48
303; RV64IZFH-NEXT:    fcvt.h.wu fa0, a0
304; RV64IZFH-NEXT:    ret
305;
306; RV32IDZFH-LABEL: fcvt_h_ui:
307; RV32IDZFH:       # %bb.0:
308; RV32IDZFH-NEXT:    slli a0, a0, 16
309; RV32IDZFH-NEXT:    srli a0, a0, 16
310; RV32IDZFH-NEXT:    fcvt.h.wu fa0, a0
311; RV32IDZFH-NEXT:    ret
312;
313; RV64IDZFH-LABEL: fcvt_h_ui:
314; RV64IDZFH:       # %bb.0:
315; RV64IDZFH-NEXT:    slli a0, a0, 48
316; RV64IDZFH-NEXT:    srli a0, a0, 48
317; RV64IDZFH-NEXT:    fcvt.h.wu fa0, a0
318; RV64IDZFH-NEXT:    ret
319  %1 = call half @llvm.experimental.constrained.uitofp.f16.i16(i16 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
320  ret half %1
321}
322declare half @llvm.experimental.constrained.uitofp.f16.i16(i16, metadata, metadata)
323
324define half @fcvt_h_ui_zeroext(i16 zeroext %a) nounwind strictfp {
325; RV32IZFH-LABEL: fcvt_h_ui_zeroext:
326; RV32IZFH:       # %bb.0:
327; RV32IZFH-NEXT:    fcvt.h.wu fa0, a0
328; RV32IZFH-NEXT:    ret
329;
330; RV64IZFH-LABEL: fcvt_h_ui_zeroext:
331; RV64IZFH:       # %bb.0:
332; RV64IZFH-NEXT:    fcvt.h.wu fa0, a0
333; RV64IZFH-NEXT:    ret
334;
335; RV32IDZFH-LABEL: fcvt_h_ui_zeroext:
336; RV32IDZFH:       # %bb.0:
337; RV32IDZFH-NEXT:    fcvt.h.wu fa0, a0
338; RV32IDZFH-NEXT:    ret
339;
340; RV64IDZFH-LABEL: fcvt_h_ui_zeroext:
341; RV64IDZFH:       # %bb.0:
342; RV64IDZFH-NEXT:    fcvt.h.wu fa0, a0
343; RV64IDZFH-NEXT:    ret
344  %1 = call half @llvm.experimental.constrained.uitofp.f16.i16(i16 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
345  ret half %1
346}
347
348define half @fcvt_h_w(i32 %a) nounwind strictfp {
349; RV32IZFH-LABEL: fcvt_h_w:
350; RV32IZFH:       # %bb.0:
351; RV32IZFH-NEXT:    fcvt.h.w fa0, a0
352; RV32IZFH-NEXT:    ret
353;
354; RV64IZFH-LABEL: fcvt_h_w:
355; RV64IZFH:       # %bb.0:
356; RV64IZFH-NEXT:    fcvt.h.w fa0, a0
357; RV64IZFH-NEXT:    ret
358;
359; RV32IDZFH-LABEL: fcvt_h_w:
360; RV32IDZFH:       # %bb.0:
361; RV32IDZFH-NEXT:    fcvt.h.w fa0, a0
362; RV32IDZFH-NEXT:    ret
363;
364; RV64IDZFH-LABEL: fcvt_h_w:
365; RV64IDZFH:       # %bb.0:
366; RV64IDZFH-NEXT:    fcvt.h.w fa0, a0
367; RV64IDZFH-NEXT:    ret
368  %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
369  ret half %1
370}
371declare half @llvm.experimental.constrained.sitofp.f16.i32(i32, metadata, metadata)
372
373define half @fcvt_h_w_load(i32* %p) nounwind strictfp {
374; RV32IZFH-LABEL: fcvt_h_w_load:
375; RV32IZFH:       # %bb.0:
376; RV32IZFH-NEXT:    lw a0, 0(a0)
377; RV32IZFH-NEXT:    fcvt.h.w fa0, a0
378; RV32IZFH-NEXT:    ret
379;
380; RV64IZFH-LABEL: fcvt_h_w_load:
381; RV64IZFH:       # %bb.0:
382; RV64IZFH-NEXT:    lw a0, 0(a0)
383; RV64IZFH-NEXT:    fcvt.h.w fa0, a0
384; RV64IZFH-NEXT:    ret
385;
386; RV32IDZFH-LABEL: fcvt_h_w_load:
387; RV32IDZFH:       # %bb.0:
388; RV32IDZFH-NEXT:    lw a0, 0(a0)
389; RV32IDZFH-NEXT:    fcvt.h.w fa0, a0
390; RV32IDZFH-NEXT:    ret
391;
392; RV64IDZFH-LABEL: fcvt_h_w_load:
393; RV64IDZFH:       # %bb.0:
394; RV64IDZFH-NEXT:    lw a0, 0(a0)
395; RV64IDZFH-NEXT:    fcvt.h.w fa0, a0
396; RV64IDZFH-NEXT:    ret
397  %a = load i32, i32* %p
398  %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
399  ret half %1
400}
401
402define half @fcvt_h_wu(i32 %a) nounwind strictfp {
403; RV32IZFH-LABEL: fcvt_h_wu:
404; RV32IZFH:       # %bb.0:
405; RV32IZFH-NEXT:    fcvt.h.wu fa0, a0
406; RV32IZFH-NEXT:    ret
407;
408; RV64IZFH-LABEL: fcvt_h_wu:
409; RV64IZFH:       # %bb.0:
410; RV64IZFH-NEXT:    fcvt.h.wu fa0, a0
411; RV64IZFH-NEXT:    ret
412;
413; RV32IDZFH-LABEL: fcvt_h_wu:
414; RV32IDZFH:       # %bb.0:
415; RV32IDZFH-NEXT:    fcvt.h.wu fa0, a0
416; RV32IDZFH-NEXT:    ret
417;
418; RV64IDZFH-LABEL: fcvt_h_wu:
419; RV64IDZFH:       # %bb.0:
420; RV64IDZFH-NEXT:    fcvt.h.wu fa0, a0
421; RV64IDZFH-NEXT:    ret
422  %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
423  ret half %1
424}
425declare half @llvm.experimental.constrained.uitofp.f16.i32(i32, metadata, metadata)
426
427define half @fcvt_h_wu_load(i32* %p) nounwind strictfp {
428; RV32IZFH-LABEL: fcvt_h_wu_load:
429; RV32IZFH:       # %bb.0:
430; RV32IZFH-NEXT:    lw a0, 0(a0)
431; RV32IZFH-NEXT:    fcvt.h.wu fa0, a0
432; RV32IZFH-NEXT:    ret
433;
434; RV64IZFH-LABEL: fcvt_h_wu_load:
435; RV64IZFH:       # %bb.0:
436; RV64IZFH-NEXT:    lwu a0, 0(a0)
437; RV64IZFH-NEXT:    fcvt.h.wu fa0, a0
438; RV64IZFH-NEXT:    ret
439;
440; RV32IDZFH-LABEL: fcvt_h_wu_load:
441; RV32IDZFH:       # %bb.0:
442; RV32IDZFH-NEXT:    lw a0, 0(a0)
443; RV32IDZFH-NEXT:    fcvt.h.wu fa0, a0
444; RV32IDZFH-NEXT:    ret
445;
446; RV64IDZFH-LABEL: fcvt_h_wu_load:
447; RV64IDZFH:       # %bb.0:
448; RV64IDZFH-NEXT:    lwu a0, 0(a0)
449; RV64IDZFH-NEXT:    fcvt.h.wu fa0, a0
450; RV64IDZFH-NEXT:    ret
451  %a = load i32, i32* %p
452  %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
453  ret half %1
454}
455
456define half @fcvt_h_l(i64 %a) nounwind strictfp {
457; RV32IZFH-LABEL: fcvt_h_l:
458; RV32IZFH:       # %bb.0:
459; RV32IZFH-NEXT:    addi sp, sp, -16
460; RV32IZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
461; RV32IZFH-NEXT:    call __floatdihf@plt
462; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
463; RV32IZFH-NEXT:    addi sp, sp, 16
464; RV32IZFH-NEXT:    ret
465;
466; RV64IZFH-LABEL: fcvt_h_l:
467; RV64IZFH:       # %bb.0:
468; RV64IZFH-NEXT:    fcvt.h.l fa0, a0
469; RV64IZFH-NEXT:    ret
470;
471; RV32IDZFH-LABEL: fcvt_h_l:
472; RV32IDZFH:       # %bb.0:
473; RV32IDZFH-NEXT:    addi sp, sp, -16
474; RV32IDZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
475; RV32IDZFH-NEXT:    call __floatdihf@plt
476; RV32IDZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
477; RV32IDZFH-NEXT:    addi sp, sp, 16
478; RV32IDZFH-NEXT:    ret
479;
480; RV64IDZFH-LABEL: fcvt_h_l:
481; RV64IDZFH:       # %bb.0:
482; RV64IDZFH-NEXT:    fcvt.h.l fa0, a0
483; RV64IDZFH-NEXT:    ret
484  %1 = call half @llvm.experimental.constrained.sitofp.f16.i64(i64 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
485  ret half %1
486}
487declare half @llvm.experimental.constrained.sitofp.f16.i64(i64, metadata, metadata)
488
489define half @fcvt_h_lu(i64 %a) nounwind strictfp {
490; RV32IZFH-LABEL: fcvt_h_lu:
491; RV32IZFH:       # %bb.0:
492; RV32IZFH-NEXT:    addi sp, sp, -16
493; RV32IZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
494; RV32IZFH-NEXT:    call __floatundihf@plt
495; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
496; RV32IZFH-NEXT:    addi sp, sp, 16
497; RV32IZFH-NEXT:    ret
498;
499; RV64IZFH-LABEL: fcvt_h_lu:
500; RV64IZFH:       # %bb.0:
501; RV64IZFH-NEXT:    fcvt.h.lu fa0, a0
502; RV64IZFH-NEXT:    ret
503;
504; RV32IDZFH-LABEL: fcvt_h_lu:
505; RV32IDZFH:       # %bb.0:
506; RV32IDZFH-NEXT:    addi sp, sp, -16
507; RV32IDZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
508; RV32IDZFH-NEXT:    call __floatundihf@plt
509; RV32IDZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
510; RV32IDZFH-NEXT:    addi sp, sp, 16
511; RV32IDZFH-NEXT:    ret
512;
513; RV64IDZFH-LABEL: fcvt_h_lu:
514; RV64IDZFH:       # %bb.0:
515; RV64IDZFH-NEXT:    fcvt.h.lu fa0, a0
516; RV64IDZFH-NEXT:    ret
517  %1 = call half @llvm.experimental.constrained.uitofp.f16.i64(i64 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
518  ret half %1
519}
520declare half @llvm.experimental.constrained.uitofp.f16.i64(i64, metadata, metadata)
521
522define half @fcvt_h_s(float %a) nounwind strictfp {
523; RV32IZFH-LABEL: fcvt_h_s:
524; RV32IZFH:       # %bb.0:
525; RV32IZFH-NEXT:    fcvt.h.s fa0, fa0
526; RV32IZFH-NEXT:    ret
527;
528; RV64IZFH-LABEL: fcvt_h_s:
529; RV64IZFH:       # %bb.0:
530; RV64IZFH-NEXT:    fcvt.h.s fa0, fa0
531; RV64IZFH-NEXT:    ret
532;
533; RV32IDZFH-LABEL: fcvt_h_s:
534; RV32IDZFH:       # %bb.0:
535; RV32IDZFH-NEXT:    fcvt.h.s fa0, fa0
536; RV32IDZFH-NEXT:    ret
537;
538; RV64IDZFH-LABEL: fcvt_h_s:
539; RV64IDZFH:       # %bb.0:
540; RV64IDZFH-NEXT:    fcvt.h.s fa0, fa0
541; RV64IDZFH-NEXT:    ret
542  %1 = call half @llvm.experimental.constrained.fptrunc.f16.f32(float %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
543  ret half %1
544}
545declare half @llvm.experimental.constrained.fptrunc.f16.f32(float, metadata, metadata)
546
547define float @fcvt_s_h(half %a) nounwind strictfp {
548; RV32IZFH-LABEL: fcvt_s_h:
549; RV32IZFH:       # %bb.0:
550; RV32IZFH-NEXT:    fcvt.s.h fa0, fa0
551; RV32IZFH-NEXT:    ret
552;
553; RV64IZFH-LABEL: fcvt_s_h:
554; RV64IZFH:       # %bb.0:
555; RV64IZFH-NEXT:    fcvt.s.h fa0, fa0
556; RV64IZFH-NEXT:    ret
557;
558; RV32IDZFH-LABEL: fcvt_s_h:
559; RV32IDZFH:       # %bb.0:
560; RV32IDZFH-NEXT:    fcvt.s.h fa0, fa0
561; RV32IDZFH-NEXT:    ret
562;
563; RV64IDZFH-LABEL: fcvt_s_h:
564; RV64IDZFH:       # %bb.0:
565; RV64IDZFH-NEXT:    fcvt.s.h fa0, fa0
566; RV64IDZFH-NEXT:    ret
567  %1 = call float @llvm.experimental.constrained.fpext.f32.f16(half %a, metadata !"fpexcept.strict")
568  ret float %1
569}
570declare float @llvm.experimental.constrained.fpext.f32.f16(half, metadata)
571
572define half @fcvt_h_d(double %a) nounwind strictfp {
573; RV32IZFH-LABEL: fcvt_h_d:
574; RV32IZFH:       # %bb.0:
575; RV32IZFH-NEXT:    addi sp, sp, -16
576; RV32IZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
577; RV32IZFH-NEXT:    call __truncdfhf2@plt
578; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
579; RV32IZFH-NEXT:    addi sp, sp, 16
580; RV32IZFH-NEXT:    ret
581;
582; RV64IZFH-LABEL: fcvt_h_d:
583; RV64IZFH:       # %bb.0:
584; RV64IZFH-NEXT:    addi sp, sp, -16
585; RV64IZFH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
586; RV64IZFH-NEXT:    call __truncdfhf2@plt
587; RV64IZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
588; RV64IZFH-NEXT:    addi sp, sp, 16
589; RV64IZFH-NEXT:    ret
590;
591; RV32IDZFH-LABEL: fcvt_h_d:
592; RV32IDZFH:       # %bb.0:
593; RV32IDZFH-NEXT:    fcvt.h.d fa0, fa0
594; RV32IDZFH-NEXT:    ret
595;
596; RV64IDZFH-LABEL: fcvt_h_d:
597; RV64IDZFH:       # %bb.0:
598; RV64IDZFH-NEXT:    fcvt.h.d fa0, fa0
599; RV64IDZFH-NEXT:    ret
600  %1 = call half @llvm.experimental.constrained.fptrunc.f16.f64(double %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
601  ret half %1
602}
603declare half @llvm.experimental.constrained.fptrunc.f16.f64(double, metadata, metadata)
604
605define double @fcvt_d_h(half %a) nounwind strictfp {
606; RV32IZFH-LABEL: fcvt_d_h:
607; RV32IZFH:       # %bb.0:
608; RV32IZFH-NEXT:    addi sp, sp, -16
609; RV32IZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
610; RV32IZFH-NEXT:    fcvt.s.h fa0, fa0
611; RV32IZFH-NEXT:    call __extendsfdf2@plt
612; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
613; RV32IZFH-NEXT:    addi sp, sp, 16
614; RV32IZFH-NEXT:    ret
615;
616; RV64IZFH-LABEL: fcvt_d_h:
617; RV64IZFH:       # %bb.0:
618; RV64IZFH-NEXT:    addi sp, sp, -16
619; RV64IZFH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
620; RV64IZFH-NEXT:    fcvt.s.h fa0, fa0
621; RV64IZFH-NEXT:    call __extendsfdf2@plt
622; RV64IZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
623; RV64IZFH-NEXT:    addi sp, sp, 16
624; RV64IZFH-NEXT:    ret
625;
626; RV32IDZFH-LABEL: fcvt_d_h:
627; RV32IDZFH:       # %bb.0:
628; RV32IDZFH-NEXT:    fcvt.d.h fa0, fa0
629; RV32IDZFH-NEXT:    ret
630;
631; RV64IDZFH-LABEL: fcvt_d_h:
632; RV64IDZFH:       # %bb.0:
633; RV64IDZFH-NEXT:    fcvt.d.h fa0, fa0
634; RV64IDZFH-NEXT:    ret
635  %1 = call double @llvm.experimental.constrained.fpext.f64.f16(half %a, metadata !"fpexcept.strict")
636  ret double %1
637}
638declare double @llvm.experimental.constrained.fpext.f64.f16(half, metadata)
639
640; Make sure we select W version of addi on RV64.
641define signext i32 @fcvt_h_w_demanded_bits(i32 signext %0, half* %1) {
642; RV32IZFH-LABEL: fcvt_h_w_demanded_bits:
643; RV32IZFH:       # %bb.0:
644; RV32IZFH-NEXT:    addi a0, a0, 1
645; RV32IZFH-NEXT:    fcvt.h.w ft0, a0
646; RV32IZFH-NEXT:    fsh ft0, 0(a1)
647; RV32IZFH-NEXT:    ret
648;
649; RV64IZFH-LABEL: fcvt_h_w_demanded_bits:
650; RV64IZFH:       # %bb.0:
651; RV64IZFH-NEXT:    addiw a0, a0, 1
652; RV64IZFH-NEXT:    fcvt.h.w ft0, a0
653; RV64IZFH-NEXT:    fsh ft0, 0(a1)
654; RV64IZFH-NEXT:    ret
655;
656; RV32IDZFH-LABEL: fcvt_h_w_demanded_bits:
657; RV32IDZFH:       # %bb.0:
658; RV32IDZFH-NEXT:    addi a0, a0, 1
659; RV32IDZFH-NEXT:    fcvt.h.w ft0, a0
660; RV32IDZFH-NEXT:    fsh ft0, 0(a1)
661; RV32IDZFH-NEXT:    ret
662;
663; RV64IDZFH-LABEL: fcvt_h_w_demanded_bits:
664; RV64IDZFH:       # %bb.0:
665; RV64IDZFH-NEXT:    addiw a0, a0, 1
666; RV64IDZFH-NEXT:    fcvt.h.w ft0, a0
667; RV64IDZFH-NEXT:    fsh ft0, 0(a1)
668; RV64IDZFH-NEXT:    ret
669  %3 = add i32 %0, 1
670  %4 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %3, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
671  store half %4, half* %1, align 2
672  ret i32 %3
673}
674
675; Make sure we select W version of addi on RV64.
676define signext i32 @fcvt_h_wu_demanded_bits(i32 signext %0, half* %1) {
677; RV32IZFH-LABEL: fcvt_h_wu_demanded_bits:
678; RV32IZFH:       # %bb.0:
679; RV32IZFH-NEXT:    addi a0, a0, 1
680; RV32IZFH-NEXT:    fcvt.h.wu ft0, a0
681; RV32IZFH-NEXT:    fsh ft0, 0(a1)
682; RV32IZFH-NEXT:    ret
683;
684; RV64IZFH-LABEL: fcvt_h_wu_demanded_bits:
685; RV64IZFH:       # %bb.0:
686; RV64IZFH-NEXT:    addiw a0, a0, 1
687; RV64IZFH-NEXT:    fcvt.h.wu ft0, a0
688; RV64IZFH-NEXT:    fsh ft0, 0(a1)
689; RV64IZFH-NEXT:    ret
690;
691; RV32IDZFH-LABEL: fcvt_h_wu_demanded_bits:
692; RV32IDZFH:       # %bb.0:
693; RV32IDZFH-NEXT:    addi a0, a0, 1
694; RV32IDZFH-NEXT:    fcvt.h.wu ft0, a0
695; RV32IDZFH-NEXT:    fsh ft0, 0(a1)
696; RV32IDZFH-NEXT:    ret
697;
698; RV64IDZFH-LABEL: fcvt_h_wu_demanded_bits:
699; RV64IDZFH:       # %bb.0:
700; RV64IDZFH-NEXT:    addiw a0, a0, 1
701; RV64IDZFH-NEXT:    fcvt.h.wu ft0, a0
702; RV64IDZFH-NEXT:    fsh ft0, 0(a1)
703; RV64IDZFH-NEXT:    ret
704  %3 = add i32 %0, 1
705  %4 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %3, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
706  store half %4, half* %1, align 2
707  ret i32 %3
708}
709