• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.l.s a0, ft0, rtz
20; RV64IF-NEXT:    ret
21  %1 = fptosi float %a to i32
22  ret i32 %1
23}
24
25; For RV64F, fcvt.lu.s is semantically equivalent to fcvt.wu.s in this case
26; because fptoui will produce poison if the result doesn't fit into an i32.
27define i32 @fcvt_wu_s(float %a) nounwind {
28; RV32IF-LABEL: fcvt_wu_s:
29; RV32IF:       # %bb.0:
30; RV32IF-NEXT:    fmv.w.x ft0, a0
31; RV32IF-NEXT:    fcvt.wu.s a0, ft0, rtz
32; RV32IF-NEXT:    ret
33;
34; RV64IF-LABEL: fcvt_wu_s:
35; RV64IF:       # %bb.0:
36; RV64IF-NEXT:    fmv.w.x ft0, a0
37; RV64IF-NEXT:    fcvt.lu.s a0, ft0, rtz
38; RV64IF-NEXT:    ret
39  %1 = fptoui float %a to i32
40  ret i32 %1
41}
42
43define i32 @fmv_x_w(float %a, float %b) nounwind {
44; RV32IF-LABEL: fmv_x_w:
45; RV32IF:       # %bb.0:
46; RV32IF-NEXT:    fmv.w.x ft0, a1
47; RV32IF-NEXT:    fmv.w.x ft1, a0
48; RV32IF-NEXT:    fadd.s ft0, ft1, ft0
49; RV32IF-NEXT:    fmv.x.w a0, ft0
50; RV32IF-NEXT:    ret
51;
52; RV64IF-LABEL: fmv_x_w:
53; RV64IF:       # %bb.0:
54; RV64IF-NEXT:    fmv.w.x ft0, a1
55; RV64IF-NEXT:    fmv.w.x ft1, a0
56; RV64IF-NEXT:    fadd.s ft0, ft1, ft0
57; RV64IF-NEXT:    fmv.x.w a0, ft0
58; RV64IF-NEXT:    ret
59; Ensure fmv.x.w is generated even for a soft float calling convention
60  %1 = fadd float %a, %b
61  %2 = bitcast float %1 to i32
62  ret i32 %2
63}
64
65define float @fcvt_s_w(i32 %a) nounwind {
66; RV32IF-LABEL: fcvt_s_w:
67; RV32IF:       # %bb.0:
68; RV32IF-NEXT:    fcvt.s.w ft0, a0
69; RV32IF-NEXT:    fmv.x.w a0, ft0
70; RV32IF-NEXT:    ret
71;
72; RV64IF-LABEL: fcvt_s_w:
73; RV64IF:       # %bb.0:
74; RV64IF-NEXT:    fcvt.s.w ft0, a0
75; RV64IF-NEXT:    fmv.x.w a0, ft0
76; RV64IF-NEXT:    ret
77  %1 = sitofp i32 %a to float
78  ret float %1
79}
80
81define float @fcvt_s_wu(i32 %a) nounwind {
82; RV32IF-LABEL: fcvt_s_wu:
83; RV32IF:       # %bb.0:
84; RV32IF-NEXT:    fcvt.s.wu ft0, a0
85; RV32IF-NEXT:    fmv.x.w a0, ft0
86; RV32IF-NEXT:    ret
87;
88; RV64IF-LABEL: fcvt_s_wu:
89; RV64IF:       # %bb.0:
90; RV64IF-NEXT:    fcvt.s.wu ft0, a0
91; RV64IF-NEXT:    fmv.x.w a0, ft0
92; RV64IF-NEXT:    ret
93  %1 = uitofp i32 %a to float
94  ret float %1
95}
96
97define float @fmv_w_x(i32 %a, i32 %b) nounwind {
98; RV32IF-LABEL: fmv_w_x:
99; RV32IF:       # %bb.0:
100; RV32IF-NEXT:    fmv.w.x ft0, a0
101; RV32IF-NEXT:    fmv.w.x ft1, a1
102; RV32IF-NEXT:    fadd.s ft0, ft0, ft1
103; RV32IF-NEXT:    fmv.x.w a0, ft0
104; RV32IF-NEXT:    ret
105;
106; RV64IF-LABEL: fmv_w_x:
107; RV64IF:       # %bb.0:
108; RV64IF-NEXT:    fmv.w.x ft0, a0
109; RV64IF-NEXT:    fmv.w.x ft1, a1
110; RV64IF-NEXT:    fadd.s ft0, ft0, ft1
111; RV64IF-NEXT:    fmv.x.w a0, ft0
112; RV64IF-NEXT:    ret
113; Ensure fmv.w.x is generated even for a soft float calling convention
114  %1 = bitcast i32 %a to float
115  %2 = bitcast i32 %b to float
116  %3 = fadd float %1, %2
117  ret float %3
118}
119
120define i64 @fcvt_l_s(float %a) nounwind {
121; RV32IF-LABEL: fcvt_l_s:
122; RV32IF:       # %bb.0:
123; RV32IF-NEXT:    addi sp, sp, -16
124; RV32IF-NEXT:    sw ra, 12(sp)
125; RV32IF-NEXT:    call __fixsfdi
126; RV32IF-NEXT:    lw ra, 12(sp)
127; RV32IF-NEXT:    addi sp, sp, 16
128; RV32IF-NEXT:    ret
129;
130; RV64IF-LABEL: fcvt_l_s:
131; RV64IF:       # %bb.0:
132; RV64IF-NEXT:    fmv.w.x ft0, a0
133; RV64IF-NEXT:    fcvt.l.s a0, ft0, rtz
134; RV64IF-NEXT:    ret
135  %1 = fptosi float %a to i64
136  ret i64 %1
137}
138
139define i64 @fcvt_lu_s(float %a) nounwind {
140; RV32IF-LABEL: fcvt_lu_s:
141; RV32IF:       # %bb.0:
142; RV32IF-NEXT:    addi sp, sp, -16
143; RV32IF-NEXT:    sw ra, 12(sp)
144; RV32IF-NEXT:    call __fixunssfdi
145; RV32IF-NEXT:    lw ra, 12(sp)
146; RV32IF-NEXT:    addi sp, sp, 16
147; RV32IF-NEXT:    ret
148;
149; RV64IF-LABEL: fcvt_lu_s:
150; RV64IF:       # %bb.0:
151; RV64IF-NEXT:    fmv.w.x ft0, a0
152; RV64IF-NEXT:    fcvt.lu.s a0, ft0, rtz
153; RV64IF-NEXT:    ret
154  %1 = fptoui float %a to i64
155  ret i64 %1
156}
157
158define float @fcvt_s_l(i64 %a) nounwind {
159; RV32IF-LABEL: fcvt_s_l:
160; RV32IF:       # %bb.0:
161; RV32IF-NEXT:    addi sp, sp, -16
162; RV32IF-NEXT:    sw ra, 12(sp)
163; RV32IF-NEXT:    call __floatdisf
164; RV32IF-NEXT:    lw ra, 12(sp)
165; RV32IF-NEXT:    addi sp, sp, 16
166; RV32IF-NEXT:    ret
167;
168; RV64IF-LABEL: fcvt_s_l:
169; RV64IF:       # %bb.0:
170; RV64IF-NEXT:    fcvt.s.l ft0, a0
171; RV64IF-NEXT:    fmv.x.w a0, ft0
172; RV64IF-NEXT:    ret
173  %1 = sitofp i64 %a to float
174  ret float %1
175}
176
177define float @fcvt_s_lu(i64 %a) nounwind {
178; RV32IF-LABEL: fcvt_s_lu:
179; RV32IF:       # %bb.0:
180; RV32IF-NEXT:    addi sp, sp, -16
181; RV32IF-NEXT:    sw ra, 12(sp)
182; RV32IF-NEXT:    call __floatundisf
183; RV32IF-NEXT:    lw ra, 12(sp)
184; RV32IF-NEXT:    addi sp, sp, 16
185; RV32IF-NEXT:    ret
186;
187; RV64IF-LABEL: fcvt_s_lu:
188; RV64IF:       # %bb.0:
189; RV64IF-NEXT:    fcvt.s.lu ft0, a0
190; RV64IF-NEXT:    fmv.x.w a0, ft0
191; RV64IF-NEXT:    ret
192  %1 = uitofp i64 %a to float
193  ret float %1
194}
195