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