1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOFP16
3 ; RUN: llc -mtriple=aarch64 -mattr=+fullfp16 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-FP16
4 ; RUN: llc -mtriple=aarch64 -global-isel=true -global-isel-abort=2 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOFP16
5 ; RUN: llc -mtriple=aarch64 -global-isel=true -global-isel-abort=2 -mattr=+fullfp16 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-FP16
7 ; Check that constrained fp intrinsics are correctly lowered.
10 ; Half-precision intrinsics
12 define half @add_f16(half %x, half %y) #0 {
13 ; CHECK-NOFP16-LABEL: add_f16:
14 ; CHECK-NOFP16: // %bb.0:
15 ; CHECK-NOFP16-NEXT: fcvt s1, h1
16 ; CHECK-NOFP16-NEXT: fcvt s0, h0
17 ; CHECK-NOFP16-NEXT: fadd s0, s0, s1
18 ; CHECK-NOFP16-NEXT: fcvt h0, s0
19 ; CHECK-NOFP16-NEXT: ret
21 ; CHECK-FP16-LABEL: add_f16:
22 ; CHECK-FP16: // %bb.0:
23 ; CHECK-FP16-NEXT: fadd h0, h0, h1
24 ; CHECK-FP16-NEXT: ret
25 %val = call half @llvm.experimental.constrained.fadd.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
29 define half @sub_f16(half %x, half %y) #0 {
30 ; CHECK-NOFP16-LABEL: sub_f16:
31 ; CHECK-NOFP16: // %bb.0:
32 ; CHECK-NOFP16-NEXT: fcvt s1, h1
33 ; CHECK-NOFP16-NEXT: fcvt s0, h0
34 ; CHECK-NOFP16-NEXT: fsub s0, s0, s1
35 ; CHECK-NOFP16-NEXT: fcvt h0, s0
36 ; CHECK-NOFP16-NEXT: ret
38 ; CHECK-FP16-LABEL: sub_f16:
39 ; CHECK-FP16: // %bb.0:
40 ; CHECK-FP16-NEXT: fsub h0, h0, h1
41 ; CHECK-FP16-NEXT: ret
42 %val = call half @llvm.experimental.constrained.fsub.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
46 define half @mul_f16(half %x, half %y) #0 {
47 ; CHECK-NOFP16-LABEL: mul_f16:
48 ; CHECK-NOFP16: // %bb.0:
49 ; CHECK-NOFP16-NEXT: fcvt s1, h1
50 ; CHECK-NOFP16-NEXT: fcvt s0, h0
51 ; CHECK-NOFP16-NEXT: fmul s0, s0, s1
52 ; CHECK-NOFP16-NEXT: fcvt h0, s0
53 ; CHECK-NOFP16-NEXT: ret
55 ; CHECK-FP16-LABEL: mul_f16:
56 ; CHECK-FP16: // %bb.0:
57 ; CHECK-FP16-NEXT: fmul h0, h0, h1
58 ; CHECK-FP16-NEXT: ret
59 %val = call half @llvm.experimental.constrained.fmul.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
63 define half @div_f16(half %x, half %y) #0 {
64 ; CHECK-NOFP16-LABEL: div_f16:
65 ; CHECK-NOFP16: // %bb.0:
66 ; CHECK-NOFP16-NEXT: fcvt s1, h1
67 ; CHECK-NOFP16-NEXT: fcvt s0, h0
68 ; CHECK-NOFP16-NEXT: fdiv s0, s0, s1
69 ; CHECK-NOFP16-NEXT: fcvt h0, s0
70 ; CHECK-NOFP16-NEXT: ret
72 ; CHECK-FP16-LABEL: div_f16:
73 ; CHECK-FP16: // %bb.0:
74 ; CHECK-FP16-NEXT: fdiv h0, h0, h1
75 ; CHECK-FP16-NEXT: ret
76 %val = call half @llvm.experimental.constrained.fdiv.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
80 define half @frem_f16(half %x, half %y) #0 {
81 ; CHECK-LABEL: frem_f16:
83 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
84 ; CHECK-NEXT: .cfi_def_cfa_offset 16
85 ; CHECK-NEXT: .cfi_offset w30, -16
86 ; CHECK-NEXT: fcvt s1, h1
87 ; CHECK-NEXT: fcvt s0, h0
88 ; CHECK-NEXT: bl fmodf
89 ; CHECK-NEXT: fcvt h0, s0
90 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
92 %val = call half @llvm.experimental.constrained.frem.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
96 define half @fma_f16(half %x, half %y, half %z) #0 {
97 ; CHECK-NOFP16-LABEL: fma_f16:
98 ; CHECK-NOFP16: // %bb.0:
99 ; CHECK-NOFP16-NEXT: fcvt s2, h2
100 ; CHECK-NOFP16-NEXT: fcvt s1, h1
101 ; CHECK-NOFP16-NEXT: fcvt s0, h0
102 ; CHECK-NOFP16-NEXT: fmadd s0, s0, s1, s2
103 ; CHECK-NOFP16-NEXT: fcvt h0, s0
104 ; CHECK-NOFP16-NEXT: ret
106 ; CHECK-FP16-LABEL: fma_f16:
107 ; CHECK-FP16: // %bb.0:
108 ; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2
109 ; CHECK-FP16-NEXT: ret
110 %val = call half @llvm.experimental.constrained.fma.f16(half %x, half %y, half %z, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
114 define i32 @fptosi_i32_f16(half %x) #0 {
115 ; CHECK-NOFP16-LABEL: fptosi_i32_f16:
116 ; CHECK-NOFP16: // %bb.0:
117 ; CHECK-NOFP16-NEXT: fcvt s0, h0
118 ; CHECK-NOFP16-NEXT: fcvtzs w0, s0
119 ; CHECK-NOFP16-NEXT: ret
121 ; CHECK-FP16-LABEL: fptosi_i32_f16:
122 ; CHECK-FP16: // %bb.0:
123 ; CHECK-FP16-NEXT: fcvtzs w0, h0
124 ; CHECK-FP16-NEXT: ret
125 %val = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %x, metadata !"fpexcept.strict") #0
129 define i32 @fptoui_i32_f16(half %x) #0 {
130 ; CHECK-NOFP16-LABEL: fptoui_i32_f16:
131 ; CHECK-NOFP16: // %bb.0:
132 ; CHECK-NOFP16-NEXT: fcvt s0, h0
133 ; CHECK-NOFP16-NEXT: fcvtzu w0, s0
134 ; CHECK-NOFP16-NEXT: ret
136 ; CHECK-FP16-LABEL: fptoui_i32_f16:
137 ; CHECK-FP16: // %bb.0:
138 ; CHECK-FP16-NEXT: fcvtzu w0, h0
139 ; CHECK-FP16-NEXT: ret
140 %val = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %x, metadata !"fpexcept.strict") #0
144 define i64 @fptosi_i64_f16(half %x) #0 {
145 ; CHECK-NOFP16-LABEL: fptosi_i64_f16:
146 ; CHECK-NOFP16: // %bb.0:
147 ; CHECK-NOFP16-NEXT: fcvt s0, h0
148 ; CHECK-NOFP16-NEXT: fcvtzs x0, s0
149 ; CHECK-NOFP16-NEXT: ret
151 ; CHECK-FP16-LABEL: fptosi_i64_f16:
152 ; CHECK-FP16: // %bb.0:
153 ; CHECK-FP16-NEXT: fcvtzs x0, h0
154 ; CHECK-FP16-NEXT: ret
155 %val = call i64 @llvm.experimental.constrained.fptosi.i64.f16(half %x, metadata !"fpexcept.strict") #0
159 define i64 @fptoui_i64_f16(half %x) #0 {
160 ; CHECK-NOFP16-LABEL: fptoui_i64_f16:
161 ; CHECK-NOFP16: // %bb.0:
162 ; CHECK-NOFP16-NEXT: fcvt s0, h0
163 ; CHECK-NOFP16-NEXT: fcvtzu x0, s0
164 ; CHECK-NOFP16-NEXT: ret
166 ; CHECK-FP16-LABEL: fptoui_i64_f16:
167 ; CHECK-FP16: // %bb.0:
168 ; CHECK-FP16-NEXT: fcvtzu x0, h0
169 ; CHECK-FP16-NEXT: ret
170 %val = call i64 @llvm.experimental.constrained.fptoui.i64.f16(half %x, metadata !"fpexcept.strict") #0
174 define half @sitofp_f16_i32(i32 %x) #0 {
175 ; CHECK-NOFP16-LABEL: sitofp_f16_i32:
176 ; CHECK-NOFP16: // %bb.0:
177 ; CHECK-NOFP16-NEXT: scvtf s0, w0
178 ; CHECK-NOFP16-NEXT: fcvt h0, s0
179 ; CHECK-NOFP16-NEXT: ret
181 ; CHECK-FP16-LABEL: sitofp_f16_i32:
182 ; CHECK-FP16: // %bb.0:
183 ; CHECK-FP16-NEXT: scvtf h0, w0
184 ; CHECK-FP16-NEXT: ret
185 %val = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
189 define half @uitofp_f16_i32(i32 %x) #0 {
190 ; CHECK-NOFP16-LABEL: uitofp_f16_i32:
191 ; CHECK-NOFP16: // %bb.0:
192 ; CHECK-NOFP16-NEXT: ucvtf s0, w0
193 ; CHECK-NOFP16-NEXT: fcvt h0, s0
194 ; CHECK-NOFP16-NEXT: ret
196 ; CHECK-FP16-LABEL: uitofp_f16_i32:
197 ; CHECK-FP16: // %bb.0:
198 ; CHECK-FP16-NEXT: ucvtf h0, w0
199 ; CHECK-FP16-NEXT: ret
200 %val = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
204 define half @sitofp_f16_i64(i64 %x) #0 {
205 ; CHECK-NOFP16-LABEL: sitofp_f16_i64:
206 ; CHECK-NOFP16: // %bb.0:
207 ; CHECK-NOFP16-NEXT: scvtf s0, x0
208 ; CHECK-NOFP16-NEXT: fcvt h0, s0
209 ; CHECK-NOFP16-NEXT: ret
211 ; CHECK-FP16-LABEL: sitofp_f16_i64:
212 ; CHECK-FP16: // %bb.0:
213 ; CHECK-FP16-NEXT: scvtf h0, x0
214 ; CHECK-FP16-NEXT: ret
215 %val = call half @llvm.experimental.constrained.sitofp.f16.i64(i64 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
219 define half @uitofp_f16_i64(i64 %x) #0 {
220 ; CHECK-NOFP16-LABEL: uitofp_f16_i64:
221 ; CHECK-NOFP16: // %bb.0:
222 ; CHECK-NOFP16-NEXT: ucvtf s0, x0
223 ; CHECK-NOFP16-NEXT: fcvt h0, s0
224 ; CHECK-NOFP16-NEXT: ret
226 ; CHECK-FP16-LABEL: uitofp_f16_i64:
227 ; CHECK-FP16: // %bb.0:
228 ; CHECK-FP16-NEXT: ucvtf h0, x0
229 ; CHECK-FP16-NEXT: ret
230 %val = call half @llvm.experimental.constrained.uitofp.f16.i64(i64 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
234 define half @sitofp_f16_i128(i128 %x) #0 {
235 ; CHECK-NOFP16-LABEL: sitofp_f16_i128:
236 ; CHECK-NOFP16: // %bb.0:
237 ; CHECK-NOFP16-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
238 ; CHECK-NOFP16-NEXT: .cfi_def_cfa_offset 16
239 ; CHECK-NOFP16-NEXT: .cfi_offset w30, -16
240 ; CHECK-NOFP16-NEXT: bl __floattisf
241 ; CHECK-NOFP16-NEXT: fcvt h0, s0
242 ; CHECK-NOFP16-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
243 ; CHECK-NOFP16-NEXT: ret
245 ; CHECK-FP16-LABEL: sitofp_f16_i128:
246 ; CHECK-FP16: // %bb.0:
247 ; CHECK-FP16-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
248 ; CHECK-FP16-NEXT: .cfi_def_cfa_offset 16
249 ; CHECK-FP16-NEXT: .cfi_offset w30, -16
250 ; CHECK-FP16-NEXT: bl __floattihf
251 ; CHECK-FP16-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
252 ; CHECK-FP16-NEXT: ret
253 %val = call half @llvm.experimental.constrained.sitofp.f16.i128(i128 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
257 define half @uitofp_f16_i128(i128 %x) #0 {
258 ; CHECK-NOFP16-LABEL: uitofp_f16_i128:
259 ; CHECK-NOFP16: // %bb.0:
260 ; CHECK-NOFP16-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
261 ; CHECK-NOFP16-NEXT: .cfi_def_cfa_offset 16
262 ; CHECK-NOFP16-NEXT: .cfi_offset w30, -16
263 ; CHECK-NOFP16-NEXT: bl __floatuntisf
264 ; CHECK-NOFP16-NEXT: fcvt h0, s0
265 ; CHECK-NOFP16-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
266 ; CHECK-NOFP16-NEXT: ret
268 ; CHECK-FP16-LABEL: uitofp_f16_i128:
269 ; CHECK-FP16: // %bb.0:
270 ; CHECK-FP16-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
271 ; CHECK-FP16-NEXT: .cfi_def_cfa_offset 16
272 ; CHECK-FP16-NEXT: .cfi_offset w30, -16
273 ; CHECK-FP16-NEXT: bl __floatuntihf
274 ; CHECK-FP16-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
275 ; CHECK-FP16-NEXT: ret
276 %val = call half @llvm.experimental.constrained.uitofp.f16.i128(i128 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
280 define half @sqrt_f16(half %x) #0 {
281 ; CHECK-NOFP16-LABEL: sqrt_f16:
282 ; CHECK-NOFP16: // %bb.0:
283 ; CHECK-NOFP16-NEXT: fcvt s0, h0
284 ; CHECK-NOFP16-NEXT: fsqrt s0, s0
285 ; CHECK-NOFP16-NEXT: fcvt h0, s0
286 ; CHECK-NOFP16-NEXT: ret
288 ; CHECK-FP16-LABEL: sqrt_f16:
289 ; CHECK-FP16: // %bb.0:
290 ; CHECK-FP16-NEXT: fsqrt h0, h0
291 ; CHECK-FP16-NEXT: ret
292 %val = call half @llvm.experimental.constrained.sqrt.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
296 define half @powi_f16(half %x, i32 %y) #0 {
297 ; CHECK-LABEL: powi_f16:
299 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
300 ; CHECK-NEXT: .cfi_def_cfa_offset 16
301 ; CHECK-NEXT: .cfi_offset w30, -16
302 ; CHECK-NEXT: fcvt s0, h0
303 ; CHECK-NEXT: bl __powisf2
304 ; CHECK-NEXT: fcvt h0, s0
305 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
307 %val = call half @llvm.experimental.constrained.powi.f16(half %x, i32 %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
311 define half @sin_f16(half %x) #0 {
312 ; CHECK-LABEL: sin_f16:
314 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
315 ; CHECK-NEXT: .cfi_def_cfa_offset 16
316 ; CHECK-NEXT: .cfi_offset w30, -16
317 ; CHECK-NEXT: fcvt s0, h0
318 ; CHECK-NEXT: bl sinf
319 ; CHECK-NEXT: fcvt h0, s0
320 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
322 %val = call half @llvm.experimental.constrained.sin.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
326 define half @cos_f16(half %x) #0 {
327 ; CHECK-LABEL: cos_f16:
329 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
330 ; CHECK-NEXT: .cfi_def_cfa_offset 16
331 ; CHECK-NEXT: .cfi_offset w30, -16
332 ; CHECK-NEXT: fcvt s0, h0
333 ; CHECK-NEXT: bl cosf
334 ; CHECK-NEXT: fcvt h0, s0
335 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
337 %val = call half @llvm.experimental.constrained.cos.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
341 define half @tan_f16(half %x) #0 {
342 ; CHECK-LABEL: tan_f16:
344 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
345 ; CHECK-NEXT: .cfi_def_cfa_offset 16
346 ; CHECK-NEXT: .cfi_offset w30, -16
347 ; CHECK-NEXT: fcvt s0, h0
348 ; CHECK-NEXT: bl tanf
349 ; CHECK-NEXT: fcvt h0, s0
350 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
352 %val = call half @llvm.experimental.constrained.tan.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
356 define half @asin_f16(half %x) #0 {
357 ; CHECK-LABEL: asin_f16:
359 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
360 ; CHECK-NEXT: .cfi_def_cfa_offset 16
361 ; CHECK-NEXT: .cfi_offset w30, -16
362 ; CHECK-NEXT: fcvt s0, h0
363 ; CHECK-NEXT: bl asinf
364 ; CHECK-NEXT: fcvt h0, s0
365 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
367 %val = call half @llvm.experimental.constrained.asin.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
371 define half @acos_f16(half %x) #0 {
372 ; CHECK-LABEL: acos_f16:
374 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
375 ; CHECK-NEXT: .cfi_def_cfa_offset 16
376 ; CHECK-NEXT: .cfi_offset w30, -16
377 ; CHECK-NEXT: fcvt s0, h0
378 ; CHECK-NEXT: bl acosf
379 ; CHECK-NEXT: fcvt h0, s0
380 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
382 %val = call half @llvm.experimental.constrained.acos.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
386 define half @atan_f16(half %x) #0 {
387 ; CHECK-LABEL: atan_f16:
389 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
390 ; CHECK-NEXT: .cfi_def_cfa_offset 16
391 ; CHECK-NEXT: .cfi_offset w30, -16
392 ; CHECK-NEXT: fcvt s0, h0
393 ; CHECK-NEXT: bl atanf
394 ; CHECK-NEXT: fcvt h0, s0
395 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
397 %val = call half @llvm.experimental.constrained.atan.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
401 define half @atan2_f16(half %x, half %y) #0 {
402 ; CHECK-LABEL: atan2_f16:
404 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
405 ; CHECK-NEXT: .cfi_def_cfa_offset 16
406 ; CHECK-NEXT: .cfi_offset w30, -16
407 ; CHECK-NEXT: fcvt s1, h1
408 ; CHECK-NEXT: fcvt s0, h0
409 ; CHECK-NEXT: bl atan2f
410 ; CHECK-NEXT: fcvt h0, s0
411 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
413 %val = call half @llvm.experimental.constrained.atan2.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
417 define half @sinh_f16(half %x) #0 {
418 ; CHECK-LABEL: sinh_f16:
420 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
421 ; CHECK-NEXT: .cfi_def_cfa_offset 16
422 ; CHECK-NEXT: .cfi_offset w30, -16
423 ; CHECK-NEXT: fcvt s0, h0
424 ; CHECK-NEXT: bl sinhf
425 ; CHECK-NEXT: fcvt h0, s0
426 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
428 %val = call half @llvm.experimental.constrained.sinh.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
432 define half @cosh_f16(half %x) #0 {
433 ; CHECK-LABEL: cosh_f16:
435 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
436 ; CHECK-NEXT: .cfi_def_cfa_offset 16
437 ; CHECK-NEXT: .cfi_offset w30, -16
438 ; CHECK-NEXT: fcvt s0, h0
439 ; CHECK-NEXT: bl coshf
440 ; CHECK-NEXT: fcvt h0, s0
441 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
443 %val = call half @llvm.experimental.constrained.cosh.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
447 define half @tanh_f16(half %x) #0 {
448 ; CHECK-LABEL: tanh_f16:
450 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
451 ; CHECK-NEXT: .cfi_def_cfa_offset 16
452 ; CHECK-NEXT: .cfi_offset w30, -16
453 ; CHECK-NEXT: fcvt s0, h0
454 ; CHECK-NEXT: bl tanhf
455 ; CHECK-NEXT: fcvt h0, s0
456 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
458 %val = call half @llvm.experimental.constrained.tanh.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
462 define half @pow_f16(half %x, half %y) #0 {
463 ; CHECK-LABEL: pow_f16:
465 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
466 ; CHECK-NEXT: .cfi_def_cfa_offset 16
467 ; CHECK-NEXT: .cfi_offset w30, -16
468 ; CHECK-NEXT: fcvt s1, h1
469 ; CHECK-NEXT: fcvt s0, h0
470 ; CHECK-NEXT: bl powf
471 ; CHECK-NEXT: fcvt h0, s0
472 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
474 %val = call half @llvm.experimental.constrained.pow.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
478 define half @log_f16(half %x) #0 {
479 ; CHECK-LABEL: log_f16:
481 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
482 ; CHECK-NEXT: .cfi_def_cfa_offset 16
483 ; CHECK-NEXT: .cfi_offset w30, -16
484 ; CHECK-NEXT: fcvt s0, h0
485 ; CHECK-NEXT: bl logf
486 ; CHECK-NEXT: fcvt h0, s0
487 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
489 %val = call half @llvm.experimental.constrained.log.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
493 define half @log10_f16(half %x) #0 {
494 ; CHECK-LABEL: log10_f16:
496 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
497 ; CHECK-NEXT: .cfi_def_cfa_offset 16
498 ; CHECK-NEXT: .cfi_offset w30, -16
499 ; CHECK-NEXT: fcvt s0, h0
500 ; CHECK-NEXT: bl log10f
501 ; CHECK-NEXT: fcvt h0, s0
502 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
504 %val = call half @llvm.experimental.constrained.log10.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
508 define half @log2_f16(half %x) #0 {
509 ; CHECK-LABEL: log2_f16:
511 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
512 ; CHECK-NEXT: .cfi_def_cfa_offset 16
513 ; CHECK-NEXT: .cfi_offset w30, -16
514 ; CHECK-NEXT: fcvt s0, h0
515 ; CHECK-NEXT: bl log2f
516 ; CHECK-NEXT: fcvt h0, s0
517 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
519 %val = call half @llvm.experimental.constrained.log2.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
523 define half @exp_f16(half %x) #0 {
524 ; CHECK-LABEL: exp_f16:
526 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
527 ; CHECK-NEXT: .cfi_def_cfa_offset 16
528 ; CHECK-NEXT: .cfi_offset w30, -16
529 ; CHECK-NEXT: fcvt s0, h0
530 ; CHECK-NEXT: bl expf
531 ; CHECK-NEXT: fcvt h0, s0
532 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
534 %val = call half @llvm.experimental.constrained.exp.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
538 define half @exp2_f16(half %x) #0 {
539 ; CHECK-LABEL: exp2_f16:
541 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
542 ; CHECK-NEXT: .cfi_def_cfa_offset 16
543 ; CHECK-NEXT: .cfi_offset w30, -16
544 ; CHECK-NEXT: fcvt s0, h0
545 ; CHECK-NEXT: bl exp2f
546 ; CHECK-NEXT: fcvt h0, s0
547 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
549 %val = call half @llvm.experimental.constrained.exp2.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
553 define half @rint_f16(half %x) #0 {
554 ; CHECK-NOFP16-LABEL: rint_f16:
555 ; CHECK-NOFP16: // %bb.0:
556 ; CHECK-NOFP16-NEXT: fcvt s0, h0
557 ; CHECK-NOFP16-NEXT: frintx s0, s0
558 ; CHECK-NOFP16-NEXT: fcvt h0, s0
559 ; CHECK-NOFP16-NEXT: ret
561 ; CHECK-FP16-LABEL: rint_f16:
562 ; CHECK-FP16: // %bb.0:
563 ; CHECK-FP16-NEXT: frintx h0, h0
564 ; CHECK-FP16-NEXT: ret
565 %val = call half @llvm.experimental.constrained.rint.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
569 define half @nearbyint_f16(half %x) #0 {
570 ; CHECK-NOFP16-LABEL: nearbyint_f16:
571 ; CHECK-NOFP16: // %bb.0:
572 ; CHECK-NOFP16-NEXT: fcvt s0, h0
573 ; CHECK-NOFP16-NEXT: frinti s0, s0
574 ; CHECK-NOFP16-NEXT: fcvt h0, s0
575 ; CHECK-NOFP16-NEXT: ret
577 ; CHECK-FP16-LABEL: nearbyint_f16:
578 ; CHECK-FP16: // %bb.0:
579 ; CHECK-FP16-NEXT: frinti h0, h0
580 ; CHECK-FP16-NEXT: ret
581 %val = call half @llvm.experimental.constrained.nearbyint.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
585 define i32 @lrint_f16(half %x) #0 {
586 ; CHECK-NOFP16-LABEL: lrint_f16:
587 ; CHECK-NOFP16: // %bb.0:
588 ; CHECK-NOFP16-NEXT: fcvt s0, h0
589 ; CHECK-NOFP16-NEXT: frintx s0, s0
590 ; CHECK-NOFP16-NEXT: fcvtzs w0, s0
591 ; CHECK-NOFP16-NEXT: ret
593 ; CHECK-FP16-LABEL: lrint_f16:
594 ; CHECK-FP16: // %bb.0:
595 ; CHECK-FP16-NEXT: frintx h0, h0
596 ; CHECK-FP16-NEXT: fcvtzs w0, h0
597 ; CHECK-FP16-NEXT: ret
598 %val = call i32 @llvm.experimental.constrained.lrint.i32.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
602 define i64 @llrint_f16(half %x) #0 {
603 ; CHECK-NOFP16-LABEL: llrint_f16:
604 ; CHECK-NOFP16: // %bb.0:
605 ; CHECK-NOFP16-NEXT: fcvt s0, h0
606 ; CHECK-NOFP16-NEXT: frintx s0, s0
607 ; CHECK-NOFP16-NEXT: fcvtzs x0, s0
608 ; CHECK-NOFP16-NEXT: ret
610 ; CHECK-FP16-LABEL: llrint_f16:
611 ; CHECK-FP16: // %bb.0:
612 ; CHECK-FP16-NEXT: frintx h0, h0
613 ; CHECK-FP16-NEXT: fcvtzs x0, h0
614 ; CHECK-FP16-NEXT: ret
615 %val = call i64 @llvm.experimental.constrained.llrint.i64.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
619 define half @maxnum_f16(half %x, half %y) #0 {
620 ; CHECK-NOFP16-LABEL: maxnum_f16:
621 ; CHECK-NOFP16: // %bb.0:
622 ; CHECK-NOFP16-NEXT: fcvt s1, h1
623 ; CHECK-NOFP16-NEXT: fcvt s0, h0
624 ; CHECK-NOFP16-NEXT: fmaxnm s0, s0, s1
625 ; CHECK-NOFP16-NEXT: fcvt h0, s0
626 ; CHECK-NOFP16-NEXT: ret
628 ; CHECK-FP16-LABEL: maxnum_f16:
629 ; CHECK-FP16: // %bb.0:
630 ; CHECK-FP16-NEXT: fmaxnm h0, h0, h1
631 ; CHECK-FP16-NEXT: ret
632 %val = call half @llvm.experimental.constrained.maxnum.f16(half %x, half %y, metadata !"fpexcept.strict") #0
636 define half @minnum_f16(half %x, half %y) #0 {
637 ; CHECK-NOFP16-LABEL: minnum_f16:
638 ; CHECK-NOFP16: // %bb.0:
639 ; CHECK-NOFP16-NEXT: fcvt s1, h1
640 ; CHECK-NOFP16-NEXT: fcvt s0, h0
641 ; CHECK-NOFP16-NEXT: fminnm s0, s0, s1
642 ; CHECK-NOFP16-NEXT: fcvt h0, s0
643 ; CHECK-NOFP16-NEXT: ret
645 ; CHECK-FP16-LABEL: minnum_f16:
646 ; CHECK-FP16: // %bb.0:
647 ; CHECK-FP16-NEXT: fminnm h0, h0, h1
648 ; CHECK-FP16-NEXT: ret
649 %val = call half @llvm.experimental.constrained.minnum.f16(half %x, half %y, metadata !"fpexcept.strict") #0
653 define half @ceil_f16(half %x) #0 {
654 ; CHECK-NOFP16-LABEL: ceil_f16:
655 ; CHECK-NOFP16: // %bb.0:
656 ; CHECK-NOFP16-NEXT: fcvt s0, h0
657 ; CHECK-NOFP16-NEXT: frintp s0, s0
658 ; CHECK-NOFP16-NEXT: fcvt h0, s0
659 ; CHECK-NOFP16-NEXT: ret
661 ; CHECK-FP16-LABEL: ceil_f16:
662 ; CHECK-FP16: // %bb.0:
663 ; CHECK-FP16-NEXT: frintp h0, h0
664 ; CHECK-FP16-NEXT: ret
665 %val = call half @llvm.experimental.constrained.ceil.f16(half %x, metadata !"fpexcept.strict") #0
669 define half @floor_f16(half %x) #0 {
670 ; CHECK-NOFP16-LABEL: floor_f16:
671 ; CHECK-NOFP16: // %bb.0:
672 ; CHECK-NOFP16-NEXT: fcvt s0, h0
673 ; CHECK-NOFP16-NEXT: frintm s0, s0
674 ; CHECK-NOFP16-NEXT: fcvt h0, s0
675 ; CHECK-NOFP16-NEXT: ret
677 ; CHECK-FP16-LABEL: floor_f16:
678 ; CHECK-FP16: // %bb.0:
679 ; CHECK-FP16-NEXT: frintm h0, h0
680 ; CHECK-FP16-NEXT: ret
681 %val = call half @llvm.experimental.constrained.floor.f16(half %x, metadata !"fpexcept.strict") #0
685 define i32 @lround_f16(half %x) #0 {
686 ; CHECK-NOFP16-LABEL: lround_f16:
687 ; CHECK-NOFP16: // %bb.0:
688 ; CHECK-NOFP16-NEXT: fcvt s0, h0
689 ; CHECK-NOFP16-NEXT: fcvtas w0, s0
690 ; CHECK-NOFP16-NEXT: ret
692 ; CHECK-FP16-LABEL: lround_f16:
693 ; CHECK-FP16: // %bb.0:
694 ; CHECK-FP16-NEXT: fcvtas w0, h0
695 ; CHECK-FP16-NEXT: ret
696 %val = call i32 @llvm.experimental.constrained.lround.i32.f16(half %x, metadata !"fpexcept.strict") #0
700 define i64 @llround_f16(half %x) #0 {
701 ; CHECK-NOFP16-LABEL: llround_f16:
702 ; CHECK-NOFP16: // %bb.0:
703 ; CHECK-NOFP16-NEXT: fcvt s0, h0
704 ; CHECK-NOFP16-NEXT: fcvtas x0, s0
705 ; CHECK-NOFP16-NEXT: ret
707 ; CHECK-FP16-LABEL: llround_f16:
708 ; CHECK-FP16: // %bb.0:
709 ; CHECK-FP16-NEXT: fcvtas x0, h0
710 ; CHECK-FP16-NEXT: ret
711 %val = call i64 @llvm.experimental.constrained.llround.i64.f16(half %x, metadata !"fpexcept.strict") #0
715 define half @round_f16(half %x) #0 {
716 ; CHECK-NOFP16-LABEL: round_f16:
717 ; CHECK-NOFP16: // %bb.0:
718 ; CHECK-NOFP16-NEXT: fcvt s0, h0
719 ; CHECK-NOFP16-NEXT: frinta s0, s0
720 ; CHECK-NOFP16-NEXT: fcvt h0, s0
721 ; CHECK-NOFP16-NEXT: ret
723 ; CHECK-FP16-LABEL: round_f16:
724 ; CHECK-FP16: // %bb.0:
725 ; CHECK-FP16-NEXT: frinta h0, h0
726 ; CHECK-FP16-NEXT: ret
727 %val = call half @llvm.experimental.constrained.round.f16(half %x, metadata !"fpexcept.strict") #0
731 define half @roundeven_f16(half %x) #0 {
732 ; CHECK-NOFP16-LABEL: roundeven_f16:
733 ; CHECK-NOFP16: // %bb.0:
734 ; CHECK-NOFP16-NEXT: fcvt s0, h0
735 ; CHECK-NOFP16-NEXT: frintn s0, s0
736 ; CHECK-NOFP16-NEXT: fcvt h0, s0
737 ; CHECK-NOFP16-NEXT: ret
739 ; CHECK-FP16-LABEL: roundeven_f16:
740 ; CHECK-FP16: // %bb.0:
741 ; CHECK-FP16-NEXT: frintn h0, h0
742 ; CHECK-FP16-NEXT: ret
743 %val = call half @llvm.experimental.constrained.roundeven.f16(half %x, metadata !"fpexcept.strict") #0
747 define half @trunc_f16(half %x) #0 {
748 ; CHECK-NOFP16-LABEL: trunc_f16:
749 ; CHECK-NOFP16: // %bb.0:
750 ; CHECK-NOFP16-NEXT: fcvt s0, h0
751 ; CHECK-NOFP16-NEXT: frintz s0, s0
752 ; CHECK-NOFP16-NEXT: fcvt h0, s0
753 ; CHECK-NOFP16-NEXT: ret
755 ; CHECK-FP16-LABEL: trunc_f16:
756 ; CHECK-FP16: // %bb.0:
757 ; CHECK-FP16-NEXT: frintz h0, h0
758 ; CHECK-FP16-NEXT: ret
759 %val = call half @llvm.experimental.constrained.trunc.f16(half %x, metadata !"fpexcept.strict") #0
763 define i32 @fcmp_olt_f16(half %a, half %b) #0 {
764 ; CHECK-NOFP16-LABEL: fcmp_olt_f16:
765 ; CHECK-NOFP16: // %bb.0:
766 ; CHECK-NOFP16-NEXT: fcvt s0, h0
767 ; CHECK-NOFP16-NEXT: fcvt s1, h1
768 ; CHECK-NOFP16-NEXT: fcmp s0, s1
769 ; CHECK-NOFP16-NEXT: cset w0, mi
770 ; CHECK-NOFP16-NEXT: ret
772 ; CHECK-FP16-LABEL: fcmp_olt_f16:
773 ; CHECK-FP16: // %bb.0:
774 ; CHECK-FP16-NEXT: fcmp h0, h1
775 ; CHECK-FP16-NEXT: cset w0, mi
776 ; CHECK-FP16-NEXT: ret
777 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict") #0
778 %conv = zext i1 %cmp to i32
782 define i32 @fcmp_ole_f16(half %a, half %b) #0 {
783 ; CHECK-NOFP16-LABEL: fcmp_ole_f16:
784 ; CHECK-NOFP16: // %bb.0:
785 ; CHECK-NOFP16-NEXT: fcvt s0, h0
786 ; CHECK-NOFP16-NEXT: fcvt s1, h1
787 ; CHECK-NOFP16-NEXT: fcmp s0, s1
788 ; CHECK-NOFP16-NEXT: cset w0, ls
789 ; CHECK-NOFP16-NEXT: ret
791 ; CHECK-FP16-LABEL: fcmp_ole_f16:
792 ; CHECK-FP16: // %bb.0:
793 ; CHECK-FP16-NEXT: fcmp h0, h1
794 ; CHECK-FP16-NEXT: cset w0, ls
795 ; CHECK-FP16-NEXT: ret
796 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict") #0
797 %conv = zext i1 %cmp to i32
801 define i32 @fcmp_ogt_f16(half %a, half %b) #0 {
802 ; CHECK-NOFP16-LABEL: fcmp_ogt_f16:
803 ; CHECK-NOFP16: // %bb.0:
804 ; CHECK-NOFP16-NEXT: fcvt s0, h0
805 ; CHECK-NOFP16-NEXT: fcvt s1, h1
806 ; CHECK-NOFP16-NEXT: fcmp s0, s1
807 ; CHECK-NOFP16-NEXT: cset w0, gt
808 ; CHECK-NOFP16-NEXT: ret
810 ; CHECK-FP16-LABEL: fcmp_ogt_f16:
811 ; CHECK-FP16: // %bb.0:
812 ; CHECK-FP16-NEXT: fcmp h0, h1
813 ; CHECK-FP16-NEXT: cset w0, gt
814 ; CHECK-FP16-NEXT: ret
815 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ogt", metadata !"fpexcept.strict") #0
816 %conv = zext i1 %cmp to i32
820 define i32 @fcmp_oge_f16(half %a, half %b) #0 {
821 ; CHECK-NOFP16-LABEL: fcmp_oge_f16:
822 ; CHECK-NOFP16: // %bb.0:
823 ; CHECK-NOFP16-NEXT: fcvt s0, h0
824 ; CHECK-NOFP16-NEXT: fcvt s1, h1
825 ; CHECK-NOFP16-NEXT: fcmp s0, s1
826 ; CHECK-NOFP16-NEXT: cset w0, ge
827 ; CHECK-NOFP16-NEXT: ret
829 ; CHECK-FP16-LABEL: fcmp_oge_f16:
830 ; CHECK-FP16: // %bb.0:
831 ; CHECK-FP16-NEXT: fcmp h0, h1
832 ; CHECK-FP16-NEXT: cset w0, ge
833 ; CHECK-FP16-NEXT: ret
834 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"oge", metadata !"fpexcept.strict") #0
835 %conv = zext i1 %cmp to i32
839 define i32 @fcmp_oeq_f16(half %a, half %b) #0 {
840 ; CHECK-NOFP16-LABEL: fcmp_oeq_f16:
841 ; CHECK-NOFP16: // %bb.0:
842 ; CHECK-NOFP16-NEXT: fcvt s0, h0
843 ; CHECK-NOFP16-NEXT: fcvt s1, h1
844 ; CHECK-NOFP16-NEXT: fcmp s0, s1
845 ; CHECK-NOFP16-NEXT: cset w0, eq
846 ; CHECK-NOFP16-NEXT: ret
848 ; CHECK-FP16-LABEL: fcmp_oeq_f16:
849 ; CHECK-FP16: // %bb.0:
850 ; CHECK-FP16-NEXT: fcmp h0, h1
851 ; CHECK-FP16-NEXT: cset w0, eq
852 ; CHECK-FP16-NEXT: ret
853 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"oeq", metadata !"fpexcept.strict") #0
854 %conv = zext i1 %cmp to i32
858 define i32 @fcmp_one_f16(half %a, half %b) #0 {
859 ; CHECK-NOFP16-LABEL: fcmp_one_f16:
860 ; CHECK-NOFP16: // %bb.0:
861 ; CHECK-NOFP16-NEXT: fcvt s0, h0
862 ; CHECK-NOFP16-NEXT: fcvt s1, h1
863 ; CHECK-NOFP16-NEXT: fcmp s0, s1
864 ; CHECK-NOFP16-NEXT: cset w8, mi
865 ; CHECK-NOFP16-NEXT: csinc w0, w8, wzr, le
866 ; CHECK-NOFP16-NEXT: ret
868 ; CHECK-FP16-LABEL: fcmp_one_f16:
869 ; CHECK-FP16: // %bb.0:
870 ; CHECK-FP16-NEXT: fcmp h0, h1
871 ; CHECK-FP16-NEXT: cset w8, mi
872 ; CHECK-FP16-NEXT: csinc w0, w8, wzr, le
873 ; CHECK-FP16-NEXT: ret
874 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"one", metadata !"fpexcept.strict") #0
875 %conv = zext i1 %cmp to i32
879 define i32 @fcmp_ult_f16(half %a, half %b) #0 {
880 ; CHECK-NOFP16-LABEL: fcmp_ult_f16:
881 ; CHECK-NOFP16: // %bb.0:
882 ; CHECK-NOFP16-NEXT: fcvt s0, h0
883 ; CHECK-NOFP16-NEXT: fcvt s1, h1
884 ; CHECK-NOFP16-NEXT: fcmp s0, s1
885 ; CHECK-NOFP16-NEXT: cset w0, lt
886 ; CHECK-NOFP16-NEXT: ret
888 ; CHECK-FP16-LABEL: fcmp_ult_f16:
889 ; CHECK-FP16: // %bb.0:
890 ; CHECK-FP16-NEXT: fcmp h0, h1
891 ; CHECK-FP16-NEXT: cset w0, lt
892 ; CHECK-FP16-NEXT: ret
893 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ult", metadata !"fpexcept.strict") #0
894 %conv = zext i1 %cmp to i32
898 define i32 @fcmp_ule_f16(half %a, half %b) #0 {
899 ; CHECK-NOFP16-LABEL: fcmp_ule_f16:
900 ; CHECK-NOFP16: // %bb.0:
901 ; CHECK-NOFP16-NEXT: fcvt s0, h0
902 ; CHECK-NOFP16-NEXT: fcvt s1, h1
903 ; CHECK-NOFP16-NEXT: fcmp s0, s1
904 ; CHECK-NOFP16-NEXT: cset w0, le
905 ; CHECK-NOFP16-NEXT: ret
907 ; CHECK-FP16-LABEL: fcmp_ule_f16:
908 ; CHECK-FP16: // %bb.0:
909 ; CHECK-FP16-NEXT: fcmp h0, h1
910 ; CHECK-FP16-NEXT: cset w0, le
911 ; CHECK-FP16-NEXT: ret
912 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ule", metadata !"fpexcept.strict") #0
913 %conv = zext i1 %cmp to i32
917 define i32 @fcmp_ugt_f16(half %a, half %b) #0 {
918 ; CHECK-NOFP16-LABEL: fcmp_ugt_f16:
919 ; CHECK-NOFP16: // %bb.0:
920 ; CHECK-NOFP16-NEXT: fcvt s0, h0
921 ; CHECK-NOFP16-NEXT: fcvt s1, h1
922 ; CHECK-NOFP16-NEXT: fcmp s0, s1
923 ; CHECK-NOFP16-NEXT: cset w0, hi
924 ; CHECK-NOFP16-NEXT: ret
926 ; CHECK-FP16-LABEL: fcmp_ugt_f16:
927 ; CHECK-FP16: // %bb.0:
928 ; CHECK-FP16-NEXT: fcmp h0, h1
929 ; CHECK-FP16-NEXT: cset w0, hi
930 ; CHECK-FP16-NEXT: ret
931 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ugt", metadata !"fpexcept.strict") #0
932 %conv = zext i1 %cmp to i32
936 define i32 @fcmp_uge_f16(half %a, half %b) #0 {
937 ; CHECK-NOFP16-LABEL: fcmp_uge_f16:
938 ; CHECK-NOFP16: // %bb.0:
939 ; CHECK-NOFP16-NEXT: fcvt s0, h0
940 ; CHECK-NOFP16-NEXT: fcvt s1, h1
941 ; CHECK-NOFP16-NEXT: fcmp s0, s1
942 ; CHECK-NOFP16-NEXT: cset w0, pl
943 ; CHECK-NOFP16-NEXT: ret
945 ; CHECK-FP16-LABEL: fcmp_uge_f16:
946 ; CHECK-FP16: // %bb.0:
947 ; CHECK-FP16-NEXT: fcmp h0, h1
948 ; CHECK-FP16-NEXT: cset w0, pl
949 ; CHECK-FP16-NEXT: ret
950 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"uge", metadata !"fpexcept.strict") #0
951 %conv = zext i1 %cmp to i32
955 define i32 @fcmp_ueq_f16(half %a, half %b) #0 {
956 ; CHECK-NOFP16-LABEL: fcmp_ueq_f16:
957 ; CHECK-NOFP16: // %bb.0:
958 ; CHECK-NOFP16-NEXT: fcvt s0, h0
959 ; CHECK-NOFP16-NEXT: fcvt s1, h1
960 ; CHECK-NOFP16-NEXT: fcmp s0, s1
961 ; CHECK-NOFP16-NEXT: cset w8, eq
962 ; CHECK-NOFP16-NEXT: csinc w0, w8, wzr, vc
963 ; CHECK-NOFP16-NEXT: ret
965 ; CHECK-FP16-LABEL: fcmp_ueq_f16:
966 ; CHECK-FP16: // %bb.0:
967 ; CHECK-FP16-NEXT: fcmp h0, h1
968 ; CHECK-FP16-NEXT: cset w8, eq
969 ; CHECK-FP16-NEXT: csinc w0, w8, wzr, vc
970 ; CHECK-FP16-NEXT: ret
971 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ueq", metadata !"fpexcept.strict") #0
972 %conv = zext i1 %cmp to i32
976 define i32 @fcmp_une_f16(half %a, half %b) #0 {
977 ; CHECK-NOFP16-LABEL: fcmp_une_f16:
978 ; CHECK-NOFP16: // %bb.0:
979 ; CHECK-NOFP16-NEXT: fcvt s0, h0
980 ; CHECK-NOFP16-NEXT: fcvt s1, h1
981 ; CHECK-NOFP16-NEXT: fcmp s0, s1
982 ; CHECK-NOFP16-NEXT: cset w0, ne
983 ; CHECK-NOFP16-NEXT: ret
985 ; CHECK-FP16-LABEL: fcmp_une_f16:
986 ; CHECK-FP16: // %bb.0:
987 ; CHECK-FP16-NEXT: fcmp h0, h1
988 ; CHECK-FP16-NEXT: cset w0, ne
989 ; CHECK-FP16-NEXT: ret
990 %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"une", metadata !"fpexcept.strict") #0
991 %conv = zext i1 %cmp to i32
995 define i32 @fcmps_olt_f16(half %a, half %b) #0 {
996 ; CHECK-NOFP16-LABEL: fcmps_olt_f16:
997 ; CHECK-NOFP16: // %bb.0:
998 ; CHECK-NOFP16-NEXT: fcvt s0, h0
999 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1000 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1001 ; CHECK-NOFP16-NEXT: cset w0, mi
1002 ; CHECK-NOFP16-NEXT: ret
1004 ; CHECK-FP16-LABEL: fcmps_olt_f16:
1005 ; CHECK-FP16: // %bb.0:
1006 ; CHECK-FP16-NEXT: fcmpe h0, h1
1007 ; CHECK-FP16-NEXT: cset w0, mi
1008 ; CHECK-FP16-NEXT: ret
1009 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict") #0
1010 %conv = zext i1 %cmp to i32
1014 define i32 @fcmps_ole_f16(half %a, half %b) #0 {
1015 ; CHECK-NOFP16-LABEL: fcmps_ole_f16:
1016 ; CHECK-NOFP16: // %bb.0:
1017 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1018 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1019 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1020 ; CHECK-NOFP16-NEXT: cset w0, ls
1021 ; CHECK-NOFP16-NEXT: ret
1023 ; CHECK-FP16-LABEL: fcmps_ole_f16:
1024 ; CHECK-FP16: // %bb.0:
1025 ; CHECK-FP16-NEXT: fcmpe h0, h1
1026 ; CHECK-FP16-NEXT: cset w0, ls
1027 ; CHECK-FP16-NEXT: ret
1028 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict") #0
1029 %conv = zext i1 %cmp to i32
1033 define i32 @fcmps_ogt_f16(half %a, half %b) #0 {
1034 ; CHECK-NOFP16-LABEL: fcmps_ogt_f16:
1035 ; CHECK-NOFP16: // %bb.0:
1036 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1037 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1038 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1039 ; CHECK-NOFP16-NEXT: cset w0, gt
1040 ; CHECK-NOFP16-NEXT: ret
1042 ; CHECK-FP16-LABEL: fcmps_ogt_f16:
1043 ; CHECK-FP16: // %bb.0:
1044 ; CHECK-FP16-NEXT: fcmpe h0, h1
1045 ; CHECK-FP16-NEXT: cset w0, gt
1046 ; CHECK-FP16-NEXT: ret
1047 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ogt", metadata !"fpexcept.strict") #0
1048 %conv = zext i1 %cmp to i32
1052 define i32 @fcmps_oge_f16(half %a, half %b) #0 {
1053 ; CHECK-NOFP16-LABEL: fcmps_oge_f16:
1054 ; CHECK-NOFP16: // %bb.0:
1055 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1056 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1057 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1058 ; CHECK-NOFP16-NEXT: cset w0, ge
1059 ; CHECK-NOFP16-NEXT: ret
1061 ; CHECK-FP16-LABEL: fcmps_oge_f16:
1062 ; CHECK-FP16: // %bb.0:
1063 ; CHECK-FP16-NEXT: fcmpe h0, h1
1064 ; CHECK-FP16-NEXT: cset w0, ge
1065 ; CHECK-FP16-NEXT: ret
1066 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"oge", metadata !"fpexcept.strict") #0
1067 %conv = zext i1 %cmp to i32
1071 define i32 @fcmps_oeq_f16(half %a, half %b) #0 {
1072 ; CHECK-NOFP16-LABEL: fcmps_oeq_f16:
1073 ; CHECK-NOFP16: // %bb.0:
1074 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1075 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1076 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1077 ; CHECK-NOFP16-NEXT: cset w0, eq
1078 ; CHECK-NOFP16-NEXT: ret
1080 ; CHECK-FP16-LABEL: fcmps_oeq_f16:
1081 ; CHECK-FP16: // %bb.0:
1082 ; CHECK-FP16-NEXT: fcmpe h0, h1
1083 ; CHECK-FP16-NEXT: cset w0, eq
1084 ; CHECK-FP16-NEXT: ret
1085 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"oeq", metadata !"fpexcept.strict") #0
1086 %conv = zext i1 %cmp to i32
1090 define i32 @fcmps_one_f16(half %a, half %b) #0 {
1091 ; CHECK-NOFP16-LABEL: fcmps_one_f16:
1092 ; CHECK-NOFP16: // %bb.0:
1093 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1094 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1095 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1096 ; CHECK-NOFP16-NEXT: cset w8, mi
1097 ; CHECK-NOFP16-NEXT: csinc w0, w8, wzr, le
1098 ; CHECK-NOFP16-NEXT: ret
1100 ; CHECK-FP16-LABEL: fcmps_one_f16:
1101 ; CHECK-FP16: // %bb.0:
1102 ; CHECK-FP16-NEXT: fcmpe h0, h1
1103 ; CHECK-FP16-NEXT: cset w8, mi
1104 ; CHECK-FP16-NEXT: csinc w0, w8, wzr, le
1105 ; CHECK-FP16-NEXT: ret
1106 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"one", metadata !"fpexcept.strict") #0
1107 %conv = zext i1 %cmp to i32
1111 define i32 @fcmps_ult_f16(half %a, half %b) #0 {
1112 ; CHECK-NOFP16-LABEL: fcmps_ult_f16:
1113 ; CHECK-NOFP16: // %bb.0:
1114 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1115 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1116 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1117 ; CHECK-NOFP16-NEXT: cset w0, lt
1118 ; CHECK-NOFP16-NEXT: ret
1120 ; CHECK-FP16-LABEL: fcmps_ult_f16:
1121 ; CHECK-FP16: // %bb.0:
1122 ; CHECK-FP16-NEXT: fcmpe h0, h1
1123 ; CHECK-FP16-NEXT: cset w0, lt
1124 ; CHECK-FP16-NEXT: ret
1125 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ult", metadata !"fpexcept.strict") #0
1126 %conv = zext i1 %cmp to i32
1130 define i32 @fcmps_ule_f16(half %a, half %b) #0 {
1131 ; CHECK-NOFP16-LABEL: fcmps_ule_f16:
1132 ; CHECK-NOFP16: // %bb.0:
1133 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1134 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1135 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1136 ; CHECK-NOFP16-NEXT: cset w0, le
1137 ; CHECK-NOFP16-NEXT: ret
1139 ; CHECK-FP16-LABEL: fcmps_ule_f16:
1140 ; CHECK-FP16: // %bb.0:
1141 ; CHECK-FP16-NEXT: fcmpe h0, h1
1142 ; CHECK-FP16-NEXT: cset w0, le
1143 ; CHECK-FP16-NEXT: ret
1144 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ule", metadata !"fpexcept.strict") #0
1145 %conv = zext i1 %cmp to i32
1149 define i32 @fcmps_ugt_f16(half %a, half %b) #0 {
1150 ; CHECK-NOFP16-LABEL: fcmps_ugt_f16:
1151 ; CHECK-NOFP16: // %bb.0:
1152 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1153 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1154 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1155 ; CHECK-NOFP16-NEXT: cset w0, hi
1156 ; CHECK-NOFP16-NEXT: ret
1158 ; CHECK-FP16-LABEL: fcmps_ugt_f16:
1159 ; CHECK-FP16: // %bb.0:
1160 ; CHECK-FP16-NEXT: fcmpe h0, h1
1161 ; CHECK-FP16-NEXT: cset w0, hi
1162 ; CHECK-FP16-NEXT: ret
1163 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ugt", metadata !"fpexcept.strict") #0
1164 %conv = zext i1 %cmp to i32
1168 define i32 @fcmps_uge_f16(half %a, half %b) #0 {
1169 ; CHECK-NOFP16-LABEL: fcmps_uge_f16:
1170 ; CHECK-NOFP16: // %bb.0:
1171 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1172 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1173 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1174 ; CHECK-NOFP16-NEXT: cset w0, pl
1175 ; CHECK-NOFP16-NEXT: ret
1177 ; CHECK-FP16-LABEL: fcmps_uge_f16:
1178 ; CHECK-FP16: // %bb.0:
1179 ; CHECK-FP16-NEXT: fcmpe h0, h1
1180 ; CHECK-FP16-NEXT: cset w0, pl
1181 ; CHECK-FP16-NEXT: ret
1182 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"uge", metadata !"fpexcept.strict") #0
1183 %conv = zext i1 %cmp to i32
1187 define i32 @fcmps_ueq_f16(half %a, half %b) #0 {
1188 ; CHECK-NOFP16-LABEL: fcmps_ueq_f16:
1189 ; CHECK-NOFP16: // %bb.0:
1190 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1191 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1192 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1193 ; CHECK-NOFP16-NEXT: cset w8, eq
1194 ; CHECK-NOFP16-NEXT: csinc w0, w8, wzr, vc
1195 ; CHECK-NOFP16-NEXT: ret
1197 ; CHECK-FP16-LABEL: fcmps_ueq_f16:
1198 ; CHECK-FP16: // %bb.0:
1199 ; CHECK-FP16-NEXT: fcmpe h0, h1
1200 ; CHECK-FP16-NEXT: cset w8, eq
1201 ; CHECK-FP16-NEXT: csinc w0, w8, wzr, vc
1202 ; CHECK-FP16-NEXT: ret
1203 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ueq", metadata !"fpexcept.strict") #0
1204 %conv = zext i1 %cmp to i32
1208 define i32 @fcmps_une_f16(half %a, half %b) #0 {
1209 ; CHECK-NOFP16-LABEL: fcmps_une_f16:
1210 ; CHECK-NOFP16: // %bb.0:
1211 ; CHECK-NOFP16-NEXT: fcvt s0, h0
1212 ; CHECK-NOFP16-NEXT: fcvt s1, h1
1213 ; CHECK-NOFP16-NEXT: fcmpe s0, s1
1214 ; CHECK-NOFP16-NEXT: cset w0, ne
1215 ; CHECK-NOFP16-NEXT: ret
1217 ; CHECK-FP16-LABEL: fcmps_une_f16:
1218 ; CHECK-FP16: // %bb.0:
1219 ; CHECK-FP16-NEXT: fcmpe h0, h1
1220 ; CHECK-FP16-NEXT: cset w0, ne
1221 ; CHECK-FP16-NEXT: ret
1222 %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"une", metadata !"fpexcept.strict") #0
1223 %conv = zext i1 %cmp to i32
1228 ; Intrinsics to convert between floating-point types
1230 define half @fptrunc_f16_f32(float %x) #0 {
1231 ; CHECK-LABEL: fptrunc_f16_f32:
1233 ; CHECK-NEXT: fcvt h0, s0
1235 %val = call half @llvm.experimental.constrained.fptrunc.f16.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
1239 define float @fpext_f32_f16(half %x) #0 {
1240 ; CHECK-LABEL: fpext_f32_f16:
1242 ; CHECK-NEXT: fcvt s0, h0
1244 %val = call float @llvm.experimental.constrained.fpext.f32.f16(half %x, metadata !"fpexcept.strict") #0
1249 attributes #0 = { strictfp }
1251 declare half @llvm.experimental.constrained.fadd.f16(half, half, metadata, metadata)
1252 declare half @llvm.experimental.constrained.fsub.f16(half, half, metadata, metadata)
1253 declare half @llvm.experimental.constrained.fmul.f16(half, half, metadata, metadata)
1254 declare half @llvm.experimental.constrained.fdiv.f16(half, half, metadata, metadata)
1255 declare half @llvm.experimental.constrained.frem.f16(half, half, metadata, metadata)
1256 declare half @llvm.experimental.constrained.fma.f16(half, half, half, metadata, metadata)
1257 declare i32 @llvm.experimental.constrained.fptosi.i32.f16(half, metadata)
1258 declare i32 @llvm.experimental.constrained.fptoui.i32.f16(half, metadata)
1259 declare i64 @llvm.experimental.constrained.fptosi.i64.f16(half, metadata)
1260 declare i64 @llvm.experimental.constrained.fptoui.i64.f16(half, metadata)
1261 declare half @llvm.experimental.constrained.sitofp.f16.i32(i32, metadata, metadata)
1262 declare half @llvm.experimental.constrained.uitofp.f16.i32(i32, metadata, metadata)
1263 declare half @llvm.experimental.constrained.sitofp.f16.i64(i64, metadata, metadata)
1264 declare half @llvm.experimental.constrained.uitofp.f16.i64(i64, metadata, metadata)
1265 declare half @llvm.experimental.constrained.sitofp.f16.i128(i128, metadata, metadata)
1266 declare half @llvm.experimental.constrained.uitofp.f16.i128(i128, metadata, metadata)
1267 declare half @llvm.experimental.constrained.sqrt.f16(half, metadata, metadata)
1268 declare half @llvm.experimental.constrained.powi.f16(half, i32, metadata, metadata)
1269 declare half @llvm.experimental.constrained.sin.f16(half, metadata, metadata)
1270 declare half @llvm.experimental.constrained.cos.f16(half, metadata, metadata)
1271 declare half @llvm.experimental.constrained.tan.f16(half, metadata, metadata)
1272 declare half @llvm.experimental.constrained.pow.f16(half, half, metadata, metadata)
1273 declare half @llvm.experimental.constrained.log.f16(half, metadata, metadata)
1274 declare half @llvm.experimental.constrained.log10.f16(half, metadata, metadata)
1275 declare half @llvm.experimental.constrained.log2.f16(half, metadata, metadata)
1276 declare half @llvm.experimental.constrained.exp.f16(half, metadata, metadata)
1277 declare half @llvm.experimental.constrained.exp2.f16(half, metadata, metadata)
1278 declare half @llvm.experimental.constrained.rint.f16(half, metadata, metadata)
1279 declare half @llvm.experimental.constrained.nearbyint.f16(half, metadata, metadata)
1280 declare i32 @llvm.experimental.constrained.lrint.i32.f16(half, metadata, metadata)
1281 declare i64 @llvm.experimental.constrained.llrint.i64.f16(half, metadata, metadata)
1282 declare half @llvm.experimental.constrained.maxnum.f16(half, half, metadata)
1283 declare half @llvm.experimental.constrained.minnum.f16(half, half, metadata)
1284 declare half @llvm.experimental.constrained.ceil.f16(half, metadata)
1285 declare half @llvm.experimental.constrained.floor.f16(half, metadata)
1286 declare i32 @llvm.experimental.constrained.lround.i32.f16(half, metadata)
1287 declare i64 @llvm.experimental.constrained.llround.i64.f16(half, metadata)
1288 declare half @llvm.experimental.constrained.round.f16(half, metadata)
1289 declare half @llvm.experimental.constrained.roundeven.f16(half, metadata)
1290 declare half @llvm.experimental.constrained.trunc.f16(half, metadata)
1291 declare i1 @llvm.experimental.constrained.fcmps.f16(half, half, metadata, metadata)
1292 declare i1 @llvm.experimental.constrained.fcmp.f16(half, half, metadata, metadata)
1294 declare half @llvm.experimental.constrained.fptrunc.f16.f32(float, metadata, metadata)
1295 declare float @llvm.experimental.constrained.fpext.f32.f16(half, metadata)