1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv64 -mattr=+zfhmin -verify-machineinstrs \
3 ; RUN: -target-abi lp64f -disable-strictnode-mutation < %s | \
4 ; RUN: FileCheck %s -check-prefix=RV64IZFHMIN
5 ; RUN: llc -mtriple=riscv64 -mattr=+zhinxmin -verify-machineinstrs \
6 ; RUN: -target-abi lp64 -disable-strictnode-mutation < %s | \
7 ; RUN: FileCheck %s -check-prefix=RV64IZHINXMIN
9 ; This file exhaustively checks half<->i32 conversions.
11 define i32 @aext_fptosi(half %a) nounwind strictfp {
12 ; RV64IZFHMIN-LABEL: aext_fptosi:
13 ; RV64IZFHMIN: # %bb.0:
14 ; RV64IZFHMIN-NEXT: fcvt.s.h fa5, fa0
15 ; RV64IZFHMIN-NEXT: fcvt.w.s a0, fa5, rtz
16 ; RV64IZFHMIN-NEXT: ret
18 ; RV64IZHINXMIN-LABEL: aext_fptosi:
19 ; RV64IZHINXMIN: # %bb.0:
20 ; RV64IZHINXMIN-NEXT: fcvt.s.h a0, a0
21 ; RV64IZHINXMIN-NEXT: fcvt.w.s a0, a0, rtz
22 ; RV64IZHINXMIN-NEXT: ret
23 %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict")
26 declare i32 @llvm.experimental.constrained.fptosi.i32.f16(half, metadata)
28 define signext i32 @sext_fptosi(half %a) nounwind strictfp {
29 ; RV64IZFHMIN-LABEL: sext_fptosi:
30 ; RV64IZFHMIN: # %bb.0:
31 ; RV64IZFHMIN-NEXT: fcvt.s.h fa5, fa0
32 ; RV64IZFHMIN-NEXT: fcvt.w.s a0, fa5, rtz
33 ; RV64IZFHMIN-NEXT: ret
35 ; RV64IZHINXMIN-LABEL: sext_fptosi:
36 ; RV64IZHINXMIN: # %bb.0:
37 ; RV64IZHINXMIN-NEXT: fcvt.s.h a0, a0
38 ; RV64IZHINXMIN-NEXT: fcvt.w.s a0, a0, rtz
39 ; RV64IZHINXMIN-NEXT: ret
40 %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict")
44 define zeroext i32 @zext_fptosi(half %a) nounwind strictfp {
45 ; RV64IZFHMIN-LABEL: zext_fptosi:
46 ; RV64IZFHMIN: # %bb.0:
47 ; RV64IZFHMIN-NEXT: fcvt.s.h fa5, fa0
48 ; RV64IZFHMIN-NEXT: fcvt.w.s a0, fa5, rtz
49 ; RV64IZFHMIN-NEXT: slli a0, a0, 32
50 ; RV64IZFHMIN-NEXT: srli a0, a0, 32
51 ; RV64IZFHMIN-NEXT: ret
53 ; RV64IZHINXMIN-LABEL: zext_fptosi:
54 ; RV64IZHINXMIN: # %bb.0:
55 ; RV64IZHINXMIN-NEXT: fcvt.s.h a0, a0
56 ; RV64IZHINXMIN-NEXT: fcvt.w.s a0, a0, rtz
57 ; RV64IZHINXMIN-NEXT: slli a0, a0, 32
58 ; RV64IZHINXMIN-NEXT: srli a0, a0, 32
59 ; RV64IZHINXMIN-NEXT: ret
60 %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict")
64 define i32 @aext_fptoui(half %a) nounwind strictfp {
65 ; RV64IZFHMIN-LABEL: aext_fptoui:
66 ; RV64IZFHMIN: # %bb.0:
67 ; RV64IZFHMIN-NEXT: fcvt.s.h fa5, fa0
68 ; RV64IZFHMIN-NEXT: fcvt.wu.s a0, fa5, rtz
69 ; RV64IZFHMIN-NEXT: ret
71 ; RV64IZHINXMIN-LABEL: aext_fptoui:
72 ; RV64IZHINXMIN: # %bb.0:
73 ; RV64IZHINXMIN-NEXT: fcvt.s.h a0, a0
74 ; RV64IZHINXMIN-NEXT: fcvt.wu.s a0, a0, rtz
75 ; RV64IZHINXMIN-NEXT: ret
76 %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict")
79 declare i32 @llvm.experimental.constrained.fptoui.i32.f16(half, metadata)
81 define signext i32 @sext_fptoui(half %a) nounwind strictfp {
82 ; RV64IZFHMIN-LABEL: sext_fptoui:
83 ; RV64IZFHMIN: # %bb.0:
84 ; RV64IZFHMIN-NEXT: fcvt.s.h fa5, fa0
85 ; RV64IZFHMIN-NEXT: fcvt.wu.s a0, fa5, rtz
86 ; RV64IZFHMIN-NEXT: ret
88 ; RV64IZHINXMIN-LABEL: sext_fptoui:
89 ; RV64IZHINXMIN: # %bb.0:
90 ; RV64IZHINXMIN-NEXT: fcvt.s.h a0, a0
91 ; RV64IZHINXMIN-NEXT: fcvt.wu.s a0, a0, rtz
92 ; RV64IZHINXMIN-NEXT: ret
93 %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict")
97 define zeroext i32 @zext_fptoui(half %a) nounwind strictfp {
98 ; RV64IZFHMIN-LABEL: zext_fptoui:
99 ; RV64IZFHMIN: # %bb.0:
100 ; RV64IZFHMIN-NEXT: fcvt.s.h fa5, fa0
101 ; RV64IZFHMIN-NEXT: fcvt.lu.s a0, fa5, rtz
102 ; RV64IZFHMIN-NEXT: ret
104 ; RV64IZHINXMIN-LABEL: zext_fptoui:
105 ; RV64IZHINXMIN: # %bb.0:
106 ; RV64IZHINXMIN-NEXT: fcvt.s.h a0, a0
107 ; RV64IZHINXMIN-NEXT: fcvt.lu.s a0, a0, rtz
108 ; RV64IZHINXMIN-NEXT: ret
109 %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict")
113 define half @uitofp_aext_i32_to_f16(i32 %a) nounwind strictfp {
114 ; RV64IZFHMIN-LABEL: uitofp_aext_i32_to_f16:
115 ; RV64IZFHMIN: # %bb.0:
116 ; RV64IZFHMIN-NEXT: slli a0, a0, 32
117 ; RV64IZFHMIN-NEXT: srli a0, a0, 32
118 ; RV64IZFHMIN-NEXT: fcvt.s.lu fa5, a0
119 ; RV64IZFHMIN-NEXT: fcvt.h.s fa0, fa5
120 ; RV64IZFHMIN-NEXT: ret
122 ; RV64IZHINXMIN-LABEL: uitofp_aext_i32_to_f16:
123 ; RV64IZHINXMIN: # %bb.0:
124 ; RV64IZHINXMIN-NEXT: slli a0, a0, 32
125 ; RV64IZHINXMIN-NEXT: srli a0, a0, 32
126 ; RV64IZHINXMIN-NEXT: fcvt.s.lu a0, a0
127 ; RV64IZHINXMIN-NEXT: fcvt.h.s a0, a0
128 ; RV64IZHINXMIN-NEXT: ret
129 %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
132 declare half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata, metadata)
134 define half @uitofp_sext_i32_to_f16(i32 signext %a) nounwind strictfp {
135 ; RV64IZFHMIN-LABEL: uitofp_sext_i32_to_f16:
136 ; RV64IZFHMIN: # %bb.0:
137 ; RV64IZFHMIN-NEXT: slli a0, a0, 32
138 ; RV64IZFHMIN-NEXT: srli a0, a0, 32
139 ; RV64IZFHMIN-NEXT: fcvt.s.lu fa5, a0
140 ; RV64IZFHMIN-NEXT: fcvt.h.s fa0, fa5
141 ; RV64IZFHMIN-NEXT: ret
143 ; RV64IZHINXMIN-LABEL: uitofp_sext_i32_to_f16:
144 ; RV64IZHINXMIN: # %bb.0:
145 ; RV64IZHINXMIN-NEXT: slli a0, a0, 32
146 ; RV64IZHINXMIN-NEXT: srli a0, a0, 32
147 ; RV64IZHINXMIN-NEXT: fcvt.s.lu a0, a0
148 ; RV64IZHINXMIN-NEXT: fcvt.h.s a0, a0
149 ; RV64IZHINXMIN-NEXT: ret
150 %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
154 define half @uitofp_zext_i32_to_f16(i32 zeroext %a) nounwind strictfp {
155 ; RV64IZFHMIN-LABEL: uitofp_zext_i32_to_f16:
156 ; RV64IZFHMIN: # %bb.0:
157 ; RV64IZFHMIN-NEXT: fcvt.s.lu fa5, a0
158 ; RV64IZFHMIN-NEXT: fcvt.h.s fa0, fa5
159 ; RV64IZFHMIN-NEXT: ret
161 ; RV64IZHINXMIN-LABEL: uitofp_zext_i32_to_f16:
162 ; RV64IZHINXMIN: # %bb.0:
163 ; RV64IZHINXMIN-NEXT: fcvt.s.lu a0, a0
164 ; RV64IZHINXMIN-NEXT: fcvt.h.s a0, a0
165 ; RV64IZHINXMIN-NEXT: ret
166 %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
170 define half @sitofp_aext_i32_to_f16(i32 %a) nounwind strictfp {
171 ; RV64IZFHMIN-LABEL: sitofp_aext_i32_to_f16:
172 ; RV64IZFHMIN: # %bb.0:
173 ; RV64IZFHMIN-NEXT: sext.w a0, a0
174 ; RV64IZFHMIN-NEXT: fcvt.s.l fa5, a0
175 ; RV64IZFHMIN-NEXT: fcvt.h.s fa0, fa5
176 ; RV64IZFHMIN-NEXT: ret
178 ; RV64IZHINXMIN-LABEL: sitofp_aext_i32_to_f16:
179 ; RV64IZHINXMIN: # %bb.0:
180 ; RV64IZHINXMIN-NEXT: sext.w a0, a0
181 ; RV64IZHINXMIN-NEXT: fcvt.s.l a0, a0
182 ; RV64IZHINXMIN-NEXT: fcvt.h.s a0, a0
183 ; RV64IZHINXMIN-NEXT: ret
184 %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
187 declare half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata, metadata)
189 define half @sitofp_sext_i32_to_f16(i32 signext %a) nounwind strictfp {
190 ; RV64IZFHMIN-LABEL: sitofp_sext_i32_to_f16:
191 ; RV64IZFHMIN: # %bb.0:
192 ; RV64IZFHMIN-NEXT: fcvt.s.l fa5, a0
193 ; RV64IZFHMIN-NEXT: fcvt.h.s fa0, fa5
194 ; RV64IZFHMIN-NEXT: ret
196 ; RV64IZHINXMIN-LABEL: sitofp_sext_i32_to_f16:
197 ; RV64IZHINXMIN: # %bb.0:
198 ; RV64IZHINXMIN-NEXT: fcvt.s.l a0, a0
199 ; RV64IZHINXMIN-NEXT: fcvt.h.s a0, a0
200 ; RV64IZHINXMIN-NEXT: ret
201 %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
205 define half @sitofp_zext_i32_to_f16(i32 zeroext %a) nounwind strictfp {
206 ; RV64IZFHMIN-LABEL: sitofp_zext_i32_to_f16:
207 ; RV64IZFHMIN: # %bb.0:
208 ; RV64IZFHMIN-NEXT: sext.w a0, a0
209 ; RV64IZFHMIN-NEXT: fcvt.s.l fa5, a0
210 ; RV64IZFHMIN-NEXT: fcvt.h.s fa0, fa5
211 ; RV64IZFHMIN-NEXT: ret
213 ; RV64IZHINXMIN-LABEL: sitofp_zext_i32_to_f16:
214 ; RV64IZHINXMIN: # %bb.0:
215 ; RV64IZHINXMIN-NEXT: sext.w a0, a0
216 ; RV64IZHINXMIN-NEXT: fcvt.s.l a0, a0
217 ; RV64IZHINXMIN-NEXT: fcvt.h.s a0, a0
218 ; RV64IZHINXMIN-NEXT: ret
219 %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")