xref: /llvm-project/llvm/test/CodeGen/RISCV/rv64zfh-half-convert-strict.ll (revision 95c2d01dfedc2bc97e1264d212da39154da015d1)
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 -disable-strictnode-mutation < %s | \
4; RUN:   FileCheck %s -check-prefix=RV64IZFH
5; RUN: llc -mtriple=riscv64 -mattr=+zhinx -verify-machineinstrs \
6; RUN:   -target-abi lp64 -disable-strictnode-mutation < %s | \
7; RUN:   FileCheck %s -check-prefix=RV64IZHINX
8
9; This file exhaustively checks half<->i32 conversions. In general,
10; fcvt.l[u].h can be selected instead of fcvt.w[u].h because poison is
11; generated for an fpto[s|u]i conversion if the result doesn't fit in the
12; target type.
13
14define i32 @aext_fptosi(half %a) nounwind strictfp {
15; RV64IZFH-LABEL: aext_fptosi:
16; RV64IZFH:       # %bb.0:
17; RV64IZFH-NEXT:    fcvt.w.h a0, fa0, rtz
18; RV64IZFH-NEXT:    ret
19;
20; RV64IZHINX-LABEL: aext_fptosi:
21; RV64IZHINX:       # %bb.0:
22; RV64IZHINX-NEXT:    fcvt.w.h a0, a0, rtz
23; RV64IZHINX-NEXT:    ret
24  %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict")
25  ret i32 %1
26}
27declare i32 @llvm.experimental.constrained.fptosi.i32.f16(half, metadata)
28
29define signext i32 @sext_fptosi(half %a) nounwind strictfp {
30; RV64IZFH-LABEL: sext_fptosi:
31; RV64IZFH:       # %bb.0:
32; RV64IZFH-NEXT:    fcvt.w.h a0, fa0, rtz
33; RV64IZFH-NEXT:    ret
34;
35; RV64IZHINX-LABEL: sext_fptosi:
36; RV64IZHINX:       # %bb.0:
37; RV64IZHINX-NEXT:    fcvt.w.h a0, a0, rtz
38; RV64IZHINX-NEXT:    ret
39  %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict")
40  ret i32 %1
41}
42
43define zeroext i32 @zext_fptosi(half %a) nounwind strictfp {
44; RV64IZFH-LABEL: zext_fptosi:
45; RV64IZFH:       # %bb.0:
46; RV64IZFH-NEXT:    fcvt.w.h a0, fa0, rtz
47; RV64IZFH-NEXT:    slli a0, a0, 32
48; RV64IZFH-NEXT:    srli a0, a0, 32
49; RV64IZFH-NEXT:    ret
50;
51; RV64IZHINX-LABEL: zext_fptosi:
52; RV64IZHINX:       # %bb.0:
53; RV64IZHINX-NEXT:    fcvt.w.h a0, a0, rtz
54; RV64IZHINX-NEXT:    slli a0, a0, 32
55; RV64IZHINX-NEXT:    srli a0, a0, 32
56; RV64IZHINX-NEXT:    ret
57  %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict")
58  ret i32 %1
59}
60
61define i32 @aext_fptoui(half %a) nounwind strictfp {
62; RV64IZFH-LABEL: aext_fptoui:
63; RV64IZFH:       # %bb.0:
64; RV64IZFH-NEXT:    fcvt.wu.h a0, fa0, rtz
65; RV64IZFH-NEXT:    ret
66;
67; RV64IZHINX-LABEL: aext_fptoui:
68; RV64IZHINX:       # %bb.0:
69; RV64IZHINX-NEXT:    fcvt.wu.h a0, a0, rtz
70; RV64IZHINX-NEXT:    ret
71  %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict")
72  ret i32 %1
73}
74declare i32 @llvm.experimental.constrained.fptoui.i32.f16(half, metadata)
75
76define signext i32 @sext_fptoui(half %a) nounwind strictfp {
77; RV64IZFH-LABEL: sext_fptoui:
78; RV64IZFH:       # %bb.0:
79; RV64IZFH-NEXT:    fcvt.wu.h a0, fa0, rtz
80; RV64IZFH-NEXT:    ret
81;
82; RV64IZHINX-LABEL: sext_fptoui:
83; RV64IZHINX:       # %bb.0:
84; RV64IZHINX-NEXT:    fcvt.wu.h a0, a0, rtz
85; RV64IZHINX-NEXT:    ret
86  %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict")
87  ret i32 %1
88}
89
90define zeroext i32 @zext_fptoui(half %a) nounwind strictfp {
91; RV64IZFH-LABEL: zext_fptoui:
92; RV64IZFH:       # %bb.0:
93; RV64IZFH-NEXT:    fcvt.lu.h a0, fa0, rtz
94; RV64IZFH-NEXT:    ret
95;
96; RV64IZHINX-LABEL: zext_fptoui:
97; RV64IZHINX:       # %bb.0:
98; RV64IZHINX-NEXT:    fcvt.lu.h a0, a0, rtz
99; RV64IZHINX-NEXT:    ret
100  %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict")
101  ret i32 %1
102}
103
104define half @uitofp_aext_i32_to_f16(i32 %a) nounwind strictfp {
105; RV64IZFH-LABEL: uitofp_aext_i32_to_f16:
106; RV64IZFH:       # %bb.0:
107; RV64IZFH-NEXT:    fcvt.h.wu fa0, a0
108; RV64IZFH-NEXT:    ret
109;
110; RV64IZHINX-LABEL: uitofp_aext_i32_to_f16:
111; RV64IZHINX:       # %bb.0:
112; RV64IZHINX-NEXT:    fcvt.h.wu a0, a0
113; RV64IZHINX-NEXT:    ret
114  %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
115  ret half %1
116}
117declare half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata, metadata)
118
119define half @uitofp_sext_i32_to_f16(i32 signext %a) nounwind strictfp {
120; RV64IZFH-LABEL: uitofp_sext_i32_to_f16:
121; RV64IZFH:       # %bb.0:
122; RV64IZFH-NEXT:    fcvt.h.wu fa0, a0
123; RV64IZFH-NEXT:    ret
124;
125; RV64IZHINX-LABEL: uitofp_sext_i32_to_f16:
126; RV64IZHINX:       # %bb.0:
127; RV64IZHINX-NEXT:    fcvt.h.wu a0, a0
128; RV64IZHINX-NEXT:    ret
129  %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
130  ret half %1
131}
132
133define half @uitofp_zext_i32_to_f16(i32 zeroext %a) nounwind strictfp {
134; RV64IZFH-LABEL: uitofp_zext_i32_to_f16:
135; RV64IZFH:       # %bb.0:
136; RV64IZFH-NEXT:    fcvt.h.wu fa0, a0
137; RV64IZFH-NEXT:    ret
138;
139; RV64IZHINX-LABEL: uitofp_zext_i32_to_f16:
140; RV64IZHINX:       # %bb.0:
141; RV64IZHINX-NEXT:    fcvt.h.wu a0, a0
142; RV64IZHINX-NEXT:    ret
143  %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
144  ret half %1
145}
146
147define half @sitofp_aext_i32_to_f16(i32 %a) nounwind strictfp {
148; RV64IZFH-LABEL: sitofp_aext_i32_to_f16:
149; RV64IZFH:       # %bb.0:
150; RV64IZFH-NEXT:    fcvt.h.w fa0, a0
151; RV64IZFH-NEXT:    ret
152;
153; RV64IZHINX-LABEL: sitofp_aext_i32_to_f16:
154; RV64IZHINX:       # %bb.0:
155; RV64IZHINX-NEXT:    fcvt.h.w a0, a0
156; RV64IZHINX-NEXT:    ret
157  %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
158  ret half %1
159}
160declare half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata, metadata)
161
162define half @sitofp_sext_i32_to_f16(i32 signext %a) nounwind strictfp {
163; RV64IZFH-LABEL: sitofp_sext_i32_to_f16:
164; RV64IZFH:       # %bb.0:
165; RV64IZFH-NEXT:    fcvt.h.w fa0, a0
166; RV64IZFH-NEXT:    ret
167;
168; RV64IZHINX-LABEL: sitofp_sext_i32_to_f16:
169; RV64IZHINX:       # %bb.0:
170; RV64IZHINX-NEXT:    fcvt.h.w a0, a0
171; RV64IZHINX-NEXT:    ret
172  %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
173  ret half %1
174}
175
176define half @sitofp_zext_i32_to_f16(i32 zeroext %a) nounwind strictfp {
177; RV64IZFH-LABEL: sitofp_zext_i32_to_f16:
178; RV64IZFH:       # %bb.0:
179; RV64IZFH-NEXT:    fcvt.h.w fa0, a0
180; RV64IZFH-NEXT:    ret
181;
182; RV64IZHINX-LABEL: sitofp_zext_i32_to_f16:
183; RV64IZHINX:       # %bb.0:
184; RV64IZHINX-NEXT:    fcvt.h.w a0, a0
185; RV64IZHINX-NEXT:    ret
186  %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
187  ret half %1
188}
189