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:   | FileCheck -check-prefix=RV32IF %s
4; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
5; RUN:   | FileCheck -check-prefix=RV64IF %s
6
7; For RV64F, fcvt.l.s is semantically equivalent to fcvt.w.s in this case
8; because fptosi will produce poison if the result doesn't fit into an i32.
9define i32 @fcvt_w_s(float %a) nounwind {
10; RV32IF-LABEL: fcvt_w_s:
11; RV32IF:       # %bb.0:
12; RV32IF-NEXT:    fmv.w.x ft0, a0
13; RV32IF-NEXT:    fcvt.w.s a0, ft0, rtz
14; RV32IF-NEXT:    ret
15;
16; RV64IF-LABEL: fcvt_w_s:
17; RV64IF:       # %bb.0:
18; RV64IF-NEXT:    fmv.w.x ft0, a0
19; RV64IF-NEXT:    fcvt.w.s a0, ft0, rtz
20; RV64IF-NEXT:    ret
21  %1 = fptosi float %a to i32
22  ret i32 %1
23}
24
25define i32 @fcvt_w_s_sat(float %a) nounwind {
26; RV32IF-LABEL: fcvt_w_s_sat:
27; RV32IF:       # %bb.0: # %start
28; RV32IF-NEXT:    fmv.w.x ft0, a0
29; RV32IF-NEXT:    feq.s a0, ft0, ft0
30; RV32IF-NEXT:    bnez a0, .LBB1_2
31; RV32IF-NEXT:  # %bb.1: # %start
32; RV32IF-NEXT:    mv a0, zero
33; RV32IF-NEXT:    ret
34; RV32IF-NEXT:  .LBB1_2:
35; RV32IF-NEXT:    fcvt.w.s a0, ft0, rtz
36; RV32IF-NEXT:    ret
37;
38; RV64IF-LABEL: fcvt_w_s_sat:
39; RV64IF:       # %bb.0: # %start
40; RV64IF-NEXT:    fmv.w.x ft0, a0
41; RV64IF-NEXT:    feq.s a0, ft0, ft0
42; RV64IF-NEXT:    bnez a0, .LBB1_2
43; RV64IF-NEXT:  # %bb.1: # %start
44; RV64IF-NEXT:    mv a0, zero
45; RV64IF-NEXT:    ret
46; RV64IF-NEXT:  .LBB1_2:
47; RV64IF-NEXT:    fcvt.w.s a0, ft0, rtz
48; RV64IF-NEXT:    ret
49start:
50  %0 = tail call i32 @llvm.fptosi.sat.i32.f32(float %a)
51  ret i32 %0
52}
53declare i32 @llvm.fptosi.sat.i32.f32(float)
54
55; For RV64F, fcvt.lu.s is semantically equivalent to fcvt.wu.s in this case
56; because fptoui will produce poison if the result doesn't fit into an i32.
57define i32 @fcvt_wu_s(float %a) nounwind {
58; RV32IF-LABEL: fcvt_wu_s:
59; RV32IF:       # %bb.0:
60; RV32IF-NEXT:    fmv.w.x ft0, a0
61; RV32IF-NEXT:    fcvt.wu.s a0, ft0, rtz
62; RV32IF-NEXT:    ret
63;
64; RV64IF-LABEL: fcvt_wu_s:
65; RV64IF:       # %bb.0:
66; RV64IF-NEXT:    fmv.w.x ft0, a0
67; RV64IF-NEXT:    fcvt.wu.s a0, ft0, rtz
68; RV64IF-NEXT:    ret
69  %1 = fptoui float %a to i32
70  ret i32 %1
71}
72
73; Test where the fptoui has multiple uses, one of which causes a sext to be
74; inserted on RV64.
75define i32 @fcvt_wu_s_multiple_use(float %x, i32* %y) {
76; RV32IF-LABEL: fcvt_wu_s_multiple_use:
77; RV32IF:       # %bb.0:
78; RV32IF-NEXT:    fmv.w.x ft0, a0
79; RV32IF-NEXT:    fcvt.wu.s a1, ft0, rtz
80; RV32IF-NEXT:    addi a0, zero, 1
81; RV32IF-NEXT:    beqz a1, .LBB3_2
82; RV32IF-NEXT:  # %bb.1:
83; RV32IF-NEXT:    mv a0, a1
84; RV32IF-NEXT:  .LBB3_2:
85; RV32IF-NEXT:    ret
86;
87; RV64IF-LABEL: fcvt_wu_s_multiple_use:
88; RV64IF:       # %bb.0:
89; RV64IF-NEXT:    fmv.w.x ft0, a0
90; RV64IF-NEXT:    fcvt.wu.s a1, ft0, rtz
91; RV64IF-NEXT:    addi a0, zero, 1
92; RV64IF-NEXT:    beqz a1, .LBB3_2
93; RV64IF-NEXT:  # %bb.1:
94; RV64IF-NEXT:    mv a0, a1
95; RV64IF-NEXT:  .LBB3_2:
96; RV64IF-NEXT:    ret
97  %a = fptoui float %x to i32
98  %b = icmp eq i32 %a, 0
99  %c = select i1 %b, i32 1, i32 %a
100  ret i32 %c
101}
102
103define i32 @fcvt_wu_s_sat(float %a) nounwind {
104; RV32IF-LABEL: fcvt_wu_s_sat:
105; RV32IF:       # %bb.0: # %start
106; RV32IF-NEXT:    fmv.w.x ft0, a0
107; RV32IF-NEXT:    feq.s a0, ft0, ft0
108; RV32IF-NEXT:    bnez a0, .LBB4_2
109; RV32IF-NEXT:  # %bb.1: # %start
110; RV32IF-NEXT:    mv a0, zero
111; RV32IF-NEXT:    ret
112; RV32IF-NEXT:  .LBB4_2:
113; RV32IF-NEXT:    fcvt.wu.s a0, ft0, rtz
114; RV32IF-NEXT:    ret
115;
116; RV64IF-LABEL: fcvt_wu_s_sat:
117; RV64IF:       # %bb.0: # %start
118; RV64IF-NEXT:    fmv.w.x ft0, a0
119; RV64IF-NEXT:    feq.s a0, ft0, ft0
120; RV64IF-NEXT:    bnez a0, .LBB4_2
121; RV64IF-NEXT:  # %bb.1: # %start
122; RV64IF-NEXT:    mv a0, zero
123; RV64IF-NEXT:    ret
124; RV64IF-NEXT:  .LBB4_2:
125; RV64IF-NEXT:    fcvt.wu.s a0, ft0, rtz
126; RV64IF-NEXT:    ret
127start:
128  %0 = tail call i32 @llvm.fptoui.sat.i32.f32(float %a)
129  ret i32 %0
130}
131declare i32 @llvm.fptoui.sat.i32.f32(float)
132
133define i32 @fmv_x_w(float %a, float %b) nounwind {
134; RV32IF-LABEL: fmv_x_w:
135; RV32IF:       # %bb.0:
136; RV32IF-NEXT:    fmv.w.x ft0, a1
137; RV32IF-NEXT:    fmv.w.x ft1, a0
138; RV32IF-NEXT:    fadd.s ft0, ft1, ft0
139; RV32IF-NEXT:    fmv.x.w a0, ft0
140; RV32IF-NEXT:    ret
141;
142; RV64IF-LABEL: fmv_x_w:
143; RV64IF:       # %bb.0:
144; RV64IF-NEXT:    fmv.w.x ft0, a1
145; RV64IF-NEXT:    fmv.w.x ft1, a0
146; RV64IF-NEXT:    fadd.s ft0, ft1, ft0
147; RV64IF-NEXT:    fmv.x.w a0, ft0
148; RV64IF-NEXT:    ret
149; Ensure fmv.x.w is generated even for a soft float calling convention
150  %1 = fadd float %a, %b
151  %2 = bitcast float %1 to i32
152  ret i32 %2
153}
154
155define float @fcvt_s_w(i32 %a) nounwind {
156; RV32IF-LABEL: fcvt_s_w:
157; RV32IF:       # %bb.0:
158; RV32IF-NEXT:    fcvt.s.w ft0, a0
159; RV32IF-NEXT:    fmv.x.w a0, ft0
160; RV32IF-NEXT:    ret
161;
162; RV64IF-LABEL: fcvt_s_w:
163; RV64IF:       # %bb.0:
164; RV64IF-NEXT:    fcvt.s.w ft0, a0
165; RV64IF-NEXT:    fmv.x.w a0, ft0
166; RV64IF-NEXT:    ret
167  %1 = sitofp i32 %a to float
168  ret float %1
169}
170
171define float @fcvt_s_w_load(i32* %p) nounwind {
172; RV32IF-LABEL: fcvt_s_w_load:
173; RV32IF:       # %bb.0:
174; RV32IF-NEXT:    lw a0, 0(a0)
175; RV32IF-NEXT:    fcvt.s.w ft0, a0
176; RV32IF-NEXT:    fmv.x.w a0, ft0
177; RV32IF-NEXT:    ret
178;
179; RV64IF-LABEL: fcvt_s_w_load:
180; RV64IF:       # %bb.0:
181; RV64IF-NEXT:    lw a0, 0(a0)
182; RV64IF-NEXT:    fcvt.s.w ft0, a0
183; RV64IF-NEXT:    fmv.x.w a0, ft0
184; RV64IF-NEXT:    ret
185  %a = load i32, i32* %p
186  %1 = sitofp i32 %a to float
187  ret float %1
188}
189
190define float @fcvt_s_wu(i32 %a) nounwind {
191; RV32IF-LABEL: fcvt_s_wu:
192; RV32IF:       # %bb.0:
193; RV32IF-NEXT:    fcvt.s.wu ft0, a0
194; RV32IF-NEXT:    fmv.x.w a0, ft0
195; RV32IF-NEXT:    ret
196;
197; RV64IF-LABEL: fcvt_s_wu:
198; RV64IF:       # %bb.0:
199; RV64IF-NEXT:    fcvt.s.wu ft0, a0
200; RV64IF-NEXT:    fmv.x.w a0, ft0
201; RV64IF-NEXT:    ret
202  %1 = uitofp i32 %a to float
203  ret float %1
204}
205
206define float @fcvt_s_wu_load(i32* %p) nounwind {
207; RV32IF-LABEL: fcvt_s_wu_load:
208; RV32IF:       # %bb.0:
209; RV32IF-NEXT:    lw a0, 0(a0)
210; RV32IF-NEXT:    fcvt.s.wu ft0, a0
211; RV32IF-NEXT:    fmv.x.w a0, ft0
212; RV32IF-NEXT:    ret
213;
214; RV64IF-LABEL: fcvt_s_wu_load:
215; RV64IF:       # %bb.0:
216; RV64IF-NEXT:    lwu a0, 0(a0)
217; RV64IF-NEXT:    fcvt.s.wu ft0, a0
218; RV64IF-NEXT:    fmv.x.w a0, ft0
219; RV64IF-NEXT:    ret
220  %a = load i32, i32* %p
221  %1 = uitofp i32 %a to float
222  ret float %1
223}
224
225define float @fmv_w_x(i32 %a, i32 %b) nounwind {
226; RV32IF-LABEL: fmv_w_x:
227; RV32IF:       # %bb.0:
228; RV32IF-NEXT:    fmv.w.x ft0, a0
229; RV32IF-NEXT:    fmv.w.x ft1, a1
230; RV32IF-NEXT:    fadd.s ft0, ft0, ft1
231; RV32IF-NEXT:    fmv.x.w a0, ft0
232; RV32IF-NEXT:    ret
233;
234; RV64IF-LABEL: fmv_w_x:
235; RV64IF:       # %bb.0:
236; RV64IF-NEXT:    fmv.w.x ft0, a0
237; RV64IF-NEXT:    fmv.w.x ft1, a1
238; RV64IF-NEXT:    fadd.s ft0, ft0, ft1
239; RV64IF-NEXT:    fmv.x.w a0, ft0
240; RV64IF-NEXT:    ret
241; Ensure fmv.w.x is generated even for a soft float calling convention
242  %1 = bitcast i32 %a to float
243  %2 = bitcast i32 %b to float
244  %3 = fadd float %1, %2
245  ret float %3
246}
247
248define i64 @fcvt_l_s(float %a) nounwind {
249; RV32IF-LABEL: fcvt_l_s:
250; RV32IF:       # %bb.0:
251; RV32IF-NEXT:    addi sp, sp, -16
252; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
253; RV32IF-NEXT:    call __fixsfdi@plt
254; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
255; RV32IF-NEXT:    addi sp, sp, 16
256; RV32IF-NEXT:    ret
257;
258; RV64IF-LABEL: fcvt_l_s:
259; RV64IF:       # %bb.0:
260; RV64IF-NEXT:    fmv.w.x ft0, a0
261; RV64IF-NEXT:    fcvt.l.s a0, ft0, rtz
262; RV64IF-NEXT:    ret
263  %1 = fptosi float %a to i64
264  ret i64 %1
265}
266
267define i64 @fcvt_l_s_sat(float %a) nounwind {
268; RV32IF-LABEL: fcvt_l_s_sat:
269; RV32IF:       # %bb.0: # %start
270; RV32IF-NEXT:    addi sp, sp, -16
271; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
272; RV32IF-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
273; RV32IF-NEXT:    lui a1, %hi(.LCPI12_0)
274; RV32IF-NEXT:    flw ft0, %lo(.LCPI12_0)(a1)
275; RV32IF-NEXT:    fmv.w.x ft1, a0
276; RV32IF-NEXT:    fsw ft1, 4(sp) # 4-byte Folded Spill
277; RV32IF-NEXT:    fle.s s0, ft0, ft1
278; RV32IF-NEXT:    call __fixsfdi@plt
279; RV32IF-NEXT:    mv a2, a0
280; RV32IF-NEXT:    bnez s0, .LBB12_2
281; RV32IF-NEXT:  # %bb.1: # %start
282; RV32IF-NEXT:    mv a2, zero
283; RV32IF-NEXT:  .LBB12_2: # %start
284; RV32IF-NEXT:    lui a0, %hi(.LCPI12_1)
285; RV32IF-NEXT:    flw ft0, %lo(.LCPI12_1)(a0)
286; RV32IF-NEXT:    flw ft1, 4(sp) # 4-byte Folded Reload
287; RV32IF-NEXT:    flt.s a3, ft0, ft1
288; RV32IF-NEXT:    fmv.s ft0, ft1
289; RV32IF-NEXT:    addi a0, zero, -1
290; RV32IF-NEXT:    beqz a3, .LBB12_9
291; RV32IF-NEXT:  # %bb.3: # %start
292; RV32IF-NEXT:    feq.s a2, ft0, ft0
293; RV32IF-NEXT:    beqz a2, .LBB12_10
294; RV32IF-NEXT:  .LBB12_4: # %start
295; RV32IF-NEXT:    lui a4, 524288
296; RV32IF-NEXT:    beqz s0, .LBB12_11
297; RV32IF-NEXT:  .LBB12_5: # %start
298; RV32IF-NEXT:    bnez a3, .LBB12_12
299; RV32IF-NEXT:  .LBB12_6: # %start
300; RV32IF-NEXT:    bnez a2, .LBB12_8
301; RV32IF-NEXT:  .LBB12_7: # %start
302; RV32IF-NEXT:    mv a1, zero
303; RV32IF-NEXT:  .LBB12_8: # %start
304; RV32IF-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
305; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
306; RV32IF-NEXT:    addi sp, sp, 16
307; RV32IF-NEXT:    ret
308; RV32IF-NEXT:  .LBB12_9: # %start
309; RV32IF-NEXT:    mv a0, a2
310; RV32IF-NEXT:    feq.s a2, ft0, ft0
311; RV32IF-NEXT:    bnez a2, .LBB12_4
312; RV32IF-NEXT:  .LBB12_10: # %start
313; RV32IF-NEXT:    mv a0, zero
314; RV32IF-NEXT:    lui a4, 524288
315; RV32IF-NEXT:    bnez s0, .LBB12_5
316; RV32IF-NEXT:  .LBB12_11: # %start
317; RV32IF-NEXT:    lui a1, 524288
318; RV32IF-NEXT:    beqz a3, .LBB12_6
319; RV32IF-NEXT:  .LBB12_12:
320; RV32IF-NEXT:    addi a1, a4, -1
321; RV32IF-NEXT:    beqz a2, .LBB12_7
322; RV32IF-NEXT:    j .LBB12_8
323;
324; RV64IF-LABEL: fcvt_l_s_sat:
325; RV64IF:       # %bb.0: # %start
326; RV64IF-NEXT:    fmv.w.x ft0, a0
327; RV64IF-NEXT:    feq.s a0, ft0, ft0
328; RV64IF-NEXT:    bnez a0, .LBB12_2
329; RV64IF-NEXT:  # %bb.1: # %start
330; RV64IF-NEXT:    mv a0, zero
331; RV64IF-NEXT:    ret
332; RV64IF-NEXT:  .LBB12_2:
333; RV64IF-NEXT:    fcvt.l.s a0, ft0, rtz
334; RV64IF-NEXT:    ret
335start:
336  %0 = tail call i64 @llvm.fptosi.sat.i64.f32(float %a)
337  ret i64 %0
338}
339declare i64 @llvm.fptosi.sat.i64.f32(float)
340
341define i64 @fcvt_lu_s(float %a) nounwind {
342; RV32IF-LABEL: fcvt_lu_s:
343; RV32IF:       # %bb.0:
344; RV32IF-NEXT:    addi sp, sp, -16
345; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
346; RV32IF-NEXT:    call __fixunssfdi@plt
347; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
348; RV32IF-NEXT:    addi sp, sp, 16
349; RV32IF-NEXT:    ret
350;
351; RV64IF-LABEL: fcvt_lu_s:
352; RV64IF:       # %bb.0:
353; RV64IF-NEXT:    fmv.w.x ft0, a0
354; RV64IF-NEXT:    fcvt.lu.s a0, ft0, rtz
355; RV64IF-NEXT:    ret
356  %1 = fptoui float %a to i64
357  ret i64 %1
358}
359
360define i64 @fcvt_lu_s_sat(float %a) nounwind {
361; RV32IF-LABEL: fcvt_lu_s_sat:
362; RV32IF:       # %bb.0: # %start
363; RV32IF-NEXT:    addi sp, sp, -16
364; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
365; RV32IF-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
366; RV32IF-NEXT:    fmv.w.x ft1, a0
367; RV32IF-NEXT:    fmv.w.x ft0, zero
368; RV32IF-NEXT:    fsw ft1, 4(sp) # 4-byte Folded Spill
369; RV32IF-NEXT:    fle.s s0, ft0, ft1
370; RV32IF-NEXT:    call __fixunssfdi@plt
371; RV32IF-NEXT:    mv a3, a0
372; RV32IF-NEXT:    bnez s0, .LBB14_2
373; RV32IF-NEXT:  # %bb.1: # %start
374; RV32IF-NEXT:    mv a3, zero
375; RV32IF-NEXT:  .LBB14_2: # %start
376; RV32IF-NEXT:    lui a0, %hi(.LCPI14_0)
377; RV32IF-NEXT:    flw ft0, %lo(.LCPI14_0)(a0)
378; RV32IF-NEXT:    flw ft1, 4(sp) # 4-byte Folded Reload
379; RV32IF-NEXT:    flt.s a4, ft0, ft1
380; RV32IF-NEXT:    addi a2, zero, -1
381; RV32IF-NEXT:    addi a0, zero, -1
382; RV32IF-NEXT:    beqz a4, .LBB14_7
383; RV32IF-NEXT:  # %bb.3: # %start
384; RV32IF-NEXT:    beqz s0, .LBB14_8
385; RV32IF-NEXT:  .LBB14_4: # %start
386; RV32IF-NEXT:    bnez a4, .LBB14_6
387; RV32IF-NEXT:  .LBB14_5: # %start
388; RV32IF-NEXT:    mv a2, a1
389; RV32IF-NEXT:  .LBB14_6: # %start
390; RV32IF-NEXT:    mv a1, a2
391; RV32IF-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
392; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
393; RV32IF-NEXT:    addi sp, sp, 16
394; RV32IF-NEXT:    ret
395; RV32IF-NEXT:  .LBB14_7: # %start
396; RV32IF-NEXT:    mv a0, a3
397; RV32IF-NEXT:    bnez s0, .LBB14_4
398; RV32IF-NEXT:  .LBB14_8: # %start
399; RV32IF-NEXT:    mv a1, zero
400; RV32IF-NEXT:    beqz a4, .LBB14_5
401; RV32IF-NEXT:    j .LBB14_6
402;
403; RV64IF-LABEL: fcvt_lu_s_sat:
404; RV64IF:       # %bb.0: # %start
405; RV64IF-NEXT:    fmv.w.x ft0, a0
406; RV64IF-NEXT:    feq.s a0, ft0, ft0
407; RV64IF-NEXT:    bnez a0, .LBB14_2
408; RV64IF-NEXT:  # %bb.1: # %start
409; RV64IF-NEXT:    mv a0, zero
410; RV64IF-NEXT:    ret
411; RV64IF-NEXT:  .LBB14_2:
412; RV64IF-NEXT:    fcvt.lu.s a0, ft0, rtz
413; RV64IF-NEXT:    ret
414start:
415  %0 = tail call i64 @llvm.fptoui.sat.i64.f32(float %a)
416  ret i64 %0
417}
418declare i64 @llvm.fptoui.sat.i64.f32(float)
419
420define float @fcvt_s_l(i64 %a) nounwind {
421; RV32IF-LABEL: fcvt_s_l:
422; RV32IF:       # %bb.0:
423; RV32IF-NEXT:    addi sp, sp, -16
424; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
425; RV32IF-NEXT:    call __floatdisf@plt
426; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
427; RV32IF-NEXT:    addi sp, sp, 16
428; RV32IF-NEXT:    ret
429;
430; RV64IF-LABEL: fcvt_s_l:
431; RV64IF:       # %bb.0:
432; RV64IF-NEXT:    fcvt.s.l ft0, a0
433; RV64IF-NEXT:    fmv.x.w a0, ft0
434; RV64IF-NEXT:    ret
435  %1 = sitofp i64 %a to float
436  ret float %1
437}
438
439define float @fcvt_s_lu(i64 %a) nounwind {
440; RV32IF-LABEL: fcvt_s_lu:
441; RV32IF:       # %bb.0:
442; RV32IF-NEXT:    addi sp, sp, -16
443; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
444; RV32IF-NEXT:    call __floatundisf@plt
445; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
446; RV32IF-NEXT:    addi sp, sp, 16
447; RV32IF-NEXT:    ret
448;
449; RV64IF-LABEL: fcvt_s_lu:
450; RV64IF:       # %bb.0:
451; RV64IF-NEXT:    fcvt.s.lu ft0, a0
452; RV64IF-NEXT:    fmv.x.w a0, ft0
453; RV64IF-NEXT:    ret
454  %1 = uitofp i64 %a to float
455  ret float %1
456}
457
458define float @fcvt_s_w_i8(i8 signext %a) nounwind {
459; RV32IF-LABEL: fcvt_s_w_i8:
460; RV32IF:       # %bb.0:
461; RV32IF-NEXT:    fcvt.s.w ft0, a0
462; RV32IF-NEXT:    fmv.x.w a0, ft0
463; RV32IF-NEXT:    ret
464;
465; RV64IF-LABEL: fcvt_s_w_i8:
466; RV64IF:       # %bb.0:
467; RV64IF-NEXT:    fcvt.s.w ft0, a0
468; RV64IF-NEXT:    fmv.x.w a0, ft0
469; RV64IF-NEXT:    ret
470  %1 = sitofp i8 %a to float
471  ret float %1
472}
473
474define float @fcvt_s_wu_i8(i8 zeroext %a) nounwind {
475; RV32IF-LABEL: fcvt_s_wu_i8:
476; RV32IF:       # %bb.0:
477; RV32IF-NEXT:    fcvt.s.wu ft0, a0
478; RV32IF-NEXT:    fmv.x.w a0, ft0
479; RV32IF-NEXT:    ret
480;
481; RV64IF-LABEL: fcvt_s_wu_i8:
482; RV64IF:       # %bb.0:
483; RV64IF-NEXT:    fcvt.s.wu ft0, a0
484; RV64IF-NEXT:    fmv.x.w a0, ft0
485; RV64IF-NEXT:    ret
486  %1 = uitofp i8 %a to float
487  ret float %1
488}
489
490define float @fcvt_s_w_i16(i16 signext %a) nounwind {
491; RV32IF-LABEL: fcvt_s_w_i16:
492; RV32IF:       # %bb.0:
493; RV32IF-NEXT:    fcvt.s.w ft0, a0
494; RV32IF-NEXT:    fmv.x.w a0, ft0
495; RV32IF-NEXT:    ret
496;
497; RV64IF-LABEL: fcvt_s_w_i16:
498; RV64IF:       # %bb.0:
499; RV64IF-NEXT:    fcvt.s.w ft0, a0
500; RV64IF-NEXT:    fmv.x.w a0, ft0
501; RV64IF-NEXT:    ret
502  %1 = sitofp i16 %a to float
503  ret float %1
504}
505
506define float @fcvt_s_wu_i16(i16 zeroext %a) nounwind {
507; RV32IF-LABEL: fcvt_s_wu_i16:
508; RV32IF:       # %bb.0:
509; RV32IF-NEXT:    fcvt.s.wu ft0, a0
510; RV32IF-NEXT:    fmv.x.w a0, ft0
511; RV32IF-NEXT:    ret
512;
513; RV64IF-LABEL: fcvt_s_wu_i16:
514; RV64IF:       # %bb.0:
515; RV64IF-NEXT:    fcvt.s.wu ft0, a0
516; RV64IF-NEXT:    fmv.x.w a0, ft0
517; RV64IF-NEXT:    ret
518  %1 = uitofp i16 %a to float
519  ret float %1
520}
521
522; Make sure we select W version of addi on RV64.
523define signext i32 @fcvt_s_w_demanded_bits(i32 signext %0, float* %1) {
524; RV32IF-LABEL: fcvt_s_w_demanded_bits:
525; RV32IF:       # %bb.0:
526; RV32IF-NEXT:    addi a0, a0, 1
527; RV32IF-NEXT:    fcvt.s.w ft0, a0
528; RV32IF-NEXT:    fsw ft0, 0(a1)
529; RV32IF-NEXT:    ret
530;
531; RV64IF-LABEL: fcvt_s_w_demanded_bits:
532; RV64IF:       # %bb.0:
533; RV64IF-NEXT:    addiw a0, a0, 1
534; RV64IF-NEXT:    fcvt.s.w ft0, a0
535; RV64IF-NEXT:    fsw ft0, 0(a1)
536; RV64IF-NEXT:    ret
537  %3 = add i32 %0, 1
538  %4 = sitofp i32 %3 to float
539  store float %4, float* %1, align 4
540  ret i32 %3
541}
542
543; Make sure we select W version of addi on RV64.
544define signext i32 @fcvt_s_wu_demanded_bits(i32 signext %0, float* %1) {
545; RV32IF-LABEL: fcvt_s_wu_demanded_bits:
546; RV32IF:       # %bb.0:
547; RV32IF-NEXT:    addi a0, a0, 1
548; RV32IF-NEXT:    fcvt.s.wu ft0, a0
549; RV32IF-NEXT:    fsw ft0, 0(a1)
550; RV32IF-NEXT:    ret
551;
552; RV64IF-LABEL: fcvt_s_wu_demanded_bits:
553; RV64IF:       # %bb.0:
554; RV64IF-NEXT:    addiw a0, a0, 1
555; RV64IF-NEXT:    fcvt.s.wu ft0, a0
556; RV64IF-NEXT:    fsw ft0, 0(a1)
557; RV64IF-NEXT:    ret
558  %3 = add i32 %0, 1
559  %4 = uitofp i32 %3 to float
560  store float %4, float* %1, align 4
561  ret i32 %3
562}
563