1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK,CHECK-CVT
3 ; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-FP16
5 ; Round towards minus infinity (fcvtms).
7 define i32 @testmswh(half %a) {
8 ; CHECK-CVT-LABEL: testmswh:
9 ; CHECK-CVT: // %bb.0: // %entry
10 ; CHECK-CVT-NEXT: fcvt s0, h0
11 ; CHECK-CVT-NEXT: frintm s0, s0
12 ; CHECK-CVT-NEXT: fcvt h0, s0
13 ; CHECK-CVT-NEXT: fcvt s0, h0
14 ; CHECK-CVT-NEXT: fcvtzs w0, s0
17 ; CHECK-FP16-LABEL: testmswh:
18 ; CHECK-FP16: // %bb.0: // %entry
19 ; CHECK-FP16-NEXT: fcvtms w0, h0
20 ; CHECK-FP16-NEXT: ret
22 %r = call half @llvm.floor.f16(half %a) nounwind readnone
23 %i = call i32 @llvm.fptosi.sat.i32.f16(half %r)
27 define i64 @testmsxh(half %a) {
28 ; CHECK-CVT-LABEL: testmsxh:
29 ; CHECK-CVT: // %bb.0: // %entry
30 ; CHECK-CVT-NEXT: fcvt s0, h0
31 ; CHECK-CVT-NEXT: frintm s0, s0
32 ; CHECK-CVT-NEXT: fcvt h0, s0
33 ; CHECK-CVT-NEXT: fcvt s0, h0
34 ; CHECK-CVT-NEXT: fcvtzs x0, s0
37 ; CHECK-FP16-LABEL: testmsxh:
38 ; CHECK-FP16: // %bb.0: // %entry
39 ; CHECK-FP16-NEXT: fcvtms x0, h0
40 ; CHECK-FP16-NEXT: ret
42 %r = call half @llvm.floor.f16(half %a) nounwind readnone
43 %i = call i64 @llvm.fptosi.sat.i64.f16(half %r)
47 define i32 @testmsws(float %a) {
48 ; CHECK-LABEL: testmsws:
49 ; CHECK: // %bb.0: // %entry
50 ; CHECK-NEXT: fcvtms w0, s0
53 %r = call float @floorf(float %a) nounwind readnone
54 %i = call i32 @llvm.fptosi.sat.i32.f32(float %r)
58 define i64 @testmsxs(float %a) {
59 ; CHECK-LABEL: testmsxs:
60 ; CHECK: // %bb.0: // %entry
61 ; CHECK-NEXT: fcvtms x0, s0
64 %r = call float @floorf(float %a) nounwind readnone
65 %i = call i64 @llvm.fptosi.sat.i64.f32(float %r)
69 define i32 @testmswd(double %a) {
70 ; CHECK-LABEL: testmswd:
71 ; CHECK: // %bb.0: // %entry
72 ; CHECK-NEXT: fcvtms w0, d0
75 %r = call double @floor(double %a) nounwind readnone
76 %i = call i32 @llvm.fptosi.sat.i32.f64(double %r)
80 define i64 @testmsxd(double %a) {
81 ; CHECK-LABEL: testmsxd:
82 ; CHECK: // %bb.0: // %entry
83 ; CHECK-NEXT: fcvtms x0, d0
86 %r = call double @floor(double %a) nounwind readnone
87 %i = call i64 @llvm.fptosi.sat.i64.f64(double %r)
91 ; Round towards plus infinity (fcvtps).
93 define i32 @testpswh(half %a) {
94 ; CHECK-CVT-LABEL: testpswh:
95 ; CHECK-CVT: // %bb.0: // %entry
96 ; CHECK-CVT-NEXT: fcvt s0, h0
97 ; CHECK-CVT-NEXT: frintp s0, s0
98 ; CHECK-CVT-NEXT: fcvt h0, s0
99 ; CHECK-CVT-NEXT: fcvt s0, h0
100 ; CHECK-CVT-NEXT: fcvtzs w0, s0
101 ; CHECK-CVT-NEXT: ret
103 ; CHECK-FP16-LABEL: testpswh:
104 ; CHECK-FP16: // %bb.0: // %entry
105 ; CHECK-FP16-NEXT: fcvtps w0, h0
106 ; CHECK-FP16-NEXT: ret
108 %r = call half @llvm.ceil.f16(half %a) nounwind readnone
109 %i = call i32 @llvm.fptosi.sat.i32.f16(half %r)
113 define i64 @testpsxh(half %a) {
114 ; CHECK-CVT-LABEL: testpsxh:
115 ; CHECK-CVT: // %bb.0: // %entry
116 ; CHECK-CVT-NEXT: fcvt s0, h0
117 ; CHECK-CVT-NEXT: frintp s0, s0
118 ; CHECK-CVT-NEXT: fcvt h0, s0
119 ; CHECK-CVT-NEXT: fcvt s0, h0
120 ; CHECK-CVT-NEXT: fcvtzs x0, s0
121 ; CHECK-CVT-NEXT: ret
123 ; CHECK-FP16-LABEL: testpsxh:
124 ; CHECK-FP16: // %bb.0: // %entry
125 ; CHECK-FP16-NEXT: fcvtps x0, h0
126 ; CHECK-FP16-NEXT: ret
128 %r = call half @llvm.ceil.f16(half %a) nounwind readnone
129 %i = call i64 @llvm.fptosi.sat.i64.f16(half %r)
133 define i32 @testpsws(float %a) {
134 ; CHECK-LABEL: testpsws:
135 ; CHECK: // %bb.0: // %entry
136 ; CHECK-NEXT: fcvtps w0, s0
139 %r = call float @ceilf(float %a) nounwind readnone
140 %i = call i32 @llvm.fptosi.sat.i32.f32(float %r)
144 define i64 @testpsxs(float %a) {
145 ; CHECK-LABEL: testpsxs:
146 ; CHECK: // %bb.0: // %entry
147 ; CHECK-NEXT: fcvtps x0, s0
150 %r = call float @ceilf(float %a) nounwind readnone
151 %i = call i64 @llvm.fptosi.sat.i64.f32(float %r)
155 define i32 @testpswd(double %a) {
156 ; CHECK-LABEL: testpswd:
157 ; CHECK: // %bb.0: // %entry
158 ; CHECK-NEXT: fcvtps w0, d0
161 %r = call double @ceil(double %a) nounwind readnone
162 %i = call i32 @llvm.fptosi.sat.i32.f64(double %r)
166 define i64 @testpsxd(double %a) {
167 ; CHECK-LABEL: testpsxd:
168 ; CHECK: // %bb.0: // %entry
169 ; CHECK-NEXT: fcvtps x0, d0
172 %r = call double @ceil(double %a) nounwind readnone
173 %i = call i64 @llvm.fptosi.sat.i64.f64(double %r)
177 ; Round towards zero (fcvtzs).
179 define i32 @testzswh(half %a) {
180 ; CHECK-CVT-LABEL: testzswh:
181 ; CHECK-CVT: // %bb.0: // %entry
182 ; CHECK-CVT-NEXT: fcvt s0, h0
183 ; CHECK-CVT-NEXT: frintz s0, s0
184 ; CHECK-CVT-NEXT: fcvt h0, s0
185 ; CHECK-CVT-NEXT: fcvt s0, h0
186 ; CHECK-CVT-NEXT: fcvtzs w0, s0
187 ; CHECK-CVT-NEXT: ret
189 ; CHECK-FP16-LABEL: testzswh:
190 ; CHECK-FP16: // %bb.0: // %entry
191 ; CHECK-FP16-NEXT: fcvtzs w0, h0
192 ; CHECK-FP16-NEXT: ret
194 %r = call half @llvm.trunc.f16(half %a) nounwind readnone
195 %i = call i32 @llvm.fptosi.sat.i32.f16(half %r)
199 define i64 @testzsxh(half %a) {
200 ; CHECK-CVT-LABEL: testzsxh:
201 ; CHECK-CVT: // %bb.0: // %entry
202 ; CHECK-CVT-NEXT: fcvt s0, h0
203 ; CHECK-CVT-NEXT: frintz s0, s0
204 ; CHECK-CVT-NEXT: fcvt h0, s0
205 ; CHECK-CVT-NEXT: fcvt s0, h0
206 ; CHECK-CVT-NEXT: fcvtzs x0, s0
207 ; CHECK-CVT-NEXT: ret
209 ; CHECK-FP16-LABEL: testzsxh:
210 ; CHECK-FP16: // %bb.0: // %entry
211 ; CHECK-FP16-NEXT: fcvtzs x0, h0
212 ; CHECK-FP16-NEXT: ret
214 %r = call half @llvm.trunc.f16(half %a) nounwind readnone
215 %i = call i64 @llvm.fptosi.sat.i64.f16(half %r)
219 define i32 @testzsws(float %a) {
220 ; CHECK-LABEL: testzsws:
221 ; CHECK: // %bb.0: // %entry
222 ; CHECK-NEXT: fcvtzs w0, s0
225 %r = call float @truncf(float %a) nounwind readnone
226 %i = call i32 @llvm.fptosi.sat.i32.f32(float %r)
230 define i64 @testzsxs(float %a) {
231 ; CHECK-LABEL: testzsxs:
232 ; CHECK: // %bb.0: // %entry
233 ; CHECK-NEXT: fcvtzs x0, s0
236 %r = call float @truncf(float %a) nounwind readnone
237 %i = call i64 @llvm.fptosi.sat.i64.f32(float %r)
241 define i32 @testzswd(double %a) {
242 ; CHECK-LABEL: testzswd:
243 ; CHECK: // %bb.0: // %entry
244 ; CHECK-NEXT: fcvtzs w0, d0
247 %r = call double @trunc(double %a) nounwind readnone
248 %i = call i32 @llvm.fptosi.sat.i32.f64(double %r)
252 define i64 @testzsxd(double %a) {
253 ; CHECK-LABEL: testzsxd:
254 ; CHECK: // %bb.0: // %entry
255 ; CHECK-NEXT: fcvtzs x0, d0
258 %r = call double @trunc(double %a) nounwind readnone
259 %i = call i64 @llvm.fptosi.sat.i64.f64(double %r)
263 ; Round to nearest, ties away from zero (fcvtas).
265 define i32 @testaswh(half %a) {
266 ; CHECK-CVT-LABEL: testaswh:
267 ; CHECK-CVT: // %bb.0: // %entry
268 ; CHECK-CVT-NEXT: fcvt s0, h0
269 ; CHECK-CVT-NEXT: frinta s0, s0
270 ; CHECK-CVT-NEXT: fcvt h0, s0
271 ; CHECK-CVT-NEXT: fcvt s0, h0
272 ; CHECK-CVT-NEXT: fcvtzs w0, s0
273 ; CHECK-CVT-NEXT: ret
275 ; CHECK-FP16-LABEL: testaswh:
276 ; CHECK-FP16: // %bb.0: // %entry
277 ; CHECK-FP16-NEXT: fcvtas w0, h0
278 ; CHECK-FP16-NEXT: ret
280 %r = call half @llvm.round.f16(half %a) nounwind readnone
281 %i = call i32 @llvm.fptosi.sat.i32.f16(half %r)
285 define i64 @testasxh(half %a) {
286 ; CHECK-CVT-LABEL: testasxh:
287 ; CHECK-CVT: // %bb.0: // %entry
288 ; CHECK-CVT-NEXT: fcvt s0, h0
289 ; CHECK-CVT-NEXT: frinta s0, s0
290 ; CHECK-CVT-NEXT: fcvt h0, s0
291 ; CHECK-CVT-NEXT: fcvt s0, h0
292 ; CHECK-CVT-NEXT: fcvtzs x0, s0
293 ; CHECK-CVT-NEXT: ret
295 ; CHECK-FP16-LABEL: testasxh:
296 ; CHECK-FP16: // %bb.0: // %entry
297 ; CHECK-FP16-NEXT: fcvtas x0, h0
298 ; CHECK-FP16-NEXT: ret
300 %r = call half @llvm.round.f16(half %a) nounwind readnone
301 %i = call i64 @llvm.fptosi.sat.i64.f16(half %r)
305 define i32 @testasws(float %a) {
306 ; CHECK-LABEL: testasws:
307 ; CHECK: // %bb.0: // %entry
308 ; CHECK-NEXT: fcvtas w0, s0
311 %r = call float @roundf(float %a) nounwind readnone
312 %i = call i32 @llvm.fptosi.sat.i32.f32(float %r)
316 define i64 @testasxs(float %a) {
317 ; CHECK-LABEL: testasxs:
318 ; CHECK: // %bb.0: // %entry
319 ; CHECK-NEXT: fcvtas x0, s0
322 %r = call float @roundf(float %a) nounwind readnone
323 %i = call i64 @llvm.fptosi.sat.i64.f32(float %r)
327 define i32 @testaswd(double %a) {
328 ; CHECK-LABEL: testaswd:
329 ; CHECK: // %bb.0: // %entry
330 ; CHECK-NEXT: fcvtas w0, d0
333 %r = call double @round(double %a) nounwind readnone
334 %i = call i32 @llvm.fptosi.sat.i32.f64(double %r)
338 define i64 @testasxd(double %a) {
339 ; CHECK-LABEL: testasxd:
340 ; CHECK: // %bb.0: // %entry
341 ; CHECK-NEXT: fcvtas x0, d0
344 %r = call double @round(double %a) nounwind readnone
345 %i = call i64 @llvm.fptosi.sat.i64.f64(double %r)
349 declare i32 @llvm.fptosi.sat.i32.f16 (half)
350 declare i64 @llvm.fptosi.sat.i64.f16 (half)
351 declare i32 @llvm.fptosi.sat.i32.f32 (float)
352 declare i64 @llvm.fptosi.sat.i64.f32 (float)
353 declare i32 @llvm.fptosi.sat.i32.f64 (double)
354 declare i64 @llvm.fptosi.sat.i64.f64 (double)
356 declare half @llvm.floor.f16(half) nounwind readnone
357 declare half @llvm.ceil.f16(half) nounwind readnone
358 declare half @llvm.trunc.f16(half) nounwind readnone
359 declare half @llvm.round.f16(half) nounwind readnone
360 declare float @floorf(float) nounwind readnone
361 declare float @ceilf(float) nounwind readnone
362 declare float @truncf(float) nounwind readnone
363 declare float @roundf(float) nounwind readnone
364 declare double @floor(double) nounwind readnone
365 declare double @ceil(double) nounwind readnone
366 declare double @trunc(double) nounwind readnone
367 declare double @round(double) nounwind readnone