xref: /llvm-project/llvm/test/CodeGen/AArch64/fp-intrinsics-fp16.ll (revision c2bb056482212a6afa91f6d52274fe0a74b91720)
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 - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
5; RUN: llc -mtriple=aarch64 -global-isel=true -global-isel-abort=2 -mattr=+fullfp16 %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
6
7; Check that constrained fp intrinsics are correctly lowered.
8
9; CHECK-GI:       warning: Instruction selection used fallback path for add_f16
10; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for sub_f16
11; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for mul_f16
12; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for div_f16
13; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for frem_f16
14; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fma_f16
15; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fptosi_i32_f16
16; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fptoui_i32_f16
17; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fptosi_i64_f16
18; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fptoui_i64_f16
19; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for sitofp_f16_i32
20; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for uitofp_f16_i32
21; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for sitofp_f16_i64
22; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for uitofp_f16_i64
23; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for sitofp_f16_i128
24; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for uitofp_f16_i128
25; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for sqrt_f16
26; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for powi_f16
27; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for sin_f16
28; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for cos_f16
29; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for tan_f16
30; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for asin_f16
31; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for acos_f16
32; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for atan_f16
33; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for atan2_f16
34; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for sinh_f16
35; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for cosh_f16
36; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for tanh_f16
37; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for pow_f16
38; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for log_f16
39; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for log10_f16
40; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for log2_f16
41; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for exp_f16
42; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for exp2_f16
43; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for rint_f16
44; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for nearbyint_f16
45; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for lrint_f16
46; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for llrint_f16
47; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for maxnum_f16
48; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for minnum_f16
49; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for ceil_f16
50; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for floor_f16
51; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for lround_f16
52; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for llround_f16
53; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for round_f16
54; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for roundeven_f16
55; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for trunc_f16
56; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for ldexp_f16
57; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_olt_f16
58; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_ole_f16
59; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_ogt_f16
60; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_oge_f16
61; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_oeq_f16
62; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_one_f16
63; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_ult_f16
64; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_ule_f16
65; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_ugt_f16
66; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_uge_f16
67; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_ueq_f16
68; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmp_une_f16
69; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_olt_f16
70; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_ole_f16
71; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_ogt_f16
72; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_oge_f16
73; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_oeq_f16
74; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_one_f16
75; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_ult_f16
76; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_ule_f16
77; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_ugt_f16
78; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_uge_f16
79; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_ueq_f16
80; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fcmps_une_f16
81; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fptrunc_f16_f32
82; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for fpext_f32_f16
83
84; Half-precision intrinsics
85
86define half @add_f16(half %x, half %y) #0 {
87; CHECK-NOFP16-LABEL: add_f16:
88; CHECK-NOFP16:       // %bb.0:
89; CHECK-NOFP16-NEXT:    fcvt s1, h1
90; CHECK-NOFP16-NEXT:    fcvt s0, h0
91; CHECK-NOFP16-NEXT:    fadd s0, s0, s1
92; CHECK-NOFP16-NEXT:    fcvt h0, s0
93; CHECK-NOFP16-NEXT:    ret
94;
95; CHECK-FP16-LABEL: add_f16:
96; CHECK-FP16:       // %bb.0:
97; CHECK-FP16-NEXT:    fadd h0, h0, h1
98; CHECK-FP16-NEXT:    ret
99  %val = call half @llvm.experimental.constrained.fadd.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
100  ret half %val
101}
102
103define half @sub_f16(half %x, half %y) #0 {
104; CHECK-NOFP16-LABEL: sub_f16:
105; CHECK-NOFP16:       // %bb.0:
106; CHECK-NOFP16-NEXT:    fcvt s1, h1
107; CHECK-NOFP16-NEXT:    fcvt s0, h0
108; CHECK-NOFP16-NEXT:    fsub s0, s0, s1
109; CHECK-NOFP16-NEXT:    fcvt h0, s0
110; CHECK-NOFP16-NEXT:    ret
111;
112; CHECK-FP16-LABEL: sub_f16:
113; CHECK-FP16:       // %bb.0:
114; CHECK-FP16-NEXT:    fsub h0, h0, h1
115; CHECK-FP16-NEXT:    ret
116  %val = call half @llvm.experimental.constrained.fsub.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
117  ret half %val
118}
119
120define half @mul_f16(half %x, half %y) #0 {
121; CHECK-NOFP16-LABEL: mul_f16:
122; CHECK-NOFP16:       // %bb.0:
123; CHECK-NOFP16-NEXT:    fcvt s1, h1
124; CHECK-NOFP16-NEXT:    fcvt s0, h0
125; CHECK-NOFP16-NEXT:    fmul s0, s0, s1
126; CHECK-NOFP16-NEXT:    fcvt h0, s0
127; CHECK-NOFP16-NEXT:    ret
128;
129; CHECK-FP16-LABEL: mul_f16:
130; CHECK-FP16:       // %bb.0:
131; CHECK-FP16-NEXT:    fmul h0, h0, h1
132; CHECK-FP16-NEXT:    ret
133  %val = call half @llvm.experimental.constrained.fmul.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
134  ret half %val
135}
136
137define half @div_f16(half %x, half %y) #0 {
138; CHECK-NOFP16-LABEL: div_f16:
139; CHECK-NOFP16:       // %bb.0:
140; CHECK-NOFP16-NEXT:    fcvt s1, h1
141; CHECK-NOFP16-NEXT:    fcvt s0, h0
142; CHECK-NOFP16-NEXT:    fdiv s0, s0, s1
143; CHECK-NOFP16-NEXT:    fcvt h0, s0
144; CHECK-NOFP16-NEXT:    ret
145;
146; CHECK-FP16-LABEL: div_f16:
147; CHECK-FP16:       // %bb.0:
148; CHECK-FP16-NEXT:    fdiv h0, h0, h1
149; CHECK-FP16-NEXT:    ret
150  %val = call half @llvm.experimental.constrained.fdiv.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
151  ret half %val
152}
153
154define half @frem_f16(half %x, half %y) #0 {
155; CHECK-LABEL: frem_f16:
156; CHECK:       // %bb.0:
157; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
158; CHECK-NEXT:    .cfi_def_cfa_offset 16
159; CHECK-NEXT:    .cfi_offset w30, -16
160; CHECK-NEXT:    fcvt s1, h1
161; CHECK-NEXT:    fcvt s0, h0
162; CHECK-NEXT:    bl fmodf
163; CHECK-NEXT:    fcvt h0, s0
164; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
165; CHECK-NEXT:    ret
166  %val = call half @llvm.experimental.constrained.frem.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
167  ret half %val
168}
169
170define half @fma_f16(half %x, half %y, half %z) #0 {
171; CHECK-NOFP16-LABEL: fma_f16:
172; CHECK-NOFP16:       // %bb.0:
173; CHECK-NOFP16-NEXT:    fcvt s2, h2
174; CHECK-NOFP16-NEXT:    fcvt s1, h1
175; CHECK-NOFP16-NEXT:    fcvt s0, h0
176; CHECK-NOFP16-NEXT:    fmadd s0, s0, s1, s2
177; CHECK-NOFP16-NEXT:    fcvt h0, s0
178; CHECK-NOFP16-NEXT:    ret
179;
180; CHECK-FP16-LABEL: fma_f16:
181; CHECK-FP16:       // %bb.0:
182; CHECK-FP16-NEXT:    fmadd h0, h0, h1, h2
183; CHECK-FP16-NEXT:    ret
184  %val = call half @llvm.experimental.constrained.fma.f16(half %x, half %y, half %z, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
185  ret half %val
186}
187
188define i32 @fptosi_i32_f16(half %x) #0 {
189; CHECK-NOFP16-LABEL: fptosi_i32_f16:
190; CHECK-NOFP16:       // %bb.0:
191; CHECK-NOFP16-NEXT:    fcvt s0, h0
192; CHECK-NOFP16-NEXT:    fcvtzs w0, s0
193; CHECK-NOFP16-NEXT:    ret
194;
195; CHECK-FP16-LABEL: fptosi_i32_f16:
196; CHECK-FP16:       // %bb.0:
197; CHECK-FP16-NEXT:    fcvtzs w0, h0
198; CHECK-FP16-NEXT:    ret
199  %val = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %x, metadata !"fpexcept.strict") #0
200  ret i32 %val
201}
202
203define i32 @fptoui_i32_f16(half %x) #0 {
204; CHECK-NOFP16-LABEL: fptoui_i32_f16:
205; CHECK-NOFP16:       // %bb.0:
206; CHECK-NOFP16-NEXT:    fcvt s0, h0
207; CHECK-NOFP16-NEXT:    fcvtzu w0, s0
208; CHECK-NOFP16-NEXT:    ret
209;
210; CHECK-FP16-LABEL: fptoui_i32_f16:
211; CHECK-FP16:       // %bb.0:
212; CHECK-FP16-NEXT:    fcvtzu w0, h0
213; CHECK-FP16-NEXT:    ret
214  %val = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %x, metadata !"fpexcept.strict") #0
215  ret i32 %val
216}
217
218define i64 @fptosi_i64_f16(half %x) #0 {
219; CHECK-NOFP16-LABEL: fptosi_i64_f16:
220; CHECK-NOFP16:       // %bb.0:
221; CHECK-NOFP16-NEXT:    fcvt s0, h0
222; CHECK-NOFP16-NEXT:    fcvtzs x0, s0
223; CHECK-NOFP16-NEXT:    ret
224;
225; CHECK-FP16-LABEL: fptosi_i64_f16:
226; CHECK-FP16:       // %bb.0:
227; CHECK-FP16-NEXT:    fcvtzs x0, h0
228; CHECK-FP16-NEXT:    ret
229  %val = call i64 @llvm.experimental.constrained.fptosi.i64.f16(half %x, metadata !"fpexcept.strict") #0
230  ret i64 %val
231}
232
233define i64 @fptoui_i64_f16(half %x) #0 {
234; CHECK-NOFP16-LABEL: fptoui_i64_f16:
235; CHECK-NOFP16:       // %bb.0:
236; CHECK-NOFP16-NEXT:    fcvt s0, h0
237; CHECK-NOFP16-NEXT:    fcvtzu x0, s0
238; CHECK-NOFP16-NEXT:    ret
239;
240; CHECK-FP16-LABEL: fptoui_i64_f16:
241; CHECK-FP16:       // %bb.0:
242; CHECK-FP16-NEXT:    fcvtzu x0, h0
243; CHECK-FP16-NEXT:    ret
244  %val = call i64 @llvm.experimental.constrained.fptoui.i64.f16(half %x, metadata !"fpexcept.strict") #0
245  ret i64 %val
246}
247
248define half @sitofp_f16_i32(i32 %x) #0 {
249; CHECK-NOFP16-LABEL: sitofp_f16_i32:
250; CHECK-NOFP16:       // %bb.0:
251; CHECK-NOFP16-NEXT:    scvtf s0, w0
252; CHECK-NOFP16-NEXT:    fcvt h0, s0
253; CHECK-NOFP16-NEXT:    ret
254;
255; CHECK-FP16-LABEL: sitofp_f16_i32:
256; CHECK-FP16:       // %bb.0:
257; CHECK-FP16-NEXT:    scvtf h0, w0
258; CHECK-FP16-NEXT:    ret
259  %val = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
260  ret half %val
261}
262
263define half @uitofp_f16_i32(i32 %x) #0 {
264; CHECK-NOFP16-LABEL: uitofp_f16_i32:
265; CHECK-NOFP16:       // %bb.0:
266; CHECK-NOFP16-NEXT:    ucvtf s0, w0
267; CHECK-NOFP16-NEXT:    fcvt h0, s0
268; CHECK-NOFP16-NEXT:    ret
269;
270; CHECK-FP16-LABEL: uitofp_f16_i32:
271; CHECK-FP16:       // %bb.0:
272; CHECK-FP16-NEXT:    ucvtf h0, w0
273; CHECK-FP16-NEXT:    ret
274  %val = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
275  ret half %val
276}
277
278define half @sitofp_f16_i64(i64 %x) #0 {
279; CHECK-NOFP16-LABEL: sitofp_f16_i64:
280; CHECK-NOFP16:       // %bb.0:
281; CHECK-NOFP16-NEXT:    scvtf s0, x0
282; CHECK-NOFP16-NEXT:    fcvt h0, s0
283; CHECK-NOFP16-NEXT:    ret
284;
285; CHECK-FP16-LABEL: sitofp_f16_i64:
286; CHECK-FP16:       // %bb.0:
287; CHECK-FP16-NEXT:    scvtf h0, x0
288; CHECK-FP16-NEXT:    ret
289  %val = call half @llvm.experimental.constrained.sitofp.f16.i64(i64 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
290  ret half %val
291}
292
293define half @uitofp_f16_i64(i64 %x) #0 {
294; CHECK-NOFP16-LABEL: uitofp_f16_i64:
295; CHECK-NOFP16:       // %bb.0:
296; CHECK-NOFP16-NEXT:    ucvtf s0, x0
297; CHECK-NOFP16-NEXT:    fcvt h0, s0
298; CHECK-NOFP16-NEXT:    ret
299;
300; CHECK-FP16-LABEL: uitofp_f16_i64:
301; CHECK-FP16:       // %bb.0:
302; CHECK-FP16-NEXT:    ucvtf h0, x0
303; CHECK-FP16-NEXT:    ret
304  %val = call half @llvm.experimental.constrained.uitofp.f16.i64(i64 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
305  ret half %val
306}
307
308define half @sitofp_f16_i128(i128 %x) #0 {
309; CHECK-NOFP16-LABEL: sitofp_f16_i128:
310; CHECK-NOFP16:       // %bb.0:
311; CHECK-NOFP16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
312; CHECK-NOFP16-NEXT:    .cfi_def_cfa_offset 16
313; CHECK-NOFP16-NEXT:    .cfi_offset w30, -16
314; CHECK-NOFP16-NEXT:    bl __floattisf
315; CHECK-NOFP16-NEXT:    fcvt h0, s0
316; CHECK-NOFP16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
317; CHECK-NOFP16-NEXT:    ret
318;
319; CHECK-FP16-LABEL: sitofp_f16_i128:
320; CHECK-FP16:       // %bb.0:
321; CHECK-FP16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
322; CHECK-FP16-NEXT:    .cfi_def_cfa_offset 16
323; CHECK-FP16-NEXT:    .cfi_offset w30, -16
324; CHECK-FP16-NEXT:    bl __floattihf
325; CHECK-FP16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
326; CHECK-FP16-NEXT:    ret
327  %val = call half @llvm.experimental.constrained.sitofp.f16.i128(i128 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
328  ret half %val
329}
330
331define half @uitofp_f16_i128(i128 %x) #0 {
332; CHECK-NOFP16-LABEL: uitofp_f16_i128:
333; CHECK-NOFP16:       // %bb.0:
334; CHECK-NOFP16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
335; CHECK-NOFP16-NEXT:    .cfi_def_cfa_offset 16
336; CHECK-NOFP16-NEXT:    .cfi_offset w30, -16
337; CHECK-NOFP16-NEXT:    bl __floatuntisf
338; CHECK-NOFP16-NEXT:    fcvt h0, s0
339; CHECK-NOFP16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
340; CHECK-NOFP16-NEXT:    ret
341;
342; CHECK-FP16-LABEL: uitofp_f16_i128:
343; CHECK-FP16:       // %bb.0:
344; CHECK-FP16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
345; CHECK-FP16-NEXT:    .cfi_def_cfa_offset 16
346; CHECK-FP16-NEXT:    .cfi_offset w30, -16
347; CHECK-FP16-NEXT:    bl __floatuntihf
348; CHECK-FP16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
349; CHECK-FP16-NEXT:    ret
350  %val = call half @llvm.experimental.constrained.uitofp.f16.i128(i128 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
351  ret half %val
352}
353
354define half @sqrt_f16(half %x) #0 {
355; CHECK-NOFP16-LABEL: sqrt_f16:
356; CHECK-NOFP16:       // %bb.0:
357; CHECK-NOFP16-NEXT:    fcvt s0, h0
358; CHECK-NOFP16-NEXT:    fsqrt s0, s0
359; CHECK-NOFP16-NEXT:    fcvt h0, s0
360; CHECK-NOFP16-NEXT:    ret
361;
362; CHECK-FP16-LABEL: sqrt_f16:
363; CHECK-FP16:       // %bb.0:
364; CHECK-FP16-NEXT:    fsqrt h0, h0
365; CHECK-FP16-NEXT:    ret
366  %val = call half @llvm.experimental.constrained.sqrt.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
367  ret half %val
368}
369
370define half @powi_f16(half %x, i32 %y) #0 {
371; CHECK-LABEL: powi_f16:
372; CHECK:       // %bb.0:
373; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
374; CHECK-NEXT:    .cfi_def_cfa_offset 16
375; CHECK-NEXT:    .cfi_offset w30, -16
376; CHECK-NEXT:    fcvt s0, h0
377; CHECK-NEXT:    bl __powisf2
378; CHECK-NEXT:    fcvt h0, s0
379; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
380; CHECK-NEXT:    ret
381  %val = call half @llvm.experimental.constrained.powi.f16(half %x, i32 %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
382  ret half %val
383}
384
385define half @sin_f16(half %x) #0 {
386; CHECK-LABEL: sin_f16:
387; CHECK:       // %bb.0:
388; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
389; CHECK-NEXT:    .cfi_def_cfa_offset 16
390; CHECK-NEXT:    .cfi_offset w30, -16
391; CHECK-NEXT:    fcvt s0, h0
392; CHECK-NEXT:    bl sinf
393; CHECK-NEXT:    fcvt h0, s0
394; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
395; CHECK-NEXT:    ret
396  %val = call half @llvm.experimental.constrained.sin.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
397  ret half %val
398}
399
400define half @cos_f16(half %x) #0 {
401; CHECK-LABEL: cos_f16:
402; CHECK:       // %bb.0:
403; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
404; CHECK-NEXT:    .cfi_def_cfa_offset 16
405; CHECK-NEXT:    .cfi_offset w30, -16
406; CHECK-NEXT:    fcvt s0, h0
407; CHECK-NEXT:    bl cosf
408; CHECK-NEXT:    fcvt h0, s0
409; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
410; CHECK-NEXT:    ret
411  %val = call half @llvm.experimental.constrained.cos.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
412  ret half %val
413}
414
415define half @tan_f16(half %x) #0 {
416; CHECK-LABEL: tan_f16:
417; CHECK:       // %bb.0:
418; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
419; CHECK-NEXT:    .cfi_def_cfa_offset 16
420; CHECK-NEXT:    .cfi_offset w30, -16
421; CHECK-NEXT:    fcvt s0, h0
422; CHECK-NEXT:    bl tanf
423; CHECK-NEXT:    fcvt h0, s0
424; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
425; CHECK-NEXT:    ret
426  %val = call half @llvm.experimental.constrained.tan.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
427  ret half %val
428}
429
430define half @asin_f16(half %x) #0 {
431; CHECK-LABEL: asin_f16:
432; CHECK:       // %bb.0:
433; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
434; CHECK-NEXT:    .cfi_def_cfa_offset 16
435; CHECK-NEXT:    .cfi_offset w30, -16
436; CHECK-NEXT:    fcvt s0, h0
437; CHECK-NEXT:    bl asinf
438; CHECK-NEXT:    fcvt h0, s0
439; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
440; CHECK-NEXT:    ret
441  %val = call half @llvm.experimental.constrained.asin.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
442  ret half %val
443}
444
445define half @acos_f16(half %x) #0 {
446; CHECK-LABEL: acos_f16:
447; CHECK:       // %bb.0:
448; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
449; CHECK-NEXT:    .cfi_def_cfa_offset 16
450; CHECK-NEXT:    .cfi_offset w30, -16
451; CHECK-NEXT:    fcvt s0, h0
452; CHECK-NEXT:    bl acosf
453; CHECK-NEXT:    fcvt h0, s0
454; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
455; CHECK-NEXT:    ret
456  %val = call half @llvm.experimental.constrained.acos.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
457  ret half %val
458}
459
460define half @atan_f16(half %x) #0 {
461; CHECK-LABEL: atan_f16:
462; CHECK:       // %bb.0:
463; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
464; CHECK-NEXT:    .cfi_def_cfa_offset 16
465; CHECK-NEXT:    .cfi_offset w30, -16
466; CHECK-NEXT:    fcvt s0, h0
467; CHECK-NEXT:    bl atanf
468; CHECK-NEXT:    fcvt h0, s0
469; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
470; CHECK-NEXT:    ret
471  %val = call half @llvm.experimental.constrained.atan.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
472  ret half %val
473}
474
475define half @atan2_f16(half %x, half %y) #0 {
476; CHECK-LABEL: atan2_f16:
477; CHECK:       // %bb.0:
478; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
479; CHECK-NEXT:    .cfi_def_cfa_offset 16
480; CHECK-NEXT:    .cfi_offset w30, -16
481; CHECK-NEXT:    fcvt s1, h1
482; CHECK-NEXT:    fcvt s0, h0
483; CHECK-NEXT:    bl atan2f
484; CHECK-NEXT:    fcvt h0, s0
485; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
486; CHECK-NEXT:    ret
487  %val = call half @llvm.experimental.constrained.atan2.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
488  ret half %val
489}
490
491define half @sinh_f16(half %x) #0 {
492; CHECK-LABEL: sinh_f16:
493; CHECK:       // %bb.0:
494; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
495; CHECK-NEXT:    .cfi_def_cfa_offset 16
496; CHECK-NEXT:    .cfi_offset w30, -16
497; CHECK-NEXT:    fcvt s0, h0
498; CHECK-NEXT:    bl sinhf
499; CHECK-NEXT:    fcvt h0, s0
500; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
501; CHECK-NEXT:    ret
502  %val = call half @llvm.experimental.constrained.sinh.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
503  ret half %val
504}
505
506define half @cosh_f16(half %x) #0 {
507; CHECK-LABEL: cosh_f16:
508; CHECK:       // %bb.0:
509; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
510; CHECK-NEXT:    .cfi_def_cfa_offset 16
511; CHECK-NEXT:    .cfi_offset w30, -16
512; CHECK-NEXT:    fcvt s0, h0
513; CHECK-NEXT:    bl coshf
514; CHECK-NEXT:    fcvt h0, s0
515; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
516; CHECK-NEXT:    ret
517  %val = call half @llvm.experimental.constrained.cosh.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
518  ret half %val
519}
520
521define half @tanh_f16(half %x) #0 {
522; CHECK-LABEL: tanh_f16:
523; CHECK:       // %bb.0:
524; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
525; CHECK-NEXT:    .cfi_def_cfa_offset 16
526; CHECK-NEXT:    .cfi_offset w30, -16
527; CHECK-NEXT:    fcvt s0, h0
528; CHECK-NEXT:    bl tanhf
529; CHECK-NEXT:    fcvt h0, s0
530; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
531; CHECK-NEXT:    ret
532  %val = call half @llvm.experimental.constrained.tanh.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
533  ret half %val
534}
535
536define half @pow_f16(half %x, half %y) #0 {
537; CHECK-LABEL: pow_f16:
538; CHECK:       // %bb.0:
539; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
540; CHECK-NEXT:    .cfi_def_cfa_offset 16
541; CHECK-NEXT:    .cfi_offset w30, -16
542; CHECK-NEXT:    fcvt s1, h1
543; CHECK-NEXT:    fcvt s0, h0
544; CHECK-NEXT:    bl powf
545; CHECK-NEXT:    fcvt h0, s0
546; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
547; CHECK-NEXT:    ret
548  %val = call half @llvm.experimental.constrained.pow.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
549  ret half %val
550}
551
552define half @log_f16(half %x) #0 {
553; CHECK-LABEL: log_f16:
554; CHECK:       // %bb.0:
555; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
556; CHECK-NEXT:    .cfi_def_cfa_offset 16
557; CHECK-NEXT:    .cfi_offset w30, -16
558; CHECK-NEXT:    fcvt s0, h0
559; CHECK-NEXT:    bl logf
560; CHECK-NEXT:    fcvt h0, s0
561; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
562; CHECK-NEXT:    ret
563  %val = call half @llvm.experimental.constrained.log.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
564  ret half %val
565}
566
567define half @log10_f16(half %x) #0 {
568; CHECK-LABEL: log10_f16:
569; CHECK:       // %bb.0:
570; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
571; CHECK-NEXT:    .cfi_def_cfa_offset 16
572; CHECK-NEXT:    .cfi_offset w30, -16
573; CHECK-NEXT:    fcvt s0, h0
574; CHECK-NEXT:    bl log10f
575; CHECK-NEXT:    fcvt h0, s0
576; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
577; CHECK-NEXT:    ret
578  %val = call half @llvm.experimental.constrained.log10.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
579  ret half %val
580}
581
582define half @log2_f16(half %x) #0 {
583; CHECK-LABEL: log2_f16:
584; CHECK:       // %bb.0:
585; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
586; CHECK-NEXT:    .cfi_def_cfa_offset 16
587; CHECK-NEXT:    .cfi_offset w30, -16
588; CHECK-NEXT:    fcvt s0, h0
589; CHECK-NEXT:    bl log2f
590; CHECK-NEXT:    fcvt h0, s0
591; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
592; CHECK-NEXT:    ret
593  %val = call half @llvm.experimental.constrained.log2.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
594  ret half %val
595}
596
597define half @exp_f16(half %x) #0 {
598; CHECK-LABEL: exp_f16:
599; CHECK:       // %bb.0:
600; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
601; CHECK-NEXT:    .cfi_def_cfa_offset 16
602; CHECK-NEXT:    .cfi_offset w30, -16
603; CHECK-NEXT:    fcvt s0, h0
604; CHECK-NEXT:    bl expf
605; CHECK-NEXT:    fcvt h0, s0
606; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
607; CHECK-NEXT:    ret
608  %val = call half @llvm.experimental.constrained.exp.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
609  ret half %val
610}
611
612define half @exp2_f16(half %x) #0 {
613; CHECK-LABEL: exp2_f16:
614; CHECK:       // %bb.0:
615; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
616; CHECK-NEXT:    .cfi_def_cfa_offset 16
617; CHECK-NEXT:    .cfi_offset w30, -16
618; CHECK-NEXT:    fcvt s0, h0
619; CHECK-NEXT:    bl exp2f
620; CHECK-NEXT:    fcvt h0, s0
621; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
622; CHECK-NEXT:    ret
623  %val = call half @llvm.experimental.constrained.exp2.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
624  ret half %val
625}
626
627define half @rint_f16(half %x) #0 {
628; CHECK-NOFP16-LABEL: rint_f16:
629; CHECK-NOFP16:       // %bb.0:
630; CHECK-NOFP16-NEXT:    fcvt s0, h0
631; CHECK-NOFP16-NEXT:    frintx s0, s0
632; CHECK-NOFP16-NEXT:    fcvt h0, s0
633; CHECK-NOFP16-NEXT:    ret
634;
635; CHECK-FP16-LABEL: rint_f16:
636; CHECK-FP16:       // %bb.0:
637; CHECK-FP16-NEXT:    frintx h0, h0
638; CHECK-FP16-NEXT:    ret
639  %val = call half @llvm.experimental.constrained.rint.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
640  ret half %val
641}
642
643define half @nearbyint_f16(half %x) #0 {
644; CHECK-NOFP16-LABEL: nearbyint_f16:
645; CHECK-NOFP16:       // %bb.0:
646; CHECK-NOFP16-NEXT:    fcvt s0, h0
647; CHECK-NOFP16-NEXT:    frinti s0, s0
648; CHECK-NOFP16-NEXT:    fcvt h0, s0
649; CHECK-NOFP16-NEXT:    ret
650;
651; CHECK-FP16-LABEL: nearbyint_f16:
652; CHECK-FP16:       // %bb.0:
653; CHECK-FP16-NEXT:    frinti h0, h0
654; CHECK-FP16-NEXT:    ret
655  %val = call half @llvm.experimental.constrained.nearbyint.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
656  ret half %val
657}
658
659define i32 @lrint_f16(half %x) #0 {
660; CHECK-NOFP16-LABEL: lrint_f16:
661; CHECK-NOFP16:       // %bb.0:
662; CHECK-NOFP16-NEXT:    fcvt s0, h0
663; CHECK-NOFP16-NEXT:    frintx s0, s0
664; CHECK-NOFP16-NEXT:    fcvtzs w0, s0
665; CHECK-NOFP16-NEXT:    ret
666;
667; CHECK-FP16-LABEL: lrint_f16:
668; CHECK-FP16:       // %bb.0:
669; CHECK-FP16-NEXT:    frintx h0, h0
670; CHECK-FP16-NEXT:    fcvtzs w0, h0
671; CHECK-FP16-NEXT:    ret
672  %val = call i32 @llvm.experimental.constrained.lrint.i32.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
673  ret i32 %val
674}
675
676define i64 @llrint_f16(half %x) #0 {
677; CHECK-NOFP16-LABEL: llrint_f16:
678; CHECK-NOFP16:       // %bb.0:
679; CHECK-NOFP16-NEXT:    fcvt s0, h0
680; CHECK-NOFP16-NEXT:    frintx s0, s0
681; CHECK-NOFP16-NEXT:    fcvtzs x0, s0
682; CHECK-NOFP16-NEXT:    ret
683;
684; CHECK-FP16-LABEL: llrint_f16:
685; CHECK-FP16:       // %bb.0:
686; CHECK-FP16-NEXT:    frintx h0, h0
687; CHECK-FP16-NEXT:    fcvtzs x0, h0
688; CHECK-FP16-NEXT:    ret
689  %val = call i64 @llvm.experimental.constrained.llrint.i64.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
690  ret i64 %val
691}
692
693define half @maxnum_f16(half %x, half %y) #0 {
694; CHECK-NOFP16-LABEL: maxnum_f16:
695; CHECK-NOFP16:       // %bb.0:
696; CHECK-NOFP16-NEXT:    fcvt s1, h1
697; CHECK-NOFP16-NEXT:    fcvt s0, h0
698; CHECK-NOFP16-NEXT:    fmaxnm s0, s0, s1
699; CHECK-NOFP16-NEXT:    fcvt h0, s0
700; CHECK-NOFP16-NEXT:    ret
701;
702; CHECK-FP16-LABEL: maxnum_f16:
703; CHECK-FP16:       // %bb.0:
704; CHECK-FP16-NEXT:    fmaxnm h0, h0, h1
705; CHECK-FP16-NEXT:    ret
706  %val = call half @llvm.experimental.constrained.maxnum.f16(half %x, half %y, metadata !"fpexcept.strict") #0
707  ret half %val
708}
709
710define half @minnum_f16(half %x, half %y) #0 {
711; CHECK-NOFP16-LABEL: minnum_f16:
712; CHECK-NOFP16:       // %bb.0:
713; CHECK-NOFP16-NEXT:    fcvt s1, h1
714; CHECK-NOFP16-NEXT:    fcvt s0, h0
715; CHECK-NOFP16-NEXT:    fminnm s0, s0, s1
716; CHECK-NOFP16-NEXT:    fcvt h0, s0
717; CHECK-NOFP16-NEXT:    ret
718;
719; CHECK-FP16-LABEL: minnum_f16:
720; CHECK-FP16:       // %bb.0:
721; CHECK-FP16-NEXT:    fminnm h0, h0, h1
722; CHECK-FP16-NEXT:    ret
723  %val = call half @llvm.experimental.constrained.minnum.f16(half %x, half %y, metadata !"fpexcept.strict") #0
724  ret half %val
725}
726
727define half @ceil_f16(half %x) #0 {
728; CHECK-NOFP16-LABEL: ceil_f16:
729; CHECK-NOFP16:       // %bb.0:
730; CHECK-NOFP16-NEXT:    fcvt s0, h0
731; CHECK-NOFP16-NEXT:    frintp s0, s0
732; CHECK-NOFP16-NEXT:    fcvt h0, s0
733; CHECK-NOFP16-NEXT:    ret
734;
735; CHECK-FP16-LABEL: ceil_f16:
736; CHECK-FP16:       // %bb.0:
737; CHECK-FP16-NEXT:    frintp h0, h0
738; CHECK-FP16-NEXT:    ret
739  %val = call half @llvm.experimental.constrained.ceil.f16(half %x, metadata !"fpexcept.strict") #0
740  ret half %val
741}
742
743define half @floor_f16(half %x) #0 {
744; CHECK-NOFP16-LABEL: floor_f16:
745; CHECK-NOFP16:       // %bb.0:
746; CHECK-NOFP16-NEXT:    fcvt s0, h0
747; CHECK-NOFP16-NEXT:    frintm s0, s0
748; CHECK-NOFP16-NEXT:    fcvt h0, s0
749; CHECK-NOFP16-NEXT:    ret
750;
751; CHECK-FP16-LABEL: floor_f16:
752; CHECK-FP16:       // %bb.0:
753; CHECK-FP16-NEXT:    frintm h0, h0
754; CHECK-FP16-NEXT:    ret
755  %val = call half @llvm.experimental.constrained.floor.f16(half %x, metadata !"fpexcept.strict") #0
756  ret half %val
757}
758
759define i32 @lround_f16(half %x) #0 {
760; CHECK-NOFP16-LABEL: lround_f16:
761; CHECK-NOFP16:       // %bb.0:
762; CHECK-NOFP16-NEXT:    fcvt s0, h0
763; CHECK-NOFP16-NEXT:    fcvtas w0, s0
764; CHECK-NOFP16-NEXT:    ret
765;
766; CHECK-FP16-LABEL: lround_f16:
767; CHECK-FP16:       // %bb.0:
768; CHECK-FP16-NEXT:    fcvtas w0, h0
769; CHECK-FP16-NEXT:    ret
770  %val = call i32 @llvm.experimental.constrained.lround.i32.f16(half %x, metadata !"fpexcept.strict") #0
771  ret i32 %val
772}
773
774define i64 @llround_f16(half %x) #0 {
775; CHECK-NOFP16-LABEL: llround_f16:
776; CHECK-NOFP16:       // %bb.0:
777; CHECK-NOFP16-NEXT:    fcvt s0, h0
778; CHECK-NOFP16-NEXT:    fcvtas x0, s0
779; CHECK-NOFP16-NEXT:    ret
780;
781; CHECK-FP16-LABEL: llround_f16:
782; CHECK-FP16:       // %bb.0:
783; CHECK-FP16-NEXT:    fcvtas x0, h0
784; CHECK-FP16-NEXT:    ret
785  %val = call i64 @llvm.experimental.constrained.llround.i64.f16(half %x, metadata !"fpexcept.strict") #0
786  ret i64 %val
787}
788
789define half @round_f16(half %x) #0 {
790; CHECK-NOFP16-LABEL: round_f16:
791; CHECK-NOFP16:       // %bb.0:
792; CHECK-NOFP16-NEXT:    fcvt s0, h0
793; CHECK-NOFP16-NEXT:    frinta s0, s0
794; CHECK-NOFP16-NEXT:    fcvt h0, s0
795; CHECK-NOFP16-NEXT:    ret
796;
797; CHECK-FP16-LABEL: round_f16:
798; CHECK-FP16:       // %bb.0:
799; CHECK-FP16-NEXT:    frinta h0, h0
800; CHECK-FP16-NEXT:    ret
801  %val = call half @llvm.experimental.constrained.round.f16(half %x, metadata !"fpexcept.strict") #0
802  ret half %val
803}
804
805define half @roundeven_f16(half %x) #0 {
806; CHECK-NOFP16-LABEL: roundeven_f16:
807; CHECK-NOFP16:       // %bb.0:
808; CHECK-NOFP16-NEXT:    fcvt s0, h0
809; CHECK-NOFP16-NEXT:    frintn s0, s0
810; CHECK-NOFP16-NEXT:    fcvt h0, s0
811; CHECK-NOFP16-NEXT:    ret
812;
813; CHECK-FP16-LABEL: roundeven_f16:
814; CHECK-FP16:       // %bb.0:
815; CHECK-FP16-NEXT:    frintn h0, h0
816; CHECK-FP16-NEXT:    ret
817  %val = call half @llvm.experimental.constrained.roundeven.f16(half %x, metadata !"fpexcept.strict") #0
818  ret half %val
819}
820
821define half @trunc_f16(half %x) #0 {
822; CHECK-NOFP16-LABEL: trunc_f16:
823; CHECK-NOFP16:       // %bb.0:
824; CHECK-NOFP16-NEXT:    fcvt s0, h0
825; CHECK-NOFP16-NEXT:    frintz s0, s0
826; CHECK-NOFP16-NEXT:    fcvt h0, s0
827; CHECK-NOFP16-NEXT:    ret
828;
829; CHECK-FP16-LABEL: trunc_f16:
830; CHECK-FP16:       // %bb.0:
831; CHECK-FP16-NEXT:    frintz h0, h0
832; CHECK-FP16-NEXT:    ret
833  %val = call half @llvm.experimental.constrained.trunc.f16(half %x, metadata !"fpexcept.strict") #0
834  ret half %val
835}
836
837define half @ldexp_f16(half %x, i32 %y) #0 {
838; CHECK-LABEL: ldexp_f16:
839; CHECK:       // %bb.0:
840; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
841; CHECK-NEXT:    .cfi_def_cfa_offset 16
842; CHECK-NEXT:    .cfi_offset w30, -16
843; CHECK-NEXT:    fcvt s0, h0
844; CHECK-NEXT:    bl ldexpf
845; CHECK-NEXT:    fcvt h0, s0
846; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
847; CHECK-NEXT:    ret
848  %val = call half @llvm.experimental.constrained.ldexp.f16.i32(half %x, i32 %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
849  ret half %val
850}
851
852define i32 @fcmp_olt_f16(half %a, half %b) #0 {
853; CHECK-NOFP16-LABEL: fcmp_olt_f16:
854; CHECK-NOFP16:       // %bb.0:
855; CHECK-NOFP16-NEXT:    fcvt s0, h0
856; CHECK-NOFP16-NEXT:    fcvt s1, h1
857; CHECK-NOFP16-NEXT:    fcmp s0, s1
858; CHECK-NOFP16-NEXT:    cset w0, mi
859; CHECK-NOFP16-NEXT:    ret
860;
861; CHECK-FP16-LABEL: fcmp_olt_f16:
862; CHECK-FP16:       // %bb.0:
863; CHECK-FP16-NEXT:    fcmp h0, h1
864; CHECK-FP16-NEXT:    cset w0, mi
865; CHECK-FP16-NEXT:    ret
866  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict") #0
867  %conv = zext i1 %cmp to i32
868  ret i32 %conv
869}
870
871define i32 @fcmp_ole_f16(half %a, half %b) #0 {
872; CHECK-NOFP16-LABEL: fcmp_ole_f16:
873; CHECK-NOFP16:       // %bb.0:
874; CHECK-NOFP16-NEXT:    fcvt s0, h0
875; CHECK-NOFP16-NEXT:    fcvt s1, h1
876; CHECK-NOFP16-NEXT:    fcmp s0, s1
877; CHECK-NOFP16-NEXT:    cset w0, ls
878; CHECK-NOFP16-NEXT:    ret
879;
880; CHECK-FP16-LABEL: fcmp_ole_f16:
881; CHECK-FP16:       // %bb.0:
882; CHECK-FP16-NEXT:    fcmp h0, h1
883; CHECK-FP16-NEXT:    cset w0, ls
884; CHECK-FP16-NEXT:    ret
885  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict") #0
886  %conv = zext i1 %cmp to i32
887  ret i32 %conv
888}
889
890define i32 @fcmp_ogt_f16(half %a, half %b) #0 {
891; CHECK-NOFP16-LABEL: fcmp_ogt_f16:
892; CHECK-NOFP16:       // %bb.0:
893; CHECK-NOFP16-NEXT:    fcvt s0, h0
894; CHECK-NOFP16-NEXT:    fcvt s1, h1
895; CHECK-NOFP16-NEXT:    fcmp s0, s1
896; CHECK-NOFP16-NEXT:    cset w0, gt
897; CHECK-NOFP16-NEXT:    ret
898;
899; CHECK-FP16-LABEL: fcmp_ogt_f16:
900; CHECK-FP16:       // %bb.0:
901; CHECK-FP16-NEXT:    fcmp h0, h1
902; CHECK-FP16-NEXT:    cset w0, gt
903; CHECK-FP16-NEXT:    ret
904  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ogt", metadata !"fpexcept.strict") #0
905  %conv = zext i1 %cmp to i32
906  ret i32 %conv
907}
908
909define i32 @fcmp_oge_f16(half %a, half %b) #0 {
910; CHECK-NOFP16-LABEL: fcmp_oge_f16:
911; CHECK-NOFP16:       // %bb.0:
912; CHECK-NOFP16-NEXT:    fcvt s0, h0
913; CHECK-NOFP16-NEXT:    fcvt s1, h1
914; CHECK-NOFP16-NEXT:    fcmp s0, s1
915; CHECK-NOFP16-NEXT:    cset w0, ge
916; CHECK-NOFP16-NEXT:    ret
917;
918; CHECK-FP16-LABEL: fcmp_oge_f16:
919; CHECK-FP16:       // %bb.0:
920; CHECK-FP16-NEXT:    fcmp h0, h1
921; CHECK-FP16-NEXT:    cset w0, ge
922; CHECK-FP16-NEXT:    ret
923  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"oge", metadata !"fpexcept.strict") #0
924  %conv = zext i1 %cmp to i32
925  ret i32 %conv
926}
927
928define i32 @fcmp_oeq_f16(half %a, half %b) #0 {
929; CHECK-NOFP16-LABEL: fcmp_oeq_f16:
930; CHECK-NOFP16:       // %bb.0:
931; CHECK-NOFP16-NEXT:    fcvt s0, h0
932; CHECK-NOFP16-NEXT:    fcvt s1, h1
933; CHECK-NOFP16-NEXT:    fcmp s0, s1
934; CHECK-NOFP16-NEXT:    cset w0, eq
935; CHECK-NOFP16-NEXT:    ret
936;
937; CHECK-FP16-LABEL: fcmp_oeq_f16:
938; CHECK-FP16:       // %bb.0:
939; CHECK-FP16-NEXT:    fcmp h0, h1
940; CHECK-FP16-NEXT:    cset w0, eq
941; CHECK-FP16-NEXT:    ret
942  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"oeq", metadata !"fpexcept.strict") #0
943  %conv = zext i1 %cmp to i32
944  ret i32 %conv
945}
946
947define i32 @fcmp_one_f16(half %a, half %b) #0 {
948; CHECK-NOFP16-LABEL: fcmp_one_f16:
949; CHECK-NOFP16:       // %bb.0:
950; CHECK-NOFP16-NEXT:    fcvt s0, h0
951; CHECK-NOFP16-NEXT:    fcvt s1, h1
952; CHECK-NOFP16-NEXT:    fcmp s0, s1
953; CHECK-NOFP16-NEXT:    cset w8, mi
954; CHECK-NOFP16-NEXT:    csinc w0, w8, wzr, le
955; CHECK-NOFP16-NEXT:    ret
956;
957; CHECK-FP16-LABEL: fcmp_one_f16:
958; CHECK-FP16:       // %bb.0:
959; CHECK-FP16-NEXT:    fcmp h0, h1
960; CHECK-FP16-NEXT:    cset w8, mi
961; CHECK-FP16-NEXT:    csinc w0, w8, wzr, le
962; CHECK-FP16-NEXT:    ret
963  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"one", metadata !"fpexcept.strict") #0
964  %conv = zext i1 %cmp to i32
965  ret i32 %conv
966}
967
968define i32 @fcmp_ult_f16(half %a, half %b) #0 {
969; CHECK-NOFP16-LABEL: fcmp_ult_f16:
970; CHECK-NOFP16:       // %bb.0:
971; CHECK-NOFP16-NEXT:    fcvt s0, h0
972; CHECK-NOFP16-NEXT:    fcvt s1, h1
973; CHECK-NOFP16-NEXT:    fcmp s0, s1
974; CHECK-NOFP16-NEXT:    cset w0, lt
975; CHECK-NOFP16-NEXT:    ret
976;
977; CHECK-FP16-LABEL: fcmp_ult_f16:
978; CHECK-FP16:       // %bb.0:
979; CHECK-FP16-NEXT:    fcmp h0, h1
980; CHECK-FP16-NEXT:    cset w0, lt
981; CHECK-FP16-NEXT:    ret
982  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ult", metadata !"fpexcept.strict") #0
983  %conv = zext i1 %cmp to i32
984  ret i32 %conv
985}
986
987define i32 @fcmp_ule_f16(half %a, half %b) #0 {
988; CHECK-NOFP16-LABEL: fcmp_ule_f16:
989; CHECK-NOFP16:       // %bb.0:
990; CHECK-NOFP16-NEXT:    fcvt s0, h0
991; CHECK-NOFP16-NEXT:    fcvt s1, h1
992; CHECK-NOFP16-NEXT:    fcmp s0, s1
993; CHECK-NOFP16-NEXT:    cset w0, le
994; CHECK-NOFP16-NEXT:    ret
995;
996; CHECK-FP16-LABEL: fcmp_ule_f16:
997; CHECK-FP16:       // %bb.0:
998; CHECK-FP16-NEXT:    fcmp h0, h1
999; CHECK-FP16-NEXT:    cset w0, le
1000; CHECK-FP16-NEXT:    ret
1001  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ule", metadata !"fpexcept.strict") #0
1002  %conv = zext i1 %cmp to i32
1003  ret i32 %conv
1004}
1005
1006define i32 @fcmp_ugt_f16(half %a, half %b) #0 {
1007; CHECK-NOFP16-LABEL: fcmp_ugt_f16:
1008; CHECK-NOFP16:       // %bb.0:
1009; CHECK-NOFP16-NEXT:    fcvt s0, h0
1010; CHECK-NOFP16-NEXT:    fcvt s1, h1
1011; CHECK-NOFP16-NEXT:    fcmp s0, s1
1012; CHECK-NOFP16-NEXT:    cset w0, hi
1013; CHECK-NOFP16-NEXT:    ret
1014;
1015; CHECK-FP16-LABEL: fcmp_ugt_f16:
1016; CHECK-FP16:       // %bb.0:
1017; CHECK-FP16-NEXT:    fcmp h0, h1
1018; CHECK-FP16-NEXT:    cset w0, hi
1019; CHECK-FP16-NEXT:    ret
1020  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ugt", metadata !"fpexcept.strict") #0
1021  %conv = zext i1 %cmp to i32
1022  ret i32 %conv
1023}
1024
1025define i32 @fcmp_uge_f16(half %a, half %b) #0 {
1026; CHECK-NOFP16-LABEL: fcmp_uge_f16:
1027; CHECK-NOFP16:       // %bb.0:
1028; CHECK-NOFP16-NEXT:    fcvt s0, h0
1029; CHECK-NOFP16-NEXT:    fcvt s1, h1
1030; CHECK-NOFP16-NEXT:    fcmp s0, s1
1031; CHECK-NOFP16-NEXT:    cset w0, pl
1032; CHECK-NOFP16-NEXT:    ret
1033;
1034; CHECK-FP16-LABEL: fcmp_uge_f16:
1035; CHECK-FP16:       // %bb.0:
1036; CHECK-FP16-NEXT:    fcmp h0, h1
1037; CHECK-FP16-NEXT:    cset w0, pl
1038; CHECK-FP16-NEXT:    ret
1039  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"uge", metadata !"fpexcept.strict") #0
1040  %conv = zext i1 %cmp to i32
1041  ret i32 %conv
1042}
1043
1044define i32 @fcmp_ueq_f16(half %a, half %b) #0 {
1045; CHECK-NOFP16-LABEL: fcmp_ueq_f16:
1046; CHECK-NOFP16:       // %bb.0:
1047; CHECK-NOFP16-NEXT:    fcvt s0, h0
1048; CHECK-NOFP16-NEXT:    fcvt s1, h1
1049; CHECK-NOFP16-NEXT:    fcmp s0, s1
1050; CHECK-NOFP16-NEXT:    cset w8, eq
1051; CHECK-NOFP16-NEXT:    csinc w0, w8, wzr, vc
1052; CHECK-NOFP16-NEXT:    ret
1053;
1054; CHECK-FP16-LABEL: fcmp_ueq_f16:
1055; CHECK-FP16:       // %bb.0:
1056; CHECK-FP16-NEXT:    fcmp h0, h1
1057; CHECK-FP16-NEXT:    cset w8, eq
1058; CHECK-FP16-NEXT:    csinc w0, w8, wzr, vc
1059; CHECK-FP16-NEXT:    ret
1060  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ueq", metadata !"fpexcept.strict") #0
1061  %conv = zext i1 %cmp to i32
1062  ret i32 %conv
1063}
1064
1065define i32 @fcmp_une_f16(half %a, half %b) #0 {
1066; CHECK-NOFP16-LABEL: fcmp_une_f16:
1067; CHECK-NOFP16:       // %bb.0:
1068; CHECK-NOFP16-NEXT:    fcvt s0, h0
1069; CHECK-NOFP16-NEXT:    fcvt s1, h1
1070; CHECK-NOFP16-NEXT:    fcmp s0, s1
1071; CHECK-NOFP16-NEXT:    cset w0, ne
1072; CHECK-NOFP16-NEXT:    ret
1073;
1074; CHECK-FP16-LABEL: fcmp_une_f16:
1075; CHECK-FP16:       // %bb.0:
1076; CHECK-FP16-NEXT:    fcmp h0, h1
1077; CHECK-FP16-NEXT:    cset w0, ne
1078; CHECK-FP16-NEXT:    ret
1079  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"une", metadata !"fpexcept.strict") #0
1080  %conv = zext i1 %cmp to i32
1081  ret i32 %conv
1082}
1083
1084define i32 @fcmps_olt_f16(half %a, half %b) #0 {
1085; CHECK-NOFP16-LABEL: fcmps_olt_f16:
1086; CHECK-NOFP16:       // %bb.0:
1087; CHECK-NOFP16-NEXT:    fcvt s0, h0
1088; CHECK-NOFP16-NEXT:    fcvt s1, h1
1089; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1090; CHECK-NOFP16-NEXT:    cset w0, mi
1091; CHECK-NOFP16-NEXT:    ret
1092;
1093; CHECK-FP16-LABEL: fcmps_olt_f16:
1094; CHECK-FP16:       // %bb.0:
1095; CHECK-FP16-NEXT:    fcmpe h0, h1
1096; CHECK-FP16-NEXT:    cset w0, mi
1097; CHECK-FP16-NEXT:    ret
1098  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict") #0
1099  %conv = zext i1 %cmp to i32
1100  ret i32 %conv
1101}
1102
1103define i32 @fcmps_ole_f16(half %a, half %b) #0 {
1104; CHECK-NOFP16-LABEL: fcmps_ole_f16:
1105; CHECK-NOFP16:       // %bb.0:
1106; CHECK-NOFP16-NEXT:    fcvt s0, h0
1107; CHECK-NOFP16-NEXT:    fcvt s1, h1
1108; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1109; CHECK-NOFP16-NEXT:    cset w0, ls
1110; CHECK-NOFP16-NEXT:    ret
1111;
1112; CHECK-FP16-LABEL: fcmps_ole_f16:
1113; CHECK-FP16:       // %bb.0:
1114; CHECK-FP16-NEXT:    fcmpe h0, h1
1115; CHECK-FP16-NEXT:    cset w0, ls
1116; CHECK-FP16-NEXT:    ret
1117  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict") #0
1118  %conv = zext i1 %cmp to i32
1119  ret i32 %conv
1120}
1121
1122define i32 @fcmps_ogt_f16(half %a, half %b) #0 {
1123; CHECK-NOFP16-LABEL: fcmps_ogt_f16:
1124; CHECK-NOFP16:       // %bb.0:
1125; CHECK-NOFP16-NEXT:    fcvt s0, h0
1126; CHECK-NOFP16-NEXT:    fcvt s1, h1
1127; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1128; CHECK-NOFP16-NEXT:    cset w0, gt
1129; CHECK-NOFP16-NEXT:    ret
1130;
1131; CHECK-FP16-LABEL: fcmps_ogt_f16:
1132; CHECK-FP16:       // %bb.0:
1133; CHECK-FP16-NEXT:    fcmpe h0, h1
1134; CHECK-FP16-NEXT:    cset w0, gt
1135; CHECK-FP16-NEXT:    ret
1136  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ogt", metadata !"fpexcept.strict") #0
1137  %conv = zext i1 %cmp to i32
1138  ret i32 %conv
1139}
1140
1141define i32 @fcmps_oge_f16(half %a, half %b) #0 {
1142; CHECK-NOFP16-LABEL: fcmps_oge_f16:
1143; CHECK-NOFP16:       // %bb.0:
1144; CHECK-NOFP16-NEXT:    fcvt s0, h0
1145; CHECK-NOFP16-NEXT:    fcvt s1, h1
1146; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1147; CHECK-NOFP16-NEXT:    cset w0, ge
1148; CHECK-NOFP16-NEXT:    ret
1149;
1150; CHECK-FP16-LABEL: fcmps_oge_f16:
1151; CHECK-FP16:       // %bb.0:
1152; CHECK-FP16-NEXT:    fcmpe h0, h1
1153; CHECK-FP16-NEXT:    cset w0, ge
1154; CHECK-FP16-NEXT:    ret
1155  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"oge", metadata !"fpexcept.strict") #0
1156  %conv = zext i1 %cmp to i32
1157  ret i32 %conv
1158}
1159
1160define i32 @fcmps_oeq_f16(half %a, half %b) #0 {
1161; CHECK-NOFP16-LABEL: fcmps_oeq_f16:
1162; CHECK-NOFP16:       // %bb.0:
1163; CHECK-NOFP16-NEXT:    fcvt s0, h0
1164; CHECK-NOFP16-NEXT:    fcvt s1, h1
1165; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1166; CHECK-NOFP16-NEXT:    cset w0, eq
1167; CHECK-NOFP16-NEXT:    ret
1168;
1169; CHECK-FP16-LABEL: fcmps_oeq_f16:
1170; CHECK-FP16:       // %bb.0:
1171; CHECK-FP16-NEXT:    fcmpe h0, h1
1172; CHECK-FP16-NEXT:    cset w0, eq
1173; CHECK-FP16-NEXT:    ret
1174  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"oeq", metadata !"fpexcept.strict") #0
1175  %conv = zext i1 %cmp to i32
1176  ret i32 %conv
1177}
1178
1179define i32 @fcmps_one_f16(half %a, half %b) #0 {
1180; CHECK-NOFP16-LABEL: fcmps_one_f16:
1181; CHECK-NOFP16:       // %bb.0:
1182; CHECK-NOFP16-NEXT:    fcvt s0, h0
1183; CHECK-NOFP16-NEXT:    fcvt s1, h1
1184; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1185; CHECK-NOFP16-NEXT:    cset w8, mi
1186; CHECK-NOFP16-NEXT:    csinc w0, w8, wzr, le
1187; CHECK-NOFP16-NEXT:    ret
1188;
1189; CHECK-FP16-LABEL: fcmps_one_f16:
1190; CHECK-FP16:       // %bb.0:
1191; CHECK-FP16-NEXT:    fcmpe h0, h1
1192; CHECK-FP16-NEXT:    cset w8, mi
1193; CHECK-FP16-NEXT:    csinc w0, w8, wzr, le
1194; CHECK-FP16-NEXT:    ret
1195  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"one", metadata !"fpexcept.strict") #0
1196  %conv = zext i1 %cmp to i32
1197  ret i32 %conv
1198}
1199
1200define i32 @fcmps_ult_f16(half %a, half %b) #0 {
1201; CHECK-NOFP16-LABEL: fcmps_ult_f16:
1202; CHECK-NOFP16:       // %bb.0:
1203; CHECK-NOFP16-NEXT:    fcvt s0, h0
1204; CHECK-NOFP16-NEXT:    fcvt s1, h1
1205; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1206; CHECK-NOFP16-NEXT:    cset w0, lt
1207; CHECK-NOFP16-NEXT:    ret
1208;
1209; CHECK-FP16-LABEL: fcmps_ult_f16:
1210; CHECK-FP16:       // %bb.0:
1211; CHECK-FP16-NEXT:    fcmpe h0, h1
1212; CHECK-FP16-NEXT:    cset w0, lt
1213; CHECK-FP16-NEXT:    ret
1214  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ult", metadata !"fpexcept.strict") #0
1215  %conv = zext i1 %cmp to i32
1216  ret i32 %conv
1217}
1218
1219define i32 @fcmps_ule_f16(half %a, half %b) #0 {
1220; CHECK-NOFP16-LABEL: fcmps_ule_f16:
1221; CHECK-NOFP16:       // %bb.0:
1222; CHECK-NOFP16-NEXT:    fcvt s0, h0
1223; CHECK-NOFP16-NEXT:    fcvt s1, h1
1224; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1225; CHECK-NOFP16-NEXT:    cset w0, le
1226; CHECK-NOFP16-NEXT:    ret
1227;
1228; CHECK-FP16-LABEL: fcmps_ule_f16:
1229; CHECK-FP16:       // %bb.0:
1230; CHECK-FP16-NEXT:    fcmpe h0, h1
1231; CHECK-FP16-NEXT:    cset w0, le
1232; CHECK-FP16-NEXT:    ret
1233  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ule", metadata !"fpexcept.strict") #0
1234  %conv = zext i1 %cmp to i32
1235  ret i32 %conv
1236}
1237
1238define i32 @fcmps_ugt_f16(half %a, half %b) #0 {
1239; CHECK-NOFP16-LABEL: fcmps_ugt_f16:
1240; CHECK-NOFP16:       // %bb.0:
1241; CHECK-NOFP16-NEXT:    fcvt s0, h0
1242; CHECK-NOFP16-NEXT:    fcvt s1, h1
1243; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1244; CHECK-NOFP16-NEXT:    cset w0, hi
1245; CHECK-NOFP16-NEXT:    ret
1246;
1247; CHECK-FP16-LABEL: fcmps_ugt_f16:
1248; CHECK-FP16:       // %bb.0:
1249; CHECK-FP16-NEXT:    fcmpe h0, h1
1250; CHECK-FP16-NEXT:    cset w0, hi
1251; CHECK-FP16-NEXT:    ret
1252  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ugt", metadata !"fpexcept.strict") #0
1253  %conv = zext i1 %cmp to i32
1254  ret i32 %conv
1255}
1256
1257define i32 @fcmps_uge_f16(half %a, half %b) #0 {
1258; CHECK-NOFP16-LABEL: fcmps_uge_f16:
1259; CHECK-NOFP16:       // %bb.0:
1260; CHECK-NOFP16-NEXT:    fcvt s0, h0
1261; CHECK-NOFP16-NEXT:    fcvt s1, h1
1262; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1263; CHECK-NOFP16-NEXT:    cset w0, pl
1264; CHECK-NOFP16-NEXT:    ret
1265;
1266; CHECK-FP16-LABEL: fcmps_uge_f16:
1267; CHECK-FP16:       // %bb.0:
1268; CHECK-FP16-NEXT:    fcmpe h0, h1
1269; CHECK-FP16-NEXT:    cset w0, pl
1270; CHECK-FP16-NEXT:    ret
1271  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"uge", metadata !"fpexcept.strict") #0
1272  %conv = zext i1 %cmp to i32
1273  ret i32 %conv
1274}
1275
1276define i32 @fcmps_ueq_f16(half %a, half %b) #0 {
1277; CHECK-NOFP16-LABEL: fcmps_ueq_f16:
1278; CHECK-NOFP16:       // %bb.0:
1279; CHECK-NOFP16-NEXT:    fcvt s0, h0
1280; CHECK-NOFP16-NEXT:    fcvt s1, h1
1281; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1282; CHECK-NOFP16-NEXT:    cset w8, eq
1283; CHECK-NOFP16-NEXT:    csinc w0, w8, wzr, vc
1284; CHECK-NOFP16-NEXT:    ret
1285;
1286; CHECK-FP16-LABEL: fcmps_ueq_f16:
1287; CHECK-FP16:       // %bb.0:
1288; CHECK-FP16-NEXT:    fcmpe h0, h1
1289; CHECK-FP16-NEXT:    cset w8, eq
1290; CHECK-FP16-NEXT:    csinc w0, w8, wzr, vc
1291; CHECK-FP16-NEXT:    ret
1292  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ueq", metadata !"fpexcept.strict") #0
1293  %conv = zext i1 %cmp to i32
1294  ret i32 %conv
1295}
1296
1297define i32 @fcmps_une_f16(half %a, half %b) #0 {
1298; CHECK-NOFP16-LABEL: fcmps_une_f16:
1299; CHECK-NOFP16:       // %bb.0:
1300; CHECK-NOFP16-NEXT:    fcvt s0, h0
1301; CHECK-NOFP16-NEXT:    fcvt s1, h1
1302; CHECK-NOFP16-NEXT:    fcmpe s0, s1
1303; CHECK-NOFP16-NEXT:    cset w0, ne
1304; CHECK-NOFP16-NEXT:    ret
1305;
1306; CHECK-FP16-LABEL: fcmps_une_f16:
1307; CHECK-FP16:       // %bb.0:
1308; CHECK-FP16-NEXT:    fcmpe h0, h1
1309; CHECK-FP16-NEXT:    cset w0, ne
1310; CHECK-FP16-NEXT:    ret
1311  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"une", metadata !"fpexcept.strict") #0
1312  %conv = zext i1 %cmp to i32
1313  ret i32 %conv
1314}
1315
1316
1317; Intrinsics to convert between floating-point types
1318
1319define half @fptrunc_f16_f32(float %x) #0 {
1320; CHECK-LABEL: fptrunc_f16_f32:
1321; CHECK:       // %bb.0:
1322; CHECK-NEXT:    fcvt h0, s0
1323; CHECK-NEXT:    ret
1324  %val = call half @llvm.experimental.constrained.fptrunc.f16.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
1325  ret half %val
1326}
1327
1328define float @fpext_f32_f16(half %x) #0 {
1329; CHECK-LABEL: fpext_f32_f16:
1330; CHECK:       // %bb.0:
1331; CHECK-NEXT:    fcvt s0, h0
1332; CHECK-NEXT:    ret
1333  %val = call float @llvm.experimental.constrained.fpext.f32.f16(half %x, metadata !"fpexcept.strict") #0
1334  ret float %val
1335}
1336
1337
1338attributes #0 = { strictfp }
1339
1340declare half @llvm.experimental.constrained.fadd.f16(half, half, metadata, metadata)
1341declare half @llvm.experimental.constrained.fsub.f16(half, half, metadata, metadata)
1342declare half @llvm.experimental.constrained.fmul.f16(half, half, metadata, metadata)
1343declare half @llvm.experimental.constrained.fdiv.f16(half, half, metadata, metadata)
1344declare half @llvm.experimental.constrained.frem.f16(half, half, metadata, metadata)
1345declare half @llvm.experimental.constrained.fma.f16(half, half, half, metadata, metadata)
1346declare i32 @llvm.experimental.constrained.fptosi.i32.f16(half, metadata)
1347declare i32 @llvm.experimental.constrained.fptoui.i32.f16(half, metadata)
1348declare i64 @llvm.experimental.constrained.fptosi.i64.f16(half, metadata)
1349declare i64 @llvm.experimental.constrained.fptoui.i64.f16(half, metadata)
1350declare half @llvm.experimental.constrained.sitofp.f16.i32(i32, metadata, metadata)
1351declare half @llvm.experimental.constrained.uitofp.f16.i32(i32, metadata, metadata)
1352declare half @llvm.experimental.constrained.sitofp.f16.i64(i64, metadata, metadata)
1353declare half @llvm.experimental.constrained.uitofp.f16.i64(i64, metadata, metadata)
1354declare half @llvm.experimental.constrained.sitofp.f16.i128(i128, metadata, metadata)
1355declare half @llvm.experimental.constrained.uitofp.f16.i128(i128, metadata, metadata)
1356declare half @llvm.experimental.constrained.sqrt.f16(half, metadata, metadata)
1357declare half @llvm.experimental.constrained.powi.f16(half, i32, metadata, metadata)
1358declare half @llvm.experimental.constrained.sin.f16(half, metadata, metadata)
1359declare half @llvm.experimental.constrained.cos.f16(half, metadata, metadata)
1360declare half @llvm.experimental.constrained.tan.f16(half, metadata, metadata)
1361declare half @llvm.experimental.constrained.pow.f16(half, half, metadata, metadata)
1362declare half @llvm.experimental.constrained.log.f16(half, metadata, metadata)
1363declare half @llvm.experimental.constrained.log10.f16(half, metadata, metadata)
1364declare half @llvm.experimental.constrained.log2.f16(half, metadata, metadata)
1365declare half @llvm.experimental.constrained.exp.f16(half, metadata, metadata)
1366declare half @llvm.experimental.constrained.exp2.f16(half, metadata, metadata)
1367declare half @llvm.experimental.constrained.rint.f16(half, metadata, metadata)
1368declare half @llvm.experimental.constrained.nearbyint.f16(half, metadata, metadata)
1369declare i32 @llvm.experimental.constrained.lrint.i32.f16(half, metadata, metadata)
1370declare i64 @llvm.experimental.constrained.llrint.i64.f16(half, metadata, metadata)
1371declare half @llvm.experimental.constrained.maxnum.f16(half, half, metadata)
1372declare half @llvm.experimental.constrained.minnum.f16(half, half, metadata)
1373declare half @llvm.experimental.constrained.ceil.f16(half, metadata)
1374declare half @llvm.experimental.constrained.floor.f16(half, metadata)
1375declare i32 @llvm.experimental.constrained.lround.i32.f16(half, metadata)
1376declare i64 @llvm.experimental.constrained.llround.i64.f16(half, metadata)
1377declare half @llvm.experimental.constrained.round.f16(half, metadata)
1378declare half @llvm.experimental.constrained.roundeven.f16(half, metadata)
1379declare half @llvm.experimental.constrained.trunc.f16(half, metadata)
1380declare i1 @llvm.experimental.constrained.fcmps.f16(half, half, metadata, metadata)
1381declare i1 @llvm.experimental.constrained.fcmp.f16(half, half, metadata, metadata)
1382
1383declare half @llvm.experimental.constrained.fptrunc.f16.f32(float, metadata, metadata)
1384declare float @llvm.experimental.constrained.fpext.f32.f16(half, metadata)
1385