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