xref: /llvm-project/llvm/test/CodeGen/RISCV/rv64zfh-half-convert.ll (revision 4f7ce107de0c3ae0fb5748f98bc696b6eec7aad9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \
3; RUN:   -target-abi lp64f < %s | FileCheck %s -check-prefix=RV64IZFH
4; RUN: llc -mtriple=riscv64 -mattr=+zhinx -verify-machineinstrs \
5; RUN:   -target-abi lp64 < %s | FileCheck %s -check-prefix=RV64IZHINX
6
7; This file exhaustively checks half<->i32 conversions. In general,
8; fcvt.l[u].h can be selected instead of fcvt.w[u].h because poison is
9; generated for an fpto[s|u]i conversion if the result doesn't fit in the
10; target type.
11
12define i32 @aext_fptosi(half %a) nounwind {
13; RV64IZFH-LABEL: aext_fptosi:
14; RV64IZFH:       # %bb.0:
15; RV64IZFH-NEXT:    fcvt.w.h a0, fa0, rtz
16; RV64IZFH-NEXT:    ret
17;
18; RV64IZHINX-LABEL: aext_fptosi:
19; RV64IZHINX:       # %bb.0:
20; RV64IZHINX-NEXT:    fcvt.w.h a0, a0, rtz
21; RV64IZHINX-NEXT:    ret
22  %1 = fptosi half %a to i32
23  ret i32 %1
24}
25
26define signext i32 @sext_fptosi(half %a) nounwind {
27; RV64IZFH-LABEL: sext_fptosi:
28; RV64IZFH:       # %bb.0:
29; RV64IZFH-NEXT:    fcvt.w.h a0, fa0, rtz
30; RV64IZFH-NEXT:    ret
31;
32; RV64IZHINX-LABEL: sext_fptosi:
33; RV64IZHINX:       # %bb.0:
34; RV64IZHINX-NEXT:    fcvt.w.h a0, a0, rtz
35; RV64IZHINX-NEXT:    ret
36  %1 = fptosi half %a to i32
37  ret i32 %1
38}
39
40define zeroext i32 @zext_fptosi(half %a) nounwind {
41; RV64IZFH-LABEL: zext_fptosi:
42; RV64IZFH:       # %bb.0:
43; RV64IZFH-NEXT:    fcvt.w.h a0, fa0, rtz
44; RV64IZFH-NEXT:    slli a0, a0, 32
45; RV64IZFH-NEXT:    srli a0, a0, 32
46; RV64IZFH-NEXT:    ret
47;
48; RV64IZHINX-LABEL: zext_fptosi:
49; RV64IZHINX:       # %bb.0:
50; RV64IZHINX-NEXT:    fcvt.w.h a0, a0, rtz
51; RV64IZHINX-NEXT:    slli a0, a0, 32
52; RV64IZHINX-NEXT:    srli a0, a0, 32
53; RV64IZHINX-NEXT:    ret
54  %1 = fptosi half %a to i32
55  ret i32 %1
56}
57
58define i32 @aext_fptoui(half %a) nounwind {
59; RV64IZFH-LABEL: aext_fptoui:
60; RV64IZFH:       # %bb.0:
61; RV64IZFH-NEXT:    fcvt.wu.h a0, fa0, rtz
62; RV64IZFH-NEXT:    ret
63;
64; RV64IZHINX-LABEL: aext_fptoui:
65; RV64IZHINX:       # %bb.0:
66; RV64IZHINX-NEXT:    fcvt.wu.h a0, a0, rtz
67; RV64IZHINX-NEXT:    ret
68  %1 = fptoui half %a to i32
69  ret i32 %1
70}
71
72define signext i32 @sext_fptoui(half %a) nounwind {
73; RV64IZFH-LABEL: sext_fptoui:
74; RV64IZFH:       # %bb.0:
75; RV64IZFH-NEXT:    fcvt.wu.h a0, fa0, rtz
76; RV64IZFH-NEXT:    ret
77;
78; RV64IZHINX-LABEL: sext_fptoui:
79; RV64IZHINX:       # %bb.0:
80; RV64IZHINX-NEXT:    fcvt.wu.h a0, a0, rtz
81; RV64IZHINX-NEXT:    ret
82  %1 = fptoui half %a to i32
83  ret i32 %1
84}
85
86define zeroext i32 @zext_fptoui(half %a) nounwind {
87; RV64IZFH-LABEL: zext_fptoui:
88; RV64IZFH:       # %bb.0:
89; RV64IZFH-NEXT:    fcvt.lu.h a0, fa0, rtz
90; RV64IZFH-NEXT:    ret
91;
92; RV64IZHINX-LABEL: zext_fptoui:
93; RV64IZHINX:       # %bb.0:
94; RV64IZHINX-NEXT:    fcvt.lu.h a0, a0, rtz
95; RV64IZHINX-NEXT:    ret
96  %1 = fptoui half %a to i32
97  ret i32 %1
98}
99
100define i16 @bcvt_f16_to_aext_i16(half %a, half %b) nounwind {
101; RV64IZFH-LABEL: bcvt_f16_to_aext_i16:
102; RV64IZFH:       # %bb.0:
103; RV64IZFH-NEXT:    fadd.h fa5, fa0, fa1
104; RV64IZFH-NEXT:    fmv.x.h a0, fa5
105; RV64IZFH-NEXT:    ret
106;
107; RV64IZHINX-LABEL: bcvt_f16_to_aext_i16:
108; RV64IZHINX:       # %bb.0:
109; RV64IZHINX-NEXT:    fadd.h a0, a0, a1
110; RV64IZHINX-NEXT:    ret
111  %1 = fadd half %a, %b
112  %2 = bitcast half %1 to i16
113  ret i16 %2
114}
115
116define signext i16 @bcvt_f16_to_sext_i16(half %a, half %b) nounwind {
117; RV64IZFH-LABEL: bcvt_f16_to_sext_i16:
118; RV64IZFH:       # %bb.0:
119; RV64IZFH-NEXT:    fadd.h fa5, fa0, fa1
120; RV64IZFH-NEXT:    fmv.x.h a0, fa5
121; RV64IZFH-NEXT:    ret
122;
123; RV64IZHINX-LABEL: bcvt_f16_to_sext_i16:
124; RV64IZHINX:       # %bb.0:
125; RV64IZHINX-NEXT:    fadd.h a0, a0, a1
126; RV64IZHINX-NEXT:    slli a0, a0, 48
127; RV64IZHINX-NEXT:    srai a0, a0, 48
128; RV64IZHINX-NEXT:    ret
129  %1 = fadd half %a, %b
130  %2 = bitcast half %1 to i16
131  ret i16 %2
132}
133
134define zeroext i16 @bcvt_f16_to_zext_i16(half %a, half %b) nounwind {
135; RV64IZFH-LABEL: bcvt_f16_to_zext_i16:
136; RV64IZFH:       # %bb.0:
137; RV64IZFH-NEXT:    fadd.h fa5, fa0, fa1
138; RV64IZFH-NEXT:    fmv.x.h a0, fa5
139; RV64IZFH-NEXT:    slli a0, a0, 48
140; RV64IZFH-NEXT:    srli a0, a0, 48
141; RV64IZFH-NEXT:    ret
142;
143; RV64IZHINX-LABEL: bcvt_f16_to_zext_i16:
144; RV64IZHINX:       # %bb.0:
145; RV64IZHINX-NEXT:    fadd.h a0, a0, a1
146; RV64IZHINX-NEXT:    slli a0, a0, 48
147; RV64IZHINX-NEXT:    srli a0, a0, 48
148; RV64IZHINX-NEXT:    ret
149  %1 = fadd half %a, %b
150  %2 = bitcast half %1 to i16
151  ret i16 %2
152}
153
154define half @bcvt_i64_to_f16_via_i16(i64 %a, i64 %b) nounwind {
155; RV64IZFH-LABEL: bcvt_i64_to_f16_via_i16:
156; RV64IZFH:       # %bb.0:
157; RV64IZFH-NEXT:    fmv.h.x fa5, a0
158; RV64IZFH-NEXT:    fmv.h.x fa4, a1
159; RV64IZFH-NEXT:    fadd.h fa0, fa5, fa4
160; RV64IZFH-NEXT:    ret
161;
162; RV64IZHINX-LABEL: bcvt_i64_to_f16_via_i16:
163; RV64IZHINX:       # %bb.0:
164; RV64IZHINX-NEXT:    fadd.h a0, a0, a1
165; RV64IZHINX-NEXT:    ret
166  %1 = trunc i64 %a to i16
167  %2 = trunc i64 %b to i16
168  %3 = bitcast i16 %1 to half
169  %4 = bitcast i16 %2 to half
170  %5 = fadd half %3, %4
171  ret half %5
172}
173
174define half @uitofp_aext_i32_to_f16(i32 %a) nounwind {
175; RV64IZFH-LABEL: uitofp_aext_i32_to_f16:
176; RV64IZFH:       # %bb.0:
177; RV64IZFH-NEXT:    fcvt.h.wu fa0, a0
178; RV64IZFH-NEXT:    ret
179;
180; RV64IZHINX-LABEL: uitofp_aext_i32_to_f16:
181; RV64IZHINX:       # %bb.0:
182; RV64IZHINX-NEXT:    fcvt.h.wu a0, a0
183; RV64IZHINX-NEXT:    ret
184  %1 = uitofp i32 %a to half
185  ret half %1
186}
187
188define half @uitofp_sext_i32_to_f16(i32 signext %a) nounwind {
189; RV64IZFH-LABEL: uitofp_sext_i32_to_f16:
190; RV64IZFH:       # %bb.0:
191; RV64IZFH-NEXT:    fcvt.h.wu fa0, a0
192; RV64IZFH-NEXT:    ret
193;
194; RV64IZHINX-LABEL: uitofp_sext_i32_to_f16:
195; RV64IZHINX:       # %bb.0:
196; RV64IZHINX-NEXT:    fcvt.h.wu a0, a0
197; RV64IZHINX-NEXT:    ret
198  %1 = uitofp i32 %a to half
199  ret half %1
200}
201
202define half @uitofp_zext_i32_to_f16(i32 zeroext %a) nounwind {
203; RV64IZFH-LABEL: uitofp_zext_i32_to_f16:
204; RV64IZFH:       # %bb.0:
205; RV64IZFH-NEXT:    fcvt.h.wu fa0, a0
206; RV64IZFH-NEXT:    ret
207;
208; RV64IZHINX-LABEL: uitofp_zext_i32_to_f16:
209; RV64IZHINX:       # %bb.0:
210; RV64IZHINX-NEXT:    fcvt.h.wu a0, a0
211; RV64IZHINX-NEXT:    ret
212  %1 = uitofp i32 %a to half
213  ret half %1
214}
215
216define half @sitofp_aext_i32_to_f16(i32 %a) nounwind {
217; RV64IZFH-LABEL: sitofp_aext_i32_to_f16:
218; RV64IZFH:       # %bb.0:
219; RV64IZFH-NEXT:    fcvt.h.w fa0, a0
220; RV64IZFH-NEXT:    ret
221;
222; RV64IZHINX-LABEL: sitofp_aext_i32_to_f16:
223; RV64IZHINX:       # %bb.0:
224; RV64IZHINX-NEXT:    fcvt.h.w a0, a0
225; RV64IZHINX-NEXT:    ret
226  %1 = sitofp i32 %a to half
227  ret half %1
228}
229
230define half @sitofp_sext_i32_to_f16(i32 signext %a) nounwind {
231; RV64IZFH-LABEL: sitofp_sext_i32_to_f16:
232; RV64IZFH:       # %bb.0:
233; RV64IZFH-NEXT:    fcvt.h.w fa0, a0
234; RV64IZFH-NEXT:    ret
235;
236; RV64IZHINX-LABEL: sitofp_sext_i32_to_f16:
237; RV64IZHINX:       # %bb.0:
238; RV64IZHINX-NEXT:    fcvt.h.w a0, a0
239; RV64IZHINX-NEXT:    ret
240  %1 = sitofp i32 %a to half
241  ret half %1
242}
243
244define half @sitofp_zext_i32_to_f16(i32 zeroext %a) nounwind {
245; RV64IZFH-LABEL: sitofp_zext_i32_to_f16:
246; RV64IZFH:       # %bb.0:
247; RV64IZFH-NEXT:    fcvt.h.w fa0, a0
248; RV64IZFH-NEXT:    ret
249;
250; RV64IZHINX-LABEL: sitofp_zext_i32_to_f16:
251; RV64IZHINX:       # %bb.0:
252; RV64IZHINX-NEXT:    fcvt.h.w a0, a0
253; RV64IZHINX-NEXT:    ret
254  %1 = sitofp i32 %a to half
255  ret half %1
256}
257