1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
3; RUN:   | FileCheck -check-prefix=RV32IFD %s
4; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \
5; RUN:   | FileCheck -check-prefix=RV64IFD %s
6
7define float @fcvt_s_d(double %a) nounwind {
8; RV32IFD-LABEL: fcvt_s_d:
9; RV32IFD:       # %bb.0:
10; RV32IFD-NEXT:    addi sp, sp, -16
11; RV32IFD-NEXT:    sw a0, 8(sp)
12; RV32IFD-NEXT:    sw a1, 12(sp)
13; RV32IFD-NEXT:    fld ft0, 8(sp)
14; RV32IFD-NEXT:    fcvt.s.d ft0, ft0
15; RV32IFD-NEXT:    fmv.x.w a0, ft0
16; RV32IFD-NEXT:    addi sp, sp, 16
17; RV32IFD-NEXT:    ret
18;
19; RV64IFD-LABEL: fcvt_s_d:
20; RV64IFD:       # %bb.0:
21; RV64IFD-NEXT:    fmv.d.x ft0, a0
22; RV64IFD-NEXT:    fcvt.s.d ft0, ft0
23; RV64IFD-NEXT:    fmv.x.w a0, ft0
24; RV64IFD-NEXT:    ret
25  %1 = fptrunc double %a to float
26  ret float %1
27}
28
29define double @fcvt_d_s(float %a) nounwind {
30; RV32IFD-LABEL: fcvt_d_s:
31; RV32IFD:       # %bb.0:
32; RV32IFD-NEXT:    addi sp, sp, -16
33; RV32IFD-NEXT:    fmv.w.x ft0, a0
34; RV32IFD-NEXT:    fcvt.d.s ft0, ft0
35; RV32IFD-NEXT:    fsd ft0, 8(sp)
36; RV32IFD-NEXT:    lw a0, 8(sp)
37; RV32IFD-NEXT:    lw a1, 12(sp)
38; RV32IFD-NEXT:    addi sp, sp, 16
39; RV32IFD-NEXT:    ret
40;
41; RV64IFD-LABEL: fcvt_d_s:
42; RV64IFD:       # %bb.0:
43; RV64IFD-NEXT:    fmv.w.x ft0, a0
44; RV64IFD-NEXT:    fcvt.d.s ft0, ft0
45; RV64IFD-NEXT:    fmv.x.d a0, ft0
46; RV64IFD-NEXT:    ret
47  %1 = fpext float %a to double
48  ret double %1
49}
50
51; For RV64D, fcvt.l.d is semantically equivalent to fcvt.w.d in this case
52; because fptosi will produce poison if the result doesn't fit into an i32.
53define i32 @fcvt_w_d(double %a) nounwind {
54; RV32IFD-LABEL: fcvt_w_d:
55; RV32IFD:       # %bb.0:
56; RV32IFD-NEXT:    addi sp, sp, -16
57; RV32IFD-NEXT:    sw a0, 8(sp)
58; RV32IFD-NEXT:    sw a1, 12(sp)
59; RV32IFD-NEXT:    fld ft0, 8(sp)
60; RV32IFD-NEXT:    fcvt.w.d a0, ft0, rtz
61; RV32IFD-NEXT:    addi sp, sp, 16
62; RV32IFD-NEXT:    ret
63;
64; RV64IFD-LABEL: fcvt_w_d:
65; RV64IFD:       # %bb.0:
66; RV64IFD-NEXT:    fmv.d.x ft0, a0
67; RV64IFD-NEXT:    fcvt.l.d a0, ft0, rtz
68; RV64IFD-NEXT:    ret
69  %1 = fptosi double %a to i32
70  ret i32 %1
71}
72
73define i32 @fcvt_w_d_sat(double %a) nounwind {
74; RV32IFD-LABEL: fcvt_w_d_sat:
75; RV32IFD:       # %bb.0: # %start
76; RV32IFD-NEXT:    addi sp, sp, -16
77; RV32IFD-NEXT:    sw a0, 8(sp)
78; RV32IFD-NEXT:    sw a1, 12(sp)
79; RV32IFD-NEXT:    fld ft0, 8(sp)
80; RV32IFD-NEXT:    feq.d a0, ft0, ft0
81; RV32IFD-NEXT:    bnez a0, .LBB3_2
82; RV32IFD-NEXT:  # %bb.1: # %start
83; RV32IFD-NEXT:    mv a0, zero
84; RV32IFD-NEXT:    addi sp, sp, 16
85; RV32IFD-NEXT:    ret
86; RV32IFD-NEXT:  .LBB3_2:
87; RV32IFD-NEXT:    lui a0, %hi(.LCPI3_0)
88; RV32IFD-NEXT:    fld ft1, %lo(.LCPI3_0)(a0)
89; RV32IFD-NEXT:    lui a0, %hi(.LCPI3_1)
90; RV32IFD-NEXT:    fld ft2, %lo(.LCPI3_1)(a0)
91; RV32IFD-NEXT:    fmax.d ft0, ft0, ft1
92; RV32IFD-NEXT:    fmin.d ft0, ft0, ft2
93; RV32IFD-NEXT:    fcvt.w.d a0, ft0, rtz
94; RV32IFD-NEXT:    addi sp, sp, 16
95; RV32IFD-NEXT:    ret
96;
97; RV64IFD-LABEL: fcvt_w_d_sat:
98; RV64IFD:       # %bb.0: # %start
99; RV64IFD-NEXT:    fmv.d.x ft0, a0
100; RV64IFD-NEXT:    feq.d a0, ft0, ft0
101; RV64IFD-NEXT:    bnez a0, .LBB3_2
102; RV64IFD-NEXT:  # %bb.1: # %start
103; RV64IFD-NEXT:    mv a0, zero
104; RV64IFD-NEXT:    ret
105; RV64IFD-NEXT:  .LBB3_2:
106; RV64IFD-NEXT:    lui a0, %hi(.LCPI3_0)
107; RV64IFD-NEXT:    fld ft1, %lo(.LCPI3_0)(a0)
108; RV64IFD-NEXT:    lui a0, %hi(.LCPI3_1)
109; RV64IFD-NEXT:    fld ft2, %lo(.LCPI3_1)(a0)
110; RV64IFD-NEXT:    fmax.d ft0, ft0, ft1
111; RV64IFD-NEXT:    fmin.d ft0, ft0, ft2
112; RV64IFD-NEXT:    fcvt.l.d a0, ft0, rtz
113; RV64IFD-NEXT:    ret
114start:
115  %0 = tail call i32 @llvm.fptosi.sat.i32.f64(double %a)
116  ret i32 %0
117}
118declare i32 @llvm.fptosi.sat.i32.f64(double)
119
120; For RV64D, fcvt.lu.d is semantically equivalent to fcvt.wu.d in this case
121; because fptosi will produce poison if the result doesn't fit into an i32.
122define i32 @fcvt_wu_d(double %a) nounwind {
123; RV32IFD-LABEL: fcvt_wu_d:
124; RV32IFD:       # %bb.0:
125; RV32IFD-NEXT:    addi sp, sp, -16
126; RV32IFD-NEXT:    sw a0, 8(sp)
127; RV32IFD-NEXT:    sw a1, 12(sp)
128; RV32IFD-NEXT:    fld ft0, 8(sp)
129; RV32IFD-NEXT:    fcvt.wu.d a0, ft0, rtz
130; RV32IFD-NEXT:    addi sp, sp, 16
131; RV32IFD-NEXT:    ret
132;
133; RV64IFD-LABEL: fcvt_wu_d:
134; RV64IFD:       # %bb.0:
135; RV64IFD-NEXT:    fmv.d.x ft0, a0
136; RV64IFD-NEXT:    fcvt.lu.d a0, ft0, rtz
137; RV64IFD-NEXT:    ret
138  %1 = fptoui double %a to i32
139  ret i32 %1
140}
141
142define i32 @fcvt_wu_d_sat(double %a) nounwind {
143; RV32IFD-LABEL: fcvt_wu_d_sat:
144; RV32IFD:       # %bb.0: # %start
145; RV32IFD-NEXT:    addi sp, sp, -16
146; RV32IFD-NEXT:    sw a0, 8(sp)
147; RV32IFD-NEXT:    sw a1, 12(sp)
148; RV32IFD-NEXT:    fld ft0, 8(sp)
149; RV32IFD-NEXT:    lui a0, %hi(.LCPI5_0)
150; RV32IFD-NEXT:    fld ft1, %lo(.LCPI5_0)(a0)
151; RV32IFD-NEXT:    fcvt.d.w ft2, zero
152; RV32IFD-NEXT:    fmax.d ft0, ft0, ft2
153; RV32IFD-NEXT:    fmin.d ft0, ft0, ft1
154; RV32IFD-NEXT:    fcvt.wu.d a0, ft0, rtz
155; RV32IFD-NEXT:    addi sp, sp, 16
156; RV32IFD-NEXT:    ret
157;
158; RV64IFD-LABEL: fcvt_wu_d_sat:
159; RV64IFD:       # %bb.0: # %start
160; RV64IFD-NEXT:    lui a1, %hi(.LCPI5_0)
161; RV64IFD-NEXT:    fld ft0, %lo(.LCPI5_0)(a1)
162; RV64IFD-NEXT:    fmv.d.x ft1, a0
163; RV64IFD-NEXT:    fmv.d.x ft2, zero
164; RV64IFD-NEXT:    fmax.d ft1, ft1, ft2
165; RV64IFD-NEXT:    fmin.d ft0, ft1, ft0
166; RV64IFD-NEXT:    fcvt.lu.d a0, ft0, rtz
167; RV64IFD-NEXT:    ret
168start:
169  %0 = tail call i32 @llvm.fptoui.sat.i32.f64(double %a)
170  ret i32 %0
171}
172declare i32 @llvm.fptoui.sat.i32.f64(double)
173
174define double @fcvt_d_w(i32 %a) nounwind {
175; RV32IFD-LABEL: fcvt_d_w:
176; RV32IFD:       # %bb.0:
177; RV32IFD-NEXT:    addi sp, sp, -16
178; RV32IFD-NEXT:    fcvt.d.w ft0, a0
179; RV32IFD-NEXT:    fsd ft0, 8(sp)
180; RV32IFD-NEXT:    lw a0, 8(sp)
181; RV32IFD-NEXT:    lw a1, 12(sp)
182; RV32IFD-NEXT:    addi sp, sp, 16
183; RV32IFD-NEXT:    ret
184;
185; RV64IFD-LABEL: fcvt_d_w:
186; RV64IFD:       # %bb.0:
187; RV64IFD-NEXT:    fcvt.d.w ft0, a0
188; RV64IFD-NEXT:    fmv.x.d a0, ft0
189; RV64IFD-NEXT:    ret
190  %1 = sitofp i32 %a to double
191  ret double %1
192}
193
194define double @fcvt_d_w_load(i32* %p) nounwind {
195; RV32IFD-LABEL: fcvt_d_w_load:
196; RV32IFD:       # %bb.0:
197; RV32IFD-NEXT:    addi sp, sp, -16
198; RV32IFD-NEXT:    lw a0, 0(a0)
199; RV32IFD-NEXT:    fcvt.d.w ft0, a0
200; RV32IFD-NEXT:    fsd ft0, 8(sp)
201; RV32IFD-NEXT:    lw a0, 8(sp)
202; RV32IFD-NEXT:    lw a1, 12(sp)
203; RV32IFD-NEXT:    addi sp, sp, 16
204; RV32IFD-NEXT:    ret
205;
206; RV64IFD-LABEL: fcvt_d_w_load:
207; RV64IFD:       # %bb.0:
208; RV64IFD-NEXT:    lw a0, 0(a0)
209; RV64IFD-NEXT:    fcvt.d.w ft0, a0
210; RV64IFD-NEXT:    fmv.x.d a0, ft0
211; RV64IFD-NEXT:    ret
212  %a = load i32, i32* %p
213  %1 = sitofp i32 %a to double
214  ret double %1
215}
216
217define double @fcvt_d_wu(i32 %a) nounwind {
218; RV32IFD-LABEL: fcvt_d_wu:
219; RV32IFD:       # %bb.0:
220; RV32IFD-NEXT:    addi sp, sp, -16
221; RV32IFD-NEXT:    fcvt.d.wu ft0, a0
222; RV32IFD-NEXT:    fsd ft0, 8(sp)
223; RV32IFD-NEXT:    lw a0, 8(sp)
224; RV32IFD-NEXT:    lw a1, 12(sp)
225; RV32IFD-NEXT:    addi sp, sp, 16
226; RV32IFD-NEXT:    ret
227;
228; RV64IFD-LABEL: fcvt_d_wu:
229; RV64IFD:       # %bb.0:
230; RV64IFD-NEXT:    fcvt.d.wu ft0, a0
231; RV64IFD-NEXT:    fmv.x.d a0, ft0
232; RV64IFD-NEXT:    ret
233  %1 = uitofp i32 %a to double
234  ret double %1
235}
236
237define double @fcvt_d_wu_load(i32* %p) nounwind {
238; RV32IFD-LABEL: fcvt_d_wu_load:
239; RV32IFD:       # %bb.0:
240; RV32IFD-NEXT:    addi sp, sp, -16
241; RV32IFD-NEXT:    lw a0, 0(a0)
242; RV32IFD-NEXT:    fcvt.d.wu ft0, a0
243; RV32IFD-NEXT:    fsd ft0, 8(sp)
244; RV32IFD-NEXT:    lw a0, 8(sp)
245; RV32IFD-NEXT:    lw a1, 12(sp)
246; RV32IFD-NEXT:    addi sp, sp, 16
247; RV32IFD-NEXT:    ret
248;
249; RV64IFD-LABEL: fcvt_d_wu_load:
250; RV64IFD:       # %bb.0:
251; RV64IFD-NEXT:    lwu a0, 0(a0)
252; RV64IFD-NEXT:    fcvt.d.wu ft0, a0
253; RV64IFD-NEXT:    fmv.x.d a0, ft0
254; RV64IFD-NEXT:    ret
255  %a = load i32, i32* %p
256  %1 = uitofp i32 %a to double
257  ret double %1
258}
259
260define i64 @fcvt_l_d(double %a) nounwind {
261; RV32IFD-LABEL: fcvt_l_d:
262; RV32IFD:       # %bb.0:
263; RV32IFD-NEXT:    addi sp, sp, -16
264; RV32IFD-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
265; RV32IFD-NEXT:    call __fixdfdi@plt
266; RV32IFD-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
267; RV32IFD-NEXT:    addi sp, sp, 16
268; RV32IFD-NEXT:    ret
269;
270; RV64IFD-LABEL: fcvt_l_d:
271; RV64IFD:       # %bb.0:
272; RV64IFD-NEXT:    fmv.d.x ft0, a0
273; RV64IFD-NEXT:    fcvt.l.d a0, ft0, rtz
274; RV64IFD-NEXT:    ret
275  %1 = fptosi double %a to i64
276  ret i64 %1
277}
278
279define i64 @fcvt_l_d_sat(double %a) nounwind {
280; RV32IFD-LABEL: fcvt_l_d_sat:
281; RV32IFD:       # %bb.0: # %start
282; RV32IFD-NEXT:    addi sp, sp, -32
283; RV32IFD-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
284; RV32IFD-NEXT:    sw a0, 16(sp)
285; RV32IFD-NEXT:    sw a1, 20(sp)
286; RV32IFD-NEXT:    fld ft0, 16(sp)
287; RV32IFD-NEXT:    fsd ft0, 8(sp) # 8-byte Folded Spill
288; RV32IFD-NEXT:    call __fixdfdi@plt
289; RV32IFD-NEXT:    fld ft1, 8(sp) # 8-byte Folded Reload
290; RV32IFD-NEXT:    lui a2, %hi(.LCPI11_0)
291; RV32IFD-NEXT:    fld ft0, %lo(.LCPI11_0)(a2)
292; RV32IFD-NEXT:    fle.d a3, ft0, ft1
293; RV32IFD-NEXT:    mv a2, a0
294; RV32IFD-NEXT:    bnez a3, .LBB11_2
295; RV32IFD-NEXT:  # %bb.1: # %start
296; RV32IFD-NEXT:    mv a2, zero
297; RV32IFD-NEXT:  .LBB11_2: # %start
298; RV32IFD-NEXT:    lui a0, %hi(.LCPI11_1)
299; RV32IFD-NEXT:    fld ft0, %lo(.LCPI11_1)(a0)
300; RV32IFD-NEXT:    flt.d a4, ft0, ft1
301; RV32IFD-NEXT:    addi a0, zero, -1
302; RV32IFD-NEXT:    beqz a4, .LBB11_9
303; RV32IFD-NEXT:  # %bb.3: # %start
304; RV32IFD-NEXT:    feq.d a2, ft1, ft1
305; RV32IFD-NEXT:    beqz a2, .LBB11_10
306; RV32IFD-NEXT:  .LBB11_4: # %start
307; RV32IFD-NEXT:    lui a5, 524288
308; RV32IFD-NEXT:    beqz a3, .LBB11_11
309; RV32IFD-NEXT:  .LBB11_5: # %start
310; RV32IFD-NEXT:    bnez a4, .LBB11_12
311; RV32IFD-NEXT:  .LBB11_6: # %start
312; RV32IFD-NEXT:    bnez a2, .LBB11_8
313; RV32IFD-NEXT:  .LBB11_7: # %start
314; RV32IFD-NEXT:    mv a1, zero
315; RV32IFD-NEXT:  .LBB11_8: # %start
316; RV32IFD-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
317; RV32IFD-NEXT:    addi sp, sp, 32
318; RV32IFD-NEXT:    ret
319; RV32IFD-NEXT:  .LBB11_9: # %start
320; RV32IFD-NEXT:    mv a0, a2
321; RV32IFD-NEXT:    feq.d a2, ft1, ft1
322; RV32IFD-NEXT:    bnez a2, .LBB11_4
323; RV32IFD-NEXT:  .LBB11_10: # %start
324; RV32IFD-NEXT:    mv a0, zero
325; RV32IFD-NEXT:    lui a5, 524288
326; RV32IFD-NEXT:    bnez a3, .LBB11_5
327; RV32IFD-NEXT:  .LBB11_11: # %start
328; RV32IFD-NEXT:    lui a1, 524288
329; RV32IFD-NEXT:    beqz a4, .LBB11_6
330; RV32IFD-NEXT:  .LBB11_12:
331; RV32IFD-NEXT:    addi a1, a5, -1
332; RV32IFD-NEXT:    beqz a2, .LBB11_7
333; RV32IFD-NEXT:    j .LBB11_8
334;
335; RV64IFD-LABEL: fcvt_l_d_sat:
336; RV64IFD:       # %bb.0: # %start
337; RV64IFD-NEXT:    lui a1, %hi(.LCPI11_0)
338; RV64IFD-NEXT:    fld ft1, %lo(.LCPI11_0)(a1)
339; RV64IFD-NEXT:    fmv.d.x ft0, a0
340; RV64IFD-NEXT:    fle.d a0, ft1, ft0
341; RV64IFD-NEXT:    addi a1, zero, -1
342; RV64IFD-NEXT:    bnez a0, .LBB11_2
343; RV64IFD-NEXT:  # %bb.1: # %start
344; RV64IFD-NEXT:    slli a0, a1, 63
345; RV64IFD-NEXT:    j .LBB11_3
346; RV64IFD-NEXT:  .LBB11_2:
347; RV64IFD-NEXT:    fcvt.l.d a0, ft0, rtz
348; RV64IFD-NEXT:  .LBB11_3: # %start
349; RV64IFD-NEXT:    lui a2, %hi(.LCPI11_1)
350; RV64IFD-NEXT:    fld ft1, %lo(.LCPI11_1)(a2)
351; RV64IFD-NEXT:    flt.d a2, ft1, ft0
352; RV64IFD-NEXT:    bnez a2, .LBB11_6
353; RV64IFD-NEXT:  # %bb.4: # %start
354; RV64IFD-NEXT:    feq.d a1, ft0, ft0
355; RV64IFD-NEXT:    beqz a1, .LBB11_7
356; RV64IFD-NEXT:  .LBB11_5: # %start
357; RV64IFD-NEXT:    ret
358; RV64IFD-NEXT:  .LBB11_6:
359; RV64IFD-NEXT:    srli a0, a1, 1
360; RV64IFD-NEXT:    feq.d a1, ft0, ft0
361; RV64IFD-NEXT:    bnez a1, .LBB11_5
362; RV64IFD-NEXT:  .LBB11_7: # %start
363; RV64IFD-NEXT:    mv a0, zero
364; RV64IFD-NEXT:    ret
365start:
366  %0 = tail call i64 @llvm.fptosi.sat.i64.f64(double %a)
367  ret i64 %0
368}
369declare i64 @llvm.fptosi.sat.i64.f64(double)
370
371define i64 @fcvt_lu_d(double %a) nounwind {
372; RV32IFD-LABEL: fcvt_lu_d:
373; RV32IFD:       # %bb.0:
374; RV32IFD-NEXT:    addi sp, sp, -16
375; RV32IFD-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
376; RV32IFD-NEXT:    call __fixunsdfdi@plt
377; RV32IFD-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
378; RV32IFD-NEXT:    addi sp, sp, 16
379; RV32IFD-NEXT:    ret
380;
381; RV64IFD-LABEL: fcvt_lu_d:
382; RV64IFD:       # %bb.0:
383; RV64IFD-NEXT:    fmv.d.x ft0, a0
384; RV64IFD-NEXT:    fcvt.lu.d a0, ft0, rtz
385; RV64IFD-NEXT:    ret
386  %1 = fptoui double %a to i64
387  ret i64 %1
388}
389
390define i64 @fcvt_lu_d_sat(double %a) nounwind {
391; RV32IFD-LABEL: fcvt_lu_d_sat:
392; RV32IFD:       # %bb.0: # %start
393; RV32IFD-NEXT:    addi sp, sp, -32
394; RV32IFD-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
395; RV32IFD-NEXT:    sw a0, 16(sp)
396; RV32IFD-NEXT:    sw a1, 20(sp)
397; RV32IFD-NEXT:    fld ft0, 16(sp)
398; RV32IFD-NEXT:    fsd ft0, 8(sp) # 8-byte Folded Spill
399; RV32IFD-NEXT:    call __fixunsdfdi@plt
400; RV32IFD-NEXT:    fld ft1, 8(sp) # 8-byte Folded Reload
401; RV32IFD-NEXT:    fcvt.d.w ft0, zero
402; RV32IFD-NEXT:    fle.d a4, ft0, ft1
403; RV32IFD-NEXT:    mv a3, a0
404; RV32IFD-NEXT:    bnez a4, .LBB13_2
405; RV32IFD-NEXT:  # %bb.1: # %start
406; RV32IFD-NEXT:    mv a3, zero
407; RV32IFD-NEXT:  .LBB13_2: # %start
408; RV32IFD-NEXT:    lui a0, %hi(.LCPI13_0)
409; RV32IFD-NEXT:    fld ft0, %lo(.LCPI13_0)(a0)
410; RV32IFD-NEXT:    flt.d a5, ft0, ft1
411; RV32IFD-NEXT:    addi a2, zero, -1
412; RV32IFD-NEXT:    addi a0, zero, -1
413; RV32IFD-NEXT:    beqz a5, .LBB13_7
414; RV32IFD-NEXT:  # %bb.3: # %start
415; RV32IFD-NEXT:    beqz a4, .LBB13_8
416; RV32IFD-NEXT:  .LBB13_4: # %start
417; RV32IFD-NEXT:    bnez a5, .LBB13_6
418; RV32IFD-NEXT:  .LBB13_5: # %start
419; RV32IFD-NEXT:    mv a2, a1
420; RV32IFD-NEXT:  .LBB13_6: # %start
421; RV32IFD-NEXT:    mv a1, a2
422; RV32IFD-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
423; RV32IFD-NEXT:    addi sp, sp, 32
424; RV32IFD-NEXT:    ret
425; RV32IFD-NEXT:  .LBB13_7: # %start
426; RV32IFD-NEXT:    mv a0, a3
427; RV32IFD-NEXT:    bnez a4, .LBB13_4
428; RV32IFD-NEXT:  .LBB13_8: # %start
429; RV32IFD-NEXT:    mv a1, zero
430; RV32IFD-NEXT:    beqz a5, .LBB13_5
431; RV32IFD-NEXT:    j .LBB13_6
432;
433; RV64IFD-LABEL: fcvt_lu_d_sat:
434; RV64IFD:       # %bb.0: # %start
435; RV64IFD-NEXT:    fmv.d.x ft0, a0
436; RV64IFD-NEXT:    fmv.d.x ft1, zero
437; RV64IFD-NEXT:    fle.d a0, ft1, ft0
438; RV64IFD-NEXT:    bnez a0, .LBB13_2
439; RV64IFD-NEXT:  # %bb.1: # %start
440; RV64IFD-NEXT:    mv a1, zero
441; RV64IFD-NEXT:    j .LBB13_3
442; RV64IFD-NEXT:  .LBB13_2:
443; RV64IFD-NEXT:    fcvt.lu.d a1, ft0, rtz
444; RV64IFD-NEXT:  .LBB13_3: # %start
445; RV64IFD-NEXT:    lui a0, %hi(.LCPI13_0)
446; RV64IFD-NEXT:    fld ft1, %lo(.LCPI13_0)(a0)
447; RV64IFD-NEXT:    flt.d a2, ft1, ft0
448; RV64IFD-NEXT:    addi a0, zero, -1
449; RV64IFD-NEXT:    bnez a2, .LBB13_5
450; RV64IFD-NEXT:  # %bb.4: # %start
451; RV64IFD-NEXT:    mv a0, a1
452; RV64IFD-NEXT:  .LBB13_5: # %start
453; RV64IFD-NEXT:    ret
454start:
455  %0 = tail call i64 @llvm.fptoui.sat.i64.f64(double %a)
456  ret i64 %0
457}
458declare i64 @llvm.fptoui.sat.i64.f64(double)
459
460define i64 @fmv_x_d(double %a, double %b) nounwind {
461; RV32IFD-LABEL: fmv_x_d:
462; RV32IFD:       # %bb.0:
463; RV32IFD-NEXT:    addi sp, sp, -16
464; RV32IFD-NEXT:    sw a2, 0(sp)
465; RV32IFD-NEXT:    sw a3, 4(sp)
466; RV32IFD-NEXT:    fld ft0, 0(sp)
467; RV32IFD-NEXT:    sw a0, 0(sp)
468; RV32IFD-NEXT:    sw a1, 4(sp)
469; RV32IFD-NEXT:    fld ft1, 0(sp)
470; RV32IFD-NEXT:    fadd.d ft0, ft1, ft0
471; RV32IFD-NEXT:    fsd ft0, 8(sp)
472; RV32IFD-NEXT:    lw a0, 8(sp)
473; RV32IFD-NEXT:    lw a1, 12(sp)
474; RV32IFD-NEXT:    addi sp, sp, 16
475; RV32IFD-NEXT:    ret
476;
477; RV64IFD-LABEL: fmv_x_d:
478; RV64IFD:       # %bb.0:
479; RV64IFD-NEXT:    fmv.d.x ft0, a1
480; RV64IFD-NEXT:    fmv.d.x ft1, a0
481; RV64IFD-NEXT:    fadd.d ft0, ft1, ft0
482; RV64IFD-NEXT:    fmv.x.d a0, ft0
483; RV64IFD-NEXT:    ret
484  %1 = fadd double %a, %b
485  %2 = bitcast double %1 to i64
486  ret i64 %2
487}
488
489define double @fcvt_d_l(i64 %a) nounwind {
490; RV32IFD-LABEL: fcvt_d_l:
491; RV32IFD:       # %bb.0:
492; RV32IFD-NEXT:    addi sp, sp, -16
493; RV32IFD-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
494; RV32IFD-NEXT:    call __floatdidf@plt
495; RV32IFD-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
496; RV32IFD-NEXT:    addi sp, sp, 16
497; RV32IFD-NEXT:    ret
498;
499; RV64IFD-LABEL: fcvt_d_l:
500; RV64IFD:       # %bb.0:
501; RV64IFD-NEXT:    fcvt.d.l ft0, a0
502; RV64IFD-NEXT:    fmv.x.d a0, ft0
503; RV64IFD-NEXT:    ret
504  %1 = sitofp i64 %a to double
505  ret double %1
506}
507
508define double @fcvt_d_lu(i64 %a) nounwind {
509; RV32IFD-LABEL: fcvt_d_lu:
510; RV32IFD:       # %bb.0:
511; RV32IFD-NEXT:    addi sp, sp, -16
512; RV32IFD-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
513; RV32IFD-NEXT:    call __floatundidf@plt
514; RV32IFD-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
515; RV32IFD-NEXT:    addi sp, sp, 16
516; RV32IFD-NEXT:    ret
517;
518; RV64IFD-LABEL: fcvt_d_lu:
519; RV64IFD:       # %bb.0:
520; RV64IFD-NEXT:    fcvt.d.lu ft0, a0
521; RV64IFD-NEXT:    fmv.x.d a0, ft0
522; RV64IFD-NEXT:    ret
523  %1 = uitofp i64 %a to double
524  ret double %1
525}
526
527define double @fmv_d_x(i64 %a, i64 %b) nounwind {
528; Ensure fmv.w.x is generated even for a soft double calling convention
529; RV32IFD-LABEL: fmv_d_x:
530; RV32IFD:       # %bb.0:
531; RV32IFD-NEXT:    addi sp, sp, -32
532; RV32IFD-NEXT:    sw a3, 20(sp)
533; RV32IFD-NEXT:    sw a2, 16(sp)
534; RV32IFD-NEXT:    sw a1, 28(sp)
535; RV32IFD-NEXT:    sw a0, 24(sp)
536; RV32IFD-NEXT:    fld ft0, 16(sp)
537; RV32IFD-NEXT:    fld ft1, 24(sp)
538; RV32IFD-NEXT:    fadd.d ft0, ft1, ft0
539; RV32IFD-NEXT:    fsd ft0, 8(sp)
540; RV32IFD-NEXT:    lw a0, 8(sp)
541; RV32IFD-NEXT:    lw a1, 12(sp)
542; RV32IFD-NEXT:    addi sp, sp, 32
543; RV32IFD-NEXT:    ret
544;
545; RV64IFD-LABEL: fmv_d_x:
546; RV64IFD:       # %bb.0:
547; RV64IFD-NEXT:    fmv.d.x ft0, a0
548; RV64IFD-NEXT:    fmv.d.x ft1, a1
549; RV64IFD-NEXT:    fadd.d ft0, ft0, ft1
550; RV64IFD-NEXT:    fmv.x.d a0, ft0
551; RV64IFD-NEXT:    ret
552  %1 = bitcast i64 %a to double
553  %2 = bitcast i64 %b to double
554  %3 = fadd double %1, %2
555  ret double %3
556}
557
558define double @fcvt_d_w_i8(i8 signext %a) nounwind {
559; RV32IFD-LABEL: fcvt_d_w_i8:
560; RV32IFD:       # %bb.0:
561; RV32IFD-NEXT:    addi sp, sp, -16
562; RV32IFD-NEXT:    fcvt.d.w ft0, a0
563; RV32IFD-NEXT:    fsd ft0, 8(sp)
564; RV32IFD-NEXT:    lw a0, 8(sp)
565; RV32IFD-NEXT:    lw a1, 12(sp)
566; RV32IFD-NEXT:    addi sp, sp, 16
567; RV32IFD-NEXT:    ret
568;
569; RV64IFD-LABEL: fcvt_d_w_i8:
570; RV64IFD:       # %bb.0:
571; RV64IFD-NEXT:    fcvt.d.w ft0, a0
572; RV64IFD-NEXT:    fmv.x.d a0, ft0
573; RV64IFD-NEXT:    ret
574  %1 = sitofp i8 %a to double
575  ret double %1
576}
577
578define double @fcvt_d_wu_i8(i8 zeroext %a) nounwind {
579; RV32IFD-LABEL: fcvt_d_wu_i8:
580; RV32IFD:       # %bb.0:
581; RV32IFD-NEXT:    addi sp, sp, -16
582; RV32IFD-NEXT:    fcvt.d.wu ft0, a0
583; RV32IFD-NEXT:    fsd ft0, 8(sp)
584; RV32IFD-NEXT:    lw a0, 8(sp)
585; RV32IFD-NEXT:    lw a1, 12(sp)
586; RV32IFD-NEXT:    addi sp, sp, 16
587; RV32IFD-NEXT:    ret
588;
589; RV64IFD-LABEL: fcvt_d_wu_i8:
590; RV64IFD:       # %bb.0:
591; RV64IFD-NEXT:    fcvt.d.wu ft0, a0
592; RV64IFD-NEXT:    fmv.x.d a0, ft0
593; RV64IFD-NEXT:    ret
594  %1 = uitofp i8 %a to double
595  ret double %1
596}
597
598define double @fcvt_d_w_i16(i16 signext %a) nounwind {
599; RV32IFD-LABEL: fcvt_d_w_i16:
600; RV32IFD:       # %bb.0:
601; RV32IFD-NEXT:    addi sp, sp, -16
602; RV32IFD-NEXT:    fcvt.d.w ft0, a0
603; RV32IFD-NEXT:    fsd ft0, 8(sp)
604; RV32IFD-NEXT:    lw a0, 8(sp)
605; RV32IFD-NEXT:    lw a1, 12(sp)
606; RV32IFD-NEXT:    addi sp, sp, 16
607; RV32IFD-NEXT:    ret
608;
609; RV64IFD-LABEL: fcvt_d_w_i16:
610; RV64IFD:       # %bb.0:
611; RV64IFD-NEXT:    fcvt.d.w ft0, a0
612; RV64IFD-NEXT:    fmv.x.d a0, ft0
613; RV64IFD-NEXT:    ret
614  %1 = sitofp i16 %a to double
615  ret double %1
616}
617
618define double @fcvt_d_wu_i16(i16 zeroext %a) nounwind {
619; RV32IFD-LABEL: fcvt_d_wu_i16:
620; RV32IFD:       # %bb.0:
621; RV32IFD-NEXT:    addi sp, sp, -16
622; RV32IFD-NEXT:    fcvt.d.wu ft0, a0
623; RV32IFD-NEXT:    fsd ft0, 8(sp)
624; RV32IFD-NEXT:    lw a0, 8(sp)
625; RV32IFD-NEXT:    lw a1, 12(sp)
626; RV32IFD-NEXT:    addi sp, sp, 16
627; RV32IFD-NEXT:    ret
628;
629; RV64IFD-LABEL: fcvt_d_wu_i16:
630; RV64IFD:       # %bb.0:
631; RV64IFD-NEXT:    fcvt.d.wu ft0, a0
632; RV64IFD-NEXT:    fmv.x.d a0, ft0
633; RV64IFD-NEXT:    ret
634  %1 = uitofp i16 %a to double
635  ret double %1
636}
637