xref: /llvm-project/llvm/test/CodeGen/AArch64/bf16-instructions.ll (revision 5a81a559d69fb84e1e8ef623ac4b642081c14c51)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2; RUN: llc < %s -mtriple aarch64-unknown-unknown | FileCheck %s --check-prefixes=CHECK,CHECK-CVT
3; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+bf16 | FileCheck %s --check-prefixes=CHECK,CHECK-BF16,CHECK-SD
4; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+bf16,+fullfp16 -global-isel -global-isel-abort=2 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-BF16,CHECK-GI
5
6; CHECK-GI:       warning: Instruction selection used fallback path for test_fadd
7; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fsub
8; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fmul
9; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fmadd
10; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fdiv
11; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_frem
12; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_call
13; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_call_flipped
14; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_tailcall_flipped
15; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_select_cc
16; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_select_cc_f32_f16
17; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_une
18; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_ueq
19; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_ugt
20; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_uge
21; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_ult
22; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_ule
23; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_uno
24; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_one
25; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_oeq
26; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_ogt
27; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_oge
28; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_olt
29; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_ole
30; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fcmp_ord
31; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fccmp
32; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_br_cc
33; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fptosi_i32
34; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fptosi_i64
35; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fptoui_i32
36; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fptoui_i64
37; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_uitofp_i32
38; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_uitofp_i64
39; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_sitofp_i32
40; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_sitofp_i64
41; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_uitofp_i32_fadd
42; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_sitofp_i32_fadd
43; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fptrunc_float
44; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fptrunc_double
45; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fpext_float
46; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fpext_double
47; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_sqrt
48; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_powi
49; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_sin
50; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_cos
51; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_tan
52; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_acos
53; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_asin
54; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_atan
55; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_atan2
56; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_cosh
57; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_sinh
58; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_tanh
59; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_pow
60; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_exp
61; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_exp2
62; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_log
63; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_log10
64; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_log2
65; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fma
66; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fabs
67; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_minnum
68; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_maxnum
69; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_copysign
70; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_copysign_f32
71; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_copysign_f64
72; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_copysign_extended
73; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_floor
74; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_ceil
75; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_trunc
76; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_rint
77; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_nearbyint
78; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_round
79; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_roundeven
80; CHECK-GI-NEXT:  warning: Instruction selection used fallback path for test_fmuladd
81
82define bfloat @test_fadd(bfloat %a, bfloat %b) #0 {
83; CHECK-CVT-LABEL: test_fadd:
84; CHECK-CVT:       // %bb.0:
85; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
86; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
87; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
88; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
89; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
90; CHECK-CVT-NEXT:    fadd s0, s0, s1
91; CHECK-CVT-NEXT:    fmov w9, s0
92; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
93; CHECK-CVT-NEXT:    add w8, w9, w8
94; CHECK-CVT-NEXT:    add w8, w10, w8
95; CHECK-CVT-NEXT:    lsr w8, w8, #16
96; CHECK-CVT-NEXT:    fmov s0, w8
97; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
98; CHECK-CVT-NEXT:    ret
99;
100; CHECK-BF16-LABEL: test_fadd:
101; CHECK-BF16:       // %bb.0:
102; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
103; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
104; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
105; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
106; CHECK-BF16-NEXT:    fadd s0, s0, s1
107; CHECK-BF16-NEXT:    bfcvt h0, s0
108; CHECK-BF16-NEXT:    ret
109  %r = fadd bfloat %a, %b
110  ret bfloat %r
111}
112
113define bfloat @test_fsub(bfloat %a, bfloat %b) #0 {
114; CHECK-CVT-LABEL: test_fsub:
115; CHECK-CVT:       // %bb.0:
116; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
117; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
118; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
119; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
120; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
121; CHECK-CVT-NEXT:    fsub s0, s0, s1
122; CHECK-CVT-NEXT:    fmov w9, s0
123; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
124; CHECK-CVT-NEXT:    add w8, w9, w8
125; CHECK-CVT-NEXT:    add w8, w10, w8
126; CHECK-CVT-NEXT:    lsr w8, w8, #16
127; CHECK-CVT-NEXT:    fmov s0, w8
128; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
129; CHECK-CVT-NEXT:    ret
130;
131; CHECK-BF16-LABEL: test_fsub:
132; CHECK-BF16:       // %bb.0:
133; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
134; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
135; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
136; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
137; CHECK-BF16-NEXT:    fsub s0, s0, s1
138; CHECK-BF16-NEXT:    bfcvt h0, s0
139; CHECK-BF16-NEXT:    ret
140  %r = fsub bfloat %a, %b
141  ret bfloat %r
142}
143
144define bfloat @test_fmul(bfloat %a, bfloat %b) #0 {
145; CHECK-CVT-LABEL: test_fmul:
146; CHECK-CVT:       // %bb.0:
147; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
148; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
149; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
150; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
151; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
152; CHECK-CVT-NEXT:    fmul s0, s0, s1
153; CHECK-CVT-NEXT:    fmov w9, s0
154; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
155; CHECK-CVT-NEXT:    add w8, w9, w8
156; CHECK-CVT-NEXT:    add w8, w10, w8
157; CHECK-CVT-NEXT:    lsr w8, w8, #16
158; CHECK-CVT-NEXT:    fmov s0, w8
159; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
160; CHECK-CVT-NEXT:    ret
161;
162; CHECK-BF16-LABEL: test_fmul:
163; CHECK-BF16:       // %bb.0:
164; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
165; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
166; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
167; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
168; CHECK-BF16-NEXT:    fmul s0, s0, s1
169; CHECK-BF16-NEXT:    bfcvt h0, s0
170; CHECK-BF16-NEXT:    ret
171  %r = fmul bfloat %a, %b
172  ret bfloat %r
173}
174
175define bfloat @test_fmadd(bfloat %a, bfloat %b, bfloat %c) #0 {
176; CHECK-CVT-LABEL: test_fmadd:
177; CHECK-CVT:       // %bb.0:
178; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
179; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
180; CHECK-CVT-NEXT:    mov w10, #32767 // =0x7fff
181; CHECK-CVT-NEXT:    // kill: def $h2 killed $h2 def $d2
182; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
183; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
184; CHECK-CVT-NEXT:    fmul s0, s0, s1
185; CHECK-CVT-NEXT:    shll v1.4s, v2.4h, #16
186; CHECK-CVT-NEXT:    fmov w8, s0
187; CHECK-CVT-NEXT:    ubfx w9, w8, #16, #1
188; CHECK-CVT-NEXT:    add w8, w8, w10
189; CHECK-CVT-NEXT:    add w8, w9, w8
190; CHECK-CVT-NEXT:    lsr w8, w8, #16
191; CHECK-CVT-NEXT:    fmov s0, w8
192; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
193; CHECK-CVT-NEXT:    fadd s0, s0, s1
194; CHECK-CVT-NEXT:    fmov w8, s0
195; CHECK-CVT-NEXT:    ubfx w9, w8, #16, #1
196; CHECK-CVT-NEXT:    add w8, w8, w10
197; CHECK-CVT-NEXT:    add w8, w9, w8
198; CHECK-CVT-NEXT:    lsr w8, w8, #16
199; CHECK-CVT-NEXT:    fmov s0, w8
200; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
201; CHECK-CVT-NEXT:    ret
202;
203; CHECK-BF16-LABEL: test_fmadd:
204; CHECK-BF16:       // %bb.0:
205; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
206; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
207; CHECK-BF16-NEXT:    // kill: def $h2 killed $h2 def $d2
208; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
209; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
210; CHECK-BF16-NEXT:    fmul s0, s0, s1
211; CHECK-BF16-NEXT:    shll v1.4s, v2.4h, #16
212; CHECK-BF16-NEXT:    bfcvt h0, s0
213; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
214; CHECK-BF16-NEXT:    fadd s0, s0, s1
215; CHECK-BF16-NEXT:    bfcvt h0, s0
216; CHECK-BF16-NEXT:    ret
217  %mul = fmul fast bfloat %a, %b
218  %r = fadd fast bfloat %mul, %c
219  ret bfloat %r
220}
221
222define bfloat @test_fdiv(bfloat %a, bfloat %b) #0 {
223; CHECK-CVT-LABEL: test_fdiv:
224; CHECK-CVT:       // %bb.0:
225; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
226; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
227; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
228; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
229; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
230; CHECK-CVT-NEXT:    fdiv s0, s0, s1
231; CHECK-CVT-NEXT:    fmov w9, s0
232; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
233; CHECK-CVT-NEXT:    add w8, w9, w8
234; CHECK-CVT-NEXT:    add w8, w10, w8
235; CHECK-CVT-NEXT:    lsr w8, w8, #16
236; CHECK-CVT-NEXT:    fmov s0, w8
237; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
238; CHECK-CVT-NEXT:    ret
239;
240; CHECK-BF16-LABEL: test_fdiv:
241; CHECK-BF16:       // %bb.0:
242; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
243; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
244; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
245; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
246; CHECK-BF16-NEXT:    fdiv s0, s0, s1
247; CHECK-BF16-NEXT:    bfcvt h0, s0
248; CHECK-BF16-NEXT:    ret
249  %r = fdiv bfloat %a, %b
250  ret bfloat %r
251}
252
253define bfloat @test_frem(bfloat %a, bfloat %b) #0 {
254; CHECK-CVT-LABEL: test_frem:
255; CHECK-CVT:       // %bb.0:
256; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
257; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
258; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
259; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
260; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
261; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
262; CHECK-CVT-NEXT:    // kill: def $s1 killed $s1 killed $q1
263; CHECK-CVT-NEXT:    bl fmodf
264; CHECK-CVT-NEXT:    fmov w9, s0
265; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
266; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
267; CHECK-CVT-NEXT:    add w8, w9, w8
268; CHECK-CVT-NEXT:    add w8, w10, w8
269; CHECK-CVT-NEXT:    lsr w8, w8, #16
270; CHECK-CVT-NEXT:    fmov s0, w8
271; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
272; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
273; CHECK-CVT-NEXT:    ret
274;
275; CHECK-BF16-LABEL: test_frem:
276; CHECK-BF16:       // %bb.0:
277; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
278; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
279; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
280; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
281; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
282; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
283; CHECK-BF16-NEXT:    // kill: def $s1 killed $s1 killed $q1
284; CHECK-BF16-NEXT:    bl fmodf
285; CHECK-BF16-NEXT:    bfcvt h0, s0
286; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
287; CHECK-BF16-NEXT:    ret
288  %r = frem bfloat %a, %b
289  ret bfloat %r
290}
291
292define void @test_store(bfloat %a, ptr %b) #0 {
293; CHECK-LABEL: test_store:
294; CHECK:       // %bb.0:
295; CHECK-NEXT:    str h0, [x0]
296; CHECK-NEXT:    ret
297  store bfloat %a, ptr %b
298  ret void
299}
300
301define bfloat @test_load(ptr %a) #0 {
302; CHECK-LABEL: test_load:
303; CHECK:       // %bb.0:
304; CHECK-NEXT:    ldr h0, [x0]
305; CHECK-NEXT:    ret
306  %r = load bfloat, ptr %a
307  ret bfloat %r
308}
309
310declare bfloat @test_callee(bfloat %a, bfloat %b) #0
311
312define bfloat @test_call(bfloat %a, bfloat %b) #0 {
313; CHECK-LABEL: test_call:
314; CHECK:       // %bb.0:
315; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
316; CHECK-NEXT:    bl test_callee
317; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
318; CHECK-NEXT:    ret
319  %r = call bfloat @test_callee(bfloat %a, bfloat %b)
320  ret bfloat %r
321}
322
323define bfloat @test_call_flipped(bfloat %a, bfloat %b) #0 {
324; CHECK-LABEL: test_call_flipped:
325; CHECK:       // %bb.0:
326; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
327; CHECK-NEXT:    fmov s2, s0
328; CHECK-NEXT:    fmov s0, s1
329; CHECK-NEXT:    fmov s1, s2
330; CHECK-NEXT:    bl test_callee
331; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
332; CHECK-NEXT:    ret
333  %r = call bfloat @test_callee(bfloat %b, bfloat %a)
334  ret bfloat %r
335}
336
337define bfloat @test_tailcall_flipped(bfloat %a, bfloat %b) #0 {
338; CHECK-LABEL: test_tailcall_flipped:
339; CHECK:       // %bb.0:
340; CHECK-NEXT:    fmov s2, s0
341; CHECK-NEXT:    fmov s0, s1
342; CHECK-NEXT:    fmov s1, s2
343; CHECK-NEXT:    b test_callee
344  %r = tail call bfloat @test_callee(bfloat %b, bfloat %a)
345  ret bfloat %r
346}
347
348define bfloat @test_select(bfloat %a, bfloat %b, i1 zeroext %c) #0 {
349; CHECK-CVT-LABEL: test_select:
350; CHECK-CVT:       // %bb.0:
351; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $s0
352; CHECK-CVT-NEXT:    cmp w0, #0
353; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $s1
354; CHECK-CVT-NEXT:    fcsel s0, s0, s1, ne
355; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
356; CHECK-CVT-NEXT:    ret
357;
358; CHECK-SD-LABEL: test_select:
359; CHECK-SD:       // %bb.0:
360; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 def $s0
361; CHECK-SD-NEXT:    cmp w0, #0
362; CHECK-SD-NEXT:    // kill: def $h1 killed $h1 def $s1
363; CHECK-SD-NEXT:    fcsel s0, s0, s1, ne
364; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 killed $s0
365; CHECK-SD-NEXT:    ret
366;
367; CHECK-GI-LABEL: test_select:
368; CHECK-GI:       // %bb.0:
369; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 def $s0
370; CHECK-GI-NEXT:    // kill: def $h1 killed $h1 def $s1
371; CHECK-GI-NEXT:    fmov w8, s0
372; CHECK-GI-NEXT:    fmov w9, s1
373; CHECK-GI-NEXT:    tst w0, #0x1
374; CHECK-GI-NEXT:    csel w8, w8, w9, ne
375; CHECK-GI-NEXT:    fmov s0, w8
376; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 killed $s0
377; CHECK-GI-NEXT:    ret
378  %r = select i1 %c, bfloat %a, bfloat %b
379  ret bfloat %r
380}
381
382define bfloat @test_select_cc(bfloat %a, bfloat %b, bfloat %c, bfloat %d) #0 {
383; CHECK-CVT-LABEL: test_select_cc:
384; CHECK-CVT:       // %bb.0:
385; CHECK-CVT-NEXT:    // kill: def $h3 killed $h3 def $d3
386; CHECK-CVT-NEXT:    // kill: def $h2 killed $h2 def $d2
387; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $s0
388; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $s1
389; CHECK-CVT-NEXT:    shll v3.4s, v3.4h, #16
390; CHECK-CVT-NEXT:    shll v2.4s, v2.4h, #16
391; CHECK-CVT-NEXT:    fcmp s2, s3
392; CHECK-CVT-NEXT:    fcsel s0, s0, s1, ne
393; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
394; CHECK-CVT-NEXT:    ret
395;
396; CHECK-SD-LABEL: test_select_cc:
397; CHECK-SD:       // %bb.0:
398; CHECK-SD-NEXT:    // kill: def $h3 killed $h3 def $d3
399; CHECK-SD-NEXT:    // kill: def $h2 killed $h2 def $d2
400; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 def $s0
401; CHECK-SD-NEXT:    // kill: def $h1 killed $h1 def $s1
402; CHECK-SD-NEXT:    shll v3.4s, v3.4h, #16
403; CHECK-SD-NEXT:    shll v2.4s, v2.4h, #16
404; CHECK-SD-NEXT:    fcmp s2, s3
405; CHECK-SD-NEXT:    fcsel s0, s0, s1, ne
406; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 killed $s0
407; CHECK-SD-NEXT:    ret
408;
409; CHECK-GI-LABEL: test_select_cc:
410; CHECK-GI:       // %bb.0:
411; CHECK-GI-NEXT:    // kill: def $h3 killed $h3 def $d3
412; CHECK-GI-NEXT:    // kill: def $h2 killed $h2 def $d2
413; CHECK-GI-NEXT:    shll v3.4s, v3.4h, #16
414; CHECK-GI-NEXT:    shll v2.4s, v2.4h, #16
415; CHECK-GI-NEXT:    fcmp s2, s3
416; CHECK-GI-NEXT:    fcsel h0, h0, h1, ne
417; CHECK-GI-NEXT:    ret
418  %cc = fcmp une bfloat %c, %d
419  %r = select i1 %cc, bfloat %a, bfloat %b
420  ret bfloat %r
421}
422
423define float @test_select_cc_f32_f16(float %a, float %b, bfloat %c, bfloat %d) #0 {
424; CHECK-LABEL: test_select_cc_f32_f16:
425; CHECK:       // %bb.0:
426; CHECK-NEXT:    // kill: def $h3 killed $h3 def $d3
427; CHECK-NEXT:    // kill: def $h2 killed $h2 def $d2
428; CHECK-NEXT:    shll v3.4s, v3.4h, #16
429; CHECK-NEXT:    shll v2.4s, v2.4h, #16
430; CHECK-NEXT:    fcmp s2, s3
431; CHECK-NEXT:    fcsel s0, s0, s1, ne
432; CHECK-NEXT:    ret
433  %cc = fcmp une bfloat %c, %d
434  %r = select i1 %cc, float %a, float %b
435  ret float %r
436}
437
438define bfloat @test_select_cc_f16_f32(bfloat %a, bfloat %b, float %c, float %d) #0 {
439; CHECK-CVT-LABEL: test_select_cc_f16_f32:
440; CHECK-CVT:       // %bb.0:
441; CHECK-CVT-NEXT:    fcmp s2, s3
442; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $s0
443; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $s1
444; CHECK-CVT-NEXT:    fcsel s0, s0, s1, ne
445; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
446; CHECK-CVT-NEXT:    ret
447;
448; CHECK-SD-LABEL: test_select_cc_f16_f32:
449; CHECK-SD:       // %bb.0:
450; CHECK-SD-NEXT:    fcmp s2, s3
451; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 def $s0
452; CHECK-SD-NEXT:    // kill: def $h1 killed $h1 def $s1
453; CHECK-SD-NEXT:    fcsel s0, s0, s1, ne
454; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 killed $s0
455; CHECK-SD-NEXT:    ret
456;
457; CHECK-GI-LABEL: test_select_cc_f16_f32:
458; CHECK-GI:       // %bb.0:
459; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 def $s0
460; CHECK-GI-NEXT:    // kill: def $h1 killed $h1 def $s1
461; CHECK-GI-NEXT:    fcmp s2, s3
462; CHECK-GI-NEXT:    fmov w8, s0
463; CHECK-GI-NEXT:    fmov w9, s1
464; CHECK-GI-NEXT:    csel w8, w8, w9, ne
465; CHECK-GI-NEXT:    fmov s0, w8
466; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 killed $s0
467; CHECK-GI-NEXT:    ret
468  %cc = fcmp une float %c, %d
469  %r = select i1 %cc, bfloat %a, bfloat %b
470  ret bfloat %r
471}
472
473define i1 @test_fcmp_une(bfloat %a, bfloat %b) #0 {
474; CHECK-LABEL: test_fcmp_une:
475; CHECK:       // %bb.0:
476; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
477; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
478; CHECK-NEXT:    shll v1.4s, v1.4h, #16
479; CHECK-NEXT:    shll v0.4s, v0.4h, #16
480; CHECK-NEXT:    fcmp s0, s1
481; CHECK-NEXT:    cset w0, ne
482; CHECK-NEXT:    ret
483  %r = fcmp une bfloat %a, %b
484  ret i1 %r
485}
486
487define i1 @test_fcmp_ueq(bfloat %a, bfloat %b) #0 {
488; CHECK-LABEL: test_fcmp_ueq:
489; CHECK:       // %bb.0:
490; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
491; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
492; CHECK-NEXT:    shll v1.4s, v1.4h, #16
493; CHECK-NEXT:    shll v0.4s, v0.4h, #16
494; CHECK-NEXT:    fcmp s0, s1
495; CHECK-NEXT:    cset w8, eq
496; CHECK-NEXT:    csinc w0, w8, wzr, vc
497; CHECK-NEXT:    ret
498  %r = fcmp ueq bfloat %a, %b
499  ret i1 %r
500}
501
502define i1 @test_fcmp_ugt(bfloat %a, bfloat %b) #0 {
503; CHECK-LABEL: test_fcmp_ugt:
504; CHECK:       // %bb.0:
505; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
506; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
507; CHECK-NEXT:    shll v1.4s, v1.4h, #16
508; CHECK-NEXT:    shll v0.4s, v0.4h, #16
509; CHECK-NEXT:    fcmp s0, s1
510; CHECK-NEXT:    cset w0, hi
511; CHECK-NEXT:    ret
512  %r = fcmp ugt bfloat %a, %b
513  ret i1 %r
514}
515
516define i1 @test_fcmp_uge(bfloat %a, bfloat %b) #0 {
517; CHECK-LABEL: test_fcmp_uge:
518; CHECK:       // %bb.0:
519; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
520; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
521; CHECK-NEXT:    shll v1.4s, v1.4h, #16
522; CHECK-NEXT:    shll v0.4s, v0.4h, #16
523; CHECK-NEXT:    fcmp s0, s1
524; CHECK-NEXT:    cset w0, pl
525; CHECK-NEXT:    ret
526  %r = fcmp uge bfloat %a, %b
527  ret i1 %r
528}
529
530define i1 @test_fcmp_ult(bfloat %a, bfloat %b) #0 {
531; CHECK-LABEL: test_fcmp_ult:
532; CHECK:       // %bb.0:
533; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
534; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
535; CHECK-NEXT:    shll v1.4s, v1.4h, #16
536; CHECK-NEXT:    shll v0.4s, v0.4h, #16
537; CHECK-NEXT:    fcmp s0, s1
538; CHECK-NEXT:    cset w0, lt
539; CHECK-NEXT:    ret
540  %r = fcmp ult bfloat %a, %b
541  ret i1 %r
542}
543
544define i1 @test_fcmp_ule(bfloat %a, bfloat %b) #0 {
545; CHECK-LABEL: test_fcmp_ule:
546; CHECK:       // %bb.0:
547; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
548; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
549; CHECK-NEXT:    shll v1.4s, v1.4h, #16
550; CHECK-NEXT:    shll v0.4s, v0.4h, #16
551; CHECK-NEXT:    fcmp s0, s1
552; CHECK-NEXT:    cset w0, le
553; CHECK-NEXT:    ret
554  %r = fcmp ule bfloat %a, %b
555  ret i1 %r
556}
557
558define i1 @test_fcmp_uno(bfloat %a, bfloat %b) #0 {
559; CHECK-LABEL: test_fcmp_uno:
560; CHECK:       // %bb.0:
561; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
562; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
563; CHECK-NEXT:    shll v1.4s, v1.4h, #16
564; CHECK-NEXT:    shll v0.4s, v0.4h, #16
565; CHECK-NEXT:    fcmp s0, s1
566; CHECK-NEXT:    cset w0, vs
567; CHECK-NEXT:    ret
568  %r = fcmp uno bfloat %a, %b
569  ret i1 %r
570}
571
572define i1 @test_fcmp_one(bfloat %a, bfloat %b) #0 {
573; CHECK-LABEL: test_fcmp_one:
574; CHECK:       // %bb.0:
575; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
576; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
577; CHECK-NEXT:    shll v1.4s, v1.4h, #16
578; CHECK-NEXT:    shll v0.4s, v0.4h, #16
579; CHECK-NEXT:    fcmp s0, s1
580; CHECK-NEXT:    cset w8, mi
581; CHECK-NEXT:    csinc w0, w8, wzr, le
582; CHECK-NEXT:    ret
583  %r = fcmp one bfloat %a, %b
584  ret i1 %r
585}
586
587define i1 @test_fcmp_oeq(bfloat %a, bfloat %b) #0 {
588; CHECK-LABEL: test_fcmp_oeq:
589; CHECK:       // %bb.0:
590; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
591; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
592; CHECK-NEXT:    shll v1.4s, v1.4h, #16
593; CHECK-NEXT:    shll v0.4s, v0.4h, #16
594; CHECK-NEXT:    fcmp s0, s1
595; CHECK-NEXT:    cset w0, eq
596; CHECK-NEXT:    ret
597  %r = fcmp oeq bfloat %a, %b
598  ret i1 %r
599}
600
601define i1 @test_fcmp_ogt(bfloat %a, bfloat %b) #0 {
602; CHECK-LABEL: test_fcmp_ogt:
603; CHECK:       // %bb.0:
604; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
605; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
606; CHECK-NEXT:    shll v1.4s, v1.4h, #16
607; CHECK-NEXT:    shll v0.4s, v0.4h, #16
608; CHECK-NEXT:    fcmp s0, s1
609; CHECK-NEXT:    cset w0, gt
610; CHECK-NEXT:    ret
611  %r = fcmp ogt bfloat %a, %b
612  ret i1 %r
613}
614
615define i1 @test_fcmp_oge(bfloat %a, bfloat %b) #0 {
616; CHECK-LABEL: test_fcmp_oge:
617; CHECK:       // %bb.0:
618; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
619; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
620; CHECK-NEXT:    shll v1.4s, v1.4h, #16
621; CHECK-NEXT:    shll v0.4s, v0.4h, #16
622; CHECK-NEXT:    fcmp s0, s1
623; CHECK-NEXT:    cset w0, ge
624; CHECK-NEXT:    ret
625  %r = fcmp oge bfloat %a, %b
626  ret i1 %r
627}
628
629define i1 @test_fcmp_olt(bfloat %a, bfloat %b) #0 {
630; CHECK-LABEL: test_fcmp_olt:
631; CHECK:       // %bb.0:
632; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
633; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
634; CHECK-NEXT:    shll v1.4s, v1.4h, #16
635; CHECK-NEXT:    shll v0.4s, v0.4h, #16
636; CHECK-NEXT:    fcmp s0, s1
637; CHECK-NEXT:    cset w0, mi
638; CHECK-NEXT:    ret
639  %r = fcmp olt bfloat %a, %b
640  ret i1 %r
641}
642
643define i1 @test_fcmp_ole(bfloat %a, bfloat %b) #0 {
644; CHECK-LABEL: test_fcmp_ole:
645; CHECK:       // %bb.0:
646; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
647; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
648; CHECK-NEXT:    shll v1.4s, v1.4h, #16
649; CHECK-NEXT:    shll v0.4s, v0.4h, #16
650; CHECK-NEXT:    fcmp s0, s1
651; CHECK-NEXT:    cset w0, ls
652; CHECK-NEXT:    ret
653  %r = fcmp ole bfloat %a, %b
654  ret i1 %r
655}
656
657define i1 @test_fcmp_ord(bfloat %a, bfloat %b) #0 {
658; CHECK-LABEL: test_fcmp_ord:
659; CHECK:       // %bb.0:
660; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
661; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
662; CHECK-NEXT:    shll v1.4s, v1.4h, #16
663; CHECK-NEXT:    shll v0.4s, v0.4h, #16
664; CHECK-NEXT:    fcmp s0, s1
665; CHECK-NEXT:    cset w0, vc
666; CHECK-NEXT:    ret
667  %r = fcmp ord bfloat %a, %b
668  ret i1 %r
669}
670
671define void @test_fccmp(bfloat %in, ptr %out) {
672; CHECK-CVT-LABEL: test_fccmp:
673; CHECK-CVT:       // %bb.0:
674; CHECK-CVT-NEXT:    movi v1.2s, #69, lsl #24
675; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
676; CHECK-CVT-NEXT:    shll v2.4s, v0.4h, #16
677; CHECK-CVT-NEXT:    adrp x8, .LCPI29_0
678; CHECK-CVT-NEXT:    movi v3.2s, #72, lsl #24
679; CHECK-CVT-NEXT:    fcmp s2, s1
680; CHECK-CVT-NEXT:    ldr h1, [x8, :lo12:.LCPI29_0]
681; CHECK-CVT-NEXT:    fccmp s2, s3, #4, mi
682; CHECK-CVT-NEXT:    fcsel s0, s0, s1, gt
683; CHECK-CVT-NEXT:    str h0, [x0]
684; CHECK-CVT-NEXT:    ret
685;
686; CHECK-SD-LABEL: test_fccmp:
687; CHECK-SD:       // %bb.0:
688; CHECK-SD-NEXT:    movi v1.2s, #69, lsl #24
689; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 def $d0
690; CHECK-SD-NEXT:    shll v2.4s, v0.4h, #16
691; CHECK-SD-NEXT:    adrp x8, .LCPI29_0
692; CHECK-SD-NEXT:    movi v3.2s, #72, lsl #24
693; CHECK-SD-NEXT:    fcmp s2, s1
694; CHECK-SD-NEXT:    ldr h1, [x8, :lo12:.LCPI29_0]
695; CHECK-SD-NEXT:    fccmp s2, s3, #4, mi
696; CHECK-SD-NEXT:    fcsel s0, s0, s1, gt
697; CHECK-SD-NEXT:    str h0, [x0]
698; CHECK-SD-NEXT:    ret
699;
700; CHECK-GI-LABEL: test_fccmp:
701; CHECK-GI:       // %bb.0:
702; CHECK-GI-NEXT:    movi v1.2s, #69, lsl #24
703; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 def $d0
704; CHECK-GI-NEXT:    shll v2.4s, v0.4h, #16
705; CHECK-GI-NEXT:    movi v3.2s, #72, lsl #24
706; CHECK-GI-NEXT:    fcmp s2, s1
707; CHECK-GI-NEXT:    fmov h1, #5.00000000
708; CHECK-GI-NEXT:    fccmp s2, s3, #4, mi
709; CHECK-GI-NEXT:    fcsel h0, h0, h1, gt
710; CHECK-GI-NEXT:    str h0, [x0]
711; CHECK-GI-NEXT:    ret
712  %cmp1 = fcmp ogt bfloat %in, 0xR4800
713  %cmp2 = fcmp olt bfloat %in, 0xR4500
714  %cond = and i1 %cmp1, %cmp2
715  %result = select i1 %cond, bfloat %in, bfloat 0xR4500
716  store bfloat %result, ptr %out
717  ret void
718}
719
720define void @test_br_cc(bfloat %a, bfloat %b, ptr %p1, ptr %p2) #0 {
721; CHECK-LABEL: test_br_cc:
722; CHECK:       // %bb.0: // %common.ret
723; CHECK-NEXT:    // kill: def $h1 killed $h1 def $d1
724; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
725; CHECK-NEXT:    shll v1.4s, v1.4h, #16
726; CHECK-NEXT:    shll v0.4s, v0.4h, #16
727; CHECK-NEXT:    fcmp s0, s1
728; CHECK-NEXT:    csel x8, x0, x1, pl
729; CHECK-NEXT:    str wzr, [x8]
730; CHECK-NEXT:    ret
731  %c = fcmp uge bfloat %a, %b
732  br i1 %c, label %then, label %else
733then:
734  store i32 0, ptr %p1
735  ret void
736else:
737  store i32 0, ptr %p2
738  ret void
739}
740
741define bfloat @test_phi(ptr %p1) #0 {
742; CHECK-LABEL: test_phi:
743; CHECK:       // %bb.0: // %entry
744; CHECK-NEXT:    stp d9, d8, [sp, #-32]! // 16-byte Folded Spill
745; CHECK-NEXT:    ldr h9, [x0]
746; CHECK-NEXT:    stp x30, x19, [sp, #16] // 16-byte Folded Spill
747; CHECK-NEXT:    mov x19, x0
748; CHECK-NEXT:  .LBB31_1: // %loop
749; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
750; CHECK-NEXT:    fmov s8, s9
751; CHECK-NEXT:    ldr h9, [x19]
752; CHECK-NEXT:    mov x0, x19
753; CHECK-NEXT:    bl test_dummy
754; CHECK-NEXT:    tbnz w0, #0, .LBB31_1
755; CHECK-NEXT:  // %bb.2: // %return
756; CHECK-NEXT:    ldp x30, x19, [sp, #16] // 16-byte Folded Reload
757; CHECK-NEXT:    fmov s0, s8
758; CHECK-NEXT:    ldp d9, d8, [sp], #32 // 16-byte Folded Reload
759; CHECK-NEXT:    ret
760entry:
761  %a = load bfloat, ptr %p1
762  br label %loop
763loop:
764  %r = phi bfloat [%a, %entry], [%b, %loop]
765  %b = load bfloat, ptr %p1
766  %c = call i1 @test_dummy(ptr %p1)
767  br i1 %c, label %loop, label %return
768return:
769  ret bfloat %r
770}
771
772declare i1 @test_dummy(ptr %p1) #0
773
774define i32 @test_fptosi_i32(bfloat %a) #0 {
775; CHECK-LABEL: test_fptosi_i32:
776; CHECK:       // %bb.0:
777; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
778; CHECK-NEXT:    shll v0.4s, v0.4h, #16
779; CHECK-NEXT:    fcvtzs w0, s0
780; CHECK-NEXT:    ret
781  %r = fptosi bfloat %a to i32
782  ret i32 %r
783}
784
785define i64 @test_fptosi_i64(bfloat %a) #0 {
786; CHECK-LABEL: test_fptosi_i64:
787; CHECK:       // %bb.0:
788; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
789; CHECK-NEXT:    shll v0.4s, v0.4h, #16
790; CHECK-NEXT:    fcvtzs x0, s0
791; CHECK-NEXT:    ret
792  %r = fptosi bfloat %a to i64
793  ret i64 %r
794}
795
796define i32 @test_fptoui_i32(bfloat %a) #0 {
797; CHECK-LABEL: test_fptoui_i32:
798; CHECK:       // %bb.0:
799; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
800; CHECK-NEXT:    shll v0.4s, v0.4h, #16
801; CHECK-NEXT:    fcvtzu w0, s0
802; CHECK-NEXT:    ret
803  %r = fptoui bfloat %a to i32
804  ret i32 %r
805}
806
807define i64 @test_fptoui_i64(bfloat %a) #0 {
808; CHECK-LABEL: test_fptoui_i64:
809; CHECK:       // %bb.0:
810; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
811; CHECK-NEXT:    shll v0.4s, v0.4h, #16
812; CHECK-NEXT:    fcvtzu x0, s0
813; CHECK-NEXT:    ret
814  %r = fptoui bfloat %a to i64
815  ret i64 %r
816}
817
818define bfloat @test_uitofp_i32(i32 %a) #0 {
819; CHECK-CVT-LABEL: test_uitofp_i32:
820; CHECK-CVT:       // %bb.0:
821; CHECK-CVT-NEXT:    ucvtf d0, w0
822; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
823; CHECK-CVT-NEXT:    fcvtxn s0, d0
824; CHECK-CVT-NEXT:    fmov w9, s0
825; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
826; CHECK-CVT-NEXT:    add w8, w9, w8
827; CHECK-CVT-NEXT:    add w8, w10, w8
828; CHECK-CVT-NEXT:    lsr w8, w8, #16
829; CHECK-CVT-NEXT:    fmov s0, w8
830; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
831; CHECK-CVT-NEXT:    ret
832;
833; CHECK-BF16-LABEL: test_uitofp_i32:
834; CHECK-BF16:       // %bb.0:
835; CHECK-BF16-NEXT:    ucvtf d0, w0
836; CHECK-BF16-NEXT:    fcvtxn s0, d0
837; CHECK-BF16-NEXT:    bfcvt h0, s0
838; CHECK-BF16-NEXT:    ret
839  %r = uitofp i32 %a to bfloat
840  ret bfloat %r
841}
842
843define bfloat @test_uitofp_i64(i64 %a) #0 {
844; CHECK-CVT-LABEL: test_uitofp_i64:
845; CHECK-CVT:       // %bb.0:
846; CHECK-CVT-NEXT:    lsr x9, x0, #53
847; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
848; CHECK-CVT-NEXT:    cmp x9, #0
849; CHECK-CVT-NEXT:    and x9, x0, #0xfffffffffffff000
850; CHECK-CVT-NEXT:    csel x9, x9, x0, ne
851; CHECK-CVT-NEXT:    ucvtf d0, x9
852; CHECK-CVT-NEXT:    cset w9, ne
853; CHECK-CVT-NEXT:    tst x0, #0xfff
854; CHECK-CVT-NEXT:    csel w9, wzr, w9, eq
855; CHECK-CVT-NEXT:    fmov x10, d0
856; CHECK-CVT-NEXT:    orr x9, x10, x9
857; CHECK-CVT-NEXT:    fmov d0, x9
858; CHECK-CVT-NEXT:    fcvtxn s0, d0
859; CHECK-CVT-NEXT:    fmov w9, s0
860; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
861; CHECK-CVT-NEXT:    add w8, w9, w8
862; CHECK-CVT-NEXT:    add w8, w10, w8
863; CHECK-CVT-NEXT:    lsr w8, w8, #16
864; CHECK-CVT-NEXT:    fmov s0, w8
865; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
866; CHECK-CVT-NEXT:    ret
867;
868; CHECK-BF16-LABEL: test_uitofp_i64:
869; CHECK-BF16:       // %bb.0:
870; CHECK-BF16-NEXT:    lsr x8, x0, #53
871; CHECK-BF16-NEXT:    and x9, x0, #0xfffffffffffff000
872; CHECK-BF16-NEXT:    cmp x8, #0
873; CHECK-BF16-NEXT:    csel x8, x9, x0, ne
874; CHECK-BF16-NEXT:    ucvtf d0, x8
875; CHECK-BF16-NEXT:    cset w8, ne
876; CHECK-BF16-NEXT:    tst x0, #0xfff
877; CHECK-BF16-NEXT:    csel w8, wzr, w8, eq
878; CHECK-BF16-NEXT:    fmov x9, d0
879; CHECK-BF16-NEXT:    orr x8, x9, x8
880; CHECK-BF16-NEXT:    fmov d0, x8
881; CHECK-BF16-NEXT:    fcvtxn s0, d0
882; CHECK-BF16-NEXT:    bfcvt h0, s0
883; CHECK-BF16-NEXT:    ret
884  %r = uitofp i64 %a to bfloat
885  ret bfloat %r
886}
887
888define bfloat @test_sitofp_i32(i32 %a) #0 {
889; CHECK-CVT-LABEL: test_sitofp_i32:
890; CHECK-CVT:       // %bb.0:
891; CHECK-CVT-NEXT:    scvtf d0, w0
892; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
893; CHECK-CVT-NEXT:    fcvtxn s0, d0
894; CHECK-CVT-NEXT:    fmov w9, s0
895; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
896; CHECK-CVT-NEXT:    add w8, w9, w8
897; CHECK-CVT-NEXT:    add w8, w10, w8
898; CHECK-CVT-NEXT:    lsr w8, w8, #16
899; CHECK-CVT-NEXT:    fmov s0, w8
900; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
901; CHECK-CVT-NEXT:    ret
902;
903; CHECK-BF16-LABEL: test_sitofp_i32:
904; CHECK-BF16:       // %bb.0:
905; CHECK-BF16-NEXT:    scvtf d0, w0
906; CHECK-BF16-NEXT:    fcvtxn s0, d0
907; CHECK-BF16-NEXT:    bfcvt h0, s0
908; CHECK-BF16-NEXT:    ret
909  %r = sitofp i32 %a to bfloat
910  ret bfloat %r
911}
912
913define bfloat @test_sitofp_i64(i64 %a) #0 {
914; CHECK-CVT-LABEL: test_sitofp_i64:
915; CHECK-CVT:       // %bb.0:
916; CHECK-CVT-NEXT:    cmp x0, #0
917; CHECK-CVT-NEXT:    and x11, x0, #0x8000000000000000
918; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
919; CHECK-CVT-NEXT:    cneg x9, x0, mi
920; CHECK-CVT-NEXT:    lsr x10, x9, #53
921; CHECK-CVT-NEXT:    cmp x10, #0
922; CHECK-CVT-NEXT:    and x10, x9, #0xfffffffffffff000
923; CHECK-CVT-NEXT:    csel x10, x10, x9, ne
924; CHECK-CVT-NEXT:    scvtf d0, x10
925; CHECK-CVT-NEXT:    cset w10, ne
926; CHECK-CVT-NEXT:    tst x9, #0xfff
927; CHECK-CVT-NEXT:    csel w10, wzr, w10, eq
928; CHECK-CVT-NEXT:    fmov x9, d0
929; CHECK-CVT-NEXT:    orr x9, x9, x11
930; CHECK-CVT-NEXT:    orr x9, x9, x10
931; CHECK-CVT-NEXT:    fmov d0, x9
932; CHECK-CVT-NEXT:    fcvtxn s0, d0
933; CHECK-CVT-NEXT:    fmov w9, s0
934; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
935; CHECK-CVT-NEXT:    add w8, w9, w8
936; CHECK-CVT-NEXT:    add w8, w10, w8
937; CHECK-CVT-NEXT:    lsr w8, w8, #16
938; CHECK-CVT-NEXT:    fmov s0, w8
939; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
940; CHECK-CVT-NEXT:    ret
941;
942; CHECK-BF16-LABEL: test_sitofp_i64:
943; CHECK-BF16:       // %bb.0:
944; CHECK-BF16-NEXT:    cmp x0, #0
945; CHECK-BF16-NEXT:    cneg x8, x0, mi
946; CHECK-BF16-NEXT:    lsr x9, x8, #53
947; CHECK-BF16-NEXT:    and x10, x8, #0xfffffffffffff000
948; CHECK-BF16-NEXT:    cmp x9, #0
949; CHECK-BF16-NEXT:    csel x9, x10, x8, ne
950; CHECK-BF16-NEXT:    and x10, x0, #0x8000000000000000
951; CHECK-BF16-NEXT:    cset w11, ne
952; CHECK-BF16-NEXT:    scvtf d0, x9
953; CHECK-BF16-NEXT:    tst x8, #0xfff
954; CHECK-BF16-NEXT:    fmov x9, d0
955; CHECK-BF16-NEXT:    orr x8, x9, x10
956; CHECK-BF16-NEXT:    csel w9, wzr, w11, eq
957; CHECK-BF16-NEXT:    orr x8, x8, x9
958; CHECK-BF16-NEXT:    fmov d0, x8
959; CHECK-BF16-NEXT:    fcvtxn s0, d0
960; CHECK-BF16-NEXT:    bfcvt h0, s0
961; CHECK-BF16-NEXT:    ret
962  %r = sitofp i64 %a to bfloat
963  ret bfloat %r
964}
965
966define bfloat @test_uitofp_i32_fadd(i32 %a, bfloat %b) #0 {
967; CHECK-CVT-LABEL: test_uitofp_i32_fadd:
968; CHECK-CVT:       // %bb.0:
969; CHECK-CVT-NEXT:    ucvtf d1, w0
970; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
971; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
972; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
973; CHECK-CVT-NEXT:    fcvtxn s1, d1
974; CHECK-CVT-NEXT:    fmov w9, s1
975; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
976; CHECK-CVT-NEXT:    add w9, w9, w8
977; CHECK-CVT-NEXT:    add w9, w10, w9
978; CHECK-CVT-NEXT:    lsr w9, w9, #16
979; CHECK-CVT-NEXT:    fmov s1, w9
980; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
981; CHECK-CVT-NEXT:    fadd s0, s0, s1
982; CHECK-CVT-NEXT:    fmov w9, s0
983; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
984; CHECK-CVT-NEXT:    add w8, w9, w8
985; CHECK-CVT-NEXT:    add w8, w10, w8
986; CHECK-CVT-NEXT:    lsr w8, w8, #16
987; CHECK-CVT-NEXT:    fmov s0, w8
988; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
989; CHECK-CVT-NEXT:    ret
990;
991; CHECK-BF16-LABEL: test_uitofp_i32_fadd:
992; CHECK-BF16:       // %bb.0:
993; CHECK-BF16-NEXT:    ucvtf d1, w0
994; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
995; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
996; CHECK-BF16-NEXT:    fcvtxn s1, d1
997; CHECK-BF16-NEXT:    bfcvt h1, s1
998; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
999; CHECK-BF16-NEXT:    fadd s0, s0, s1
1000; CHECK-BF16-NEXT:    bfcvt h0, s0
1001; CHECK-BF16-NEXT:    ret
1002  %c = uitofp i32 %a to bfloat
1003  %r = fadd bfloat %b, %c
1004  ret bfloat %r
1005}
1006
1007define bfloat @test_sitofp_i32_fadd(i32 %a, bfloat %b) #0 {
1008; CHECK-CVT-LABEL: test_sitofp_i32_fadd:
1009; CHECK-CVT:       // %bb.0:
1010; CHECK-CVT-NEXT:    scvtf d1, w0
1011; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1012; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1013; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1014; CHECK-CVT-NEXT:    fcvtxn s1, d1
1015; CHECK-CVT-NEXT:    fmov w9, s1
1016; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1017; CHECK-CVT-NEXT:    add w9, w9, w8
1018; CHECK-CVT-NEXT:    add w9, w10, w9
1019; CHECK-CVT-NEXT:    lsr w9, w9, #16
1020; CHECK-CVT-NEXT:    fmov s1, w9
1021; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
1022; CHECK-CVT-NEXT:    fadd s0, s0, s1
1023; CHECK-CVT-NEXT:    fmov w9, s0
1024; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1025; CHECK-CVT-NEXT:    add w8, w9, w8
1026; CHECK-CVT-NEXT:    add w8, w10, w8
1027; CHECK-CVT-NEXT:    lsr w8, w8, #16
1028; CHECK-CVT-NEXT:    fmov s0, w8
1029; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1030; CHECK-CVT-NEXT:    ret
1031;
1032; CHECK-BF16-LABEL: test_sitofp_i32_fadd:
1033; CHECK-BF16:       // %bb.0:
1034; CHECK-BF16-NEXT:    scvtf d1, w0
1035; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1036; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1037; CHECK-BF16-NEXT:    fcvtxn s1, d1
1038; CHECK-BF16-NEXT:    bfcvt h1, s1
1039; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
1040; CHECK-BF16-NEXT:    fadd s0, s0, s1
1041; CHECK-BF16-NEXT:    bfcvt h0, s0
1042; CHECK-BF16-NEXT:    ret
1043  %c = sitofp i32 %a to bfloat
1044  %r = fadd bfloat %b, %c
1045  ret bfloat %r
1046}
1047
1048define bfloat @test_fptrunc_float(float %a) #0 {
1049; CHECK-CVT-LABEL: test_fptrunc_float:
1050; CHECK-CVT:       // %bb.0:
1051; CHECK-CVT-NEXT:    fmov w9, s0
1052; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1053; CHECK-CVT-NEXT:    fcmp s0, s0
1054; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1055; CHECK-CVT-NEXT:    add w8, w9, w8
1056; CHECK-CVT-NEXT:    orr w9, w9, #0x400000
1057; CHECK-CVT-NEXT:    add w8, w10, w8
1058; CHECK-CVT-NEXT:    csel w8, w9, w8, vs
1059; CHECK-CVT-NEXT:    lsr w8, w8, #16
1060; CHECK-CVT-NEXT:    fmov s0, w8
1061; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1062; CHECK-CVT-NEXT:    ret
1063;
1064; CHECK-BF16-LABEL: test_fptrunc_float:
1065; CHECK-BF16:       // %bb.0:
1066; CHECK-BF16-NEXT:    bfcvt h0, s0
1067; CHECK-BF16-NEXT:    ret
1068  %r = fptrunc float %a to bfloat
1069  ret bfloat %r
1070}
1071
1072define bfloat @test_fptrunc_double(double %a) #0 {
1073; CHECK-CVT-LABEL: test_fptrunc_double:
1074; CHECK-CVT:       // %bb.0:
1075; CHECK-CVT-NEXT:    fcvtxn s0, d0
1076; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1077; CHECK-CVT-NEXT:    fmov w9, s0
1078; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1079; CHECK-CVT-NEXT:    add w8, w9, w8
1080; CHECK-CVT-NEXT:    add w8, w10, w8
1081; CHECK-CVT-NEXT:    lsr w8, w8, #16
1082; CHECK-CVT-NEXT:    fmov s0, w8
1083; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1084; CHECK-CVT-NEXT:    ret
1085;
1086; CHECK-BF16-LABEL: test_fptrunc_double:
1087; CHECK-BF16:       // %bb.0:
1088; CHECK-BF16-NEXT:    fcvtxn s0, d0
1089; CHECK-BF16-NEXT:    bfcvt h0, s0
1090; CHECK-BF16-NEXT:    ret
1091  %r = fptrunc double %a to bfloat
1092  ret bfloat %r
1093}
1094
1095define float @test_fpext_float(bfloat %a) #0 {
1096; CHECK-LABEL: test_fpext_float:
1097; CHECK:       // %bb.0:
1098; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
1099; CHECK-NEXT:    shll v0.4s, v0.4h, #16
1100; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $q0
1101; CHECK-NEXT:    ret
1102  %r = fpext bfloat %a to float
1103  ret float %r
1104}
1105
1106define double @test_fpext_double(bfloat %a) #0 {
1107; CHECK-LABEL: test_fpext_double:
1108; CHECK:       // %bb.0:
1109; CHECK-NEXT:    // kill: def $h0 killed $h0 def $d0
1110; CHECK-NEXT:    shll v0.4s, v0.4h, #16
1111; CHECK-NEXT:    fcvt d0, s0
1112; CHECK-NEXT:    ret
1113  %r = fpext bfloat %a to double
1114  ret double %r
1115}
1116
1117define i16 @test_bitcast_bfloattoi16(bfloat %a) #0 {
1118; CHECK-LABEL: test_bitcast_bfloattoi16:
1119; CHECK:       // %bb.0:
1120; CHECK-NEXT:    // kill: def $h0 killed $h0 def $s0
1121; CHECK-NEXT:    fmov w0, s0
1122; CHECK-NEXT:    ret
1123  %r = bitcast bfloat %a to i16
1124  ret i16 %r
1125}
1126
1127define bfloat @test_bitcast_i16tobfloat(i16 %a) #0 {
1128; CHECK-LABEL: test_bitcast_i16tobfloat:
1129; CHECK:       // %bb.0:
1130; CHECK-NEXT:    fmov s0, w0
1131; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $s0
1132; CHECK-NEXT:    ret
1133  %r = bitcast i16 %a to bfloat
1134  ret bfloat %r
1135}
1136
1137declare bfloat @llvm.sqrt.f16(bfloat %a) #0
1138declare bfloat @llvm.powi.f16.i32(bfloat %a, i32 %b) #0
1139declare bfloat @llvm.sin.f16(bfloat %a) #0
1140declare bfloat @llvm.cos.f16(bfloat %a) #0
1141declare bfloat @llvm.tan.f16(bfloat %a) #0
1142declare bfloat @llvm.asin.f16(bfloat %a) #0
1143declare bfloat @llvm.acos.f16(bfloat %a) #0
1144declare bfloat @llvm.atan.f16(bfloat %a) #0
1145declare bfloat @llvm.atan2.f16(bfloat %a, bfloat %b) #0
1146declare bfloat @llvm.sinh.f16(bfloat %a) #0
1147declare bfloat @llvm.cosh.f16(bfloat %a) #0
1148declare bfloat @llvm.tanh.f16(bfloat %a) #0
1149declare bfloat @llvm.pow.f16(bfloat %a, bfloat %b) #0
1150declare bfloat @llvm.exp.f16(bfloat %a) #0
1151declare bfloat @llvm.exp2.f16(bfloat %a) #0
1152declare bfloat @llvm.log.f16(bfloat %a) #0
1153declare bfloat @llvm.log10.f16(bfloat %a) #0
1154declare bfloat @llvm.log2.f16(bfloat %a) #0
1155declare bfloat @llvm.fma.f16(bfloat %a, bfloat %b, bfloat %c) #0
1156declare bfloat @llvm.fabs.f16(bfloat %a) #0
1157declare bfloat @llvm.minnum.f16(bfloat %a, bfloat %b) #0
1158declare bfloat @llvm.maxnum.f16(bfloat %a, bfloat %b) #0
1159declare bfloat @llvm.copysign.f16(bfloat %a, bfloat %b) #0
1160declare bfloat @llvm.floor.f16(bfloat %a) #0
1161declare bfloat @llvm.ceil.f16(bfloat %a) #0
1162declare bfloat @llvm.trunc.f16(bfloat %a) #0
1163declare bfloat @llvm.rint.f16(bfloat %a) #0
1164declare bfloat @llvm.nearbyint.f16(bfloat %a) #0
1165declare bfloat @llvm.round.f16(bfloat %a) #0
1166declare bfloat @llvm.roundeven.f16(bfloat %a) #0
1167declare bfloat @llvm.fmuladd.f16(bfloat %a, bfloat %b, bfloat %c) #0
1168
1169
1170define bfloat @test_sqrt(bfloat %a) #0 {
1171; CHECK-CVT-LABEL: test_sqrt:
1172; CHECK-CVT:       // %bb.0:
1173; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1174; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1175; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1176; CHECK-CVT-NEXT:    fsqrt s0, s0
1177; CHECK-CVT-NEXT:    fmov w9, s0
1178; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1179; CHECK-CVT-NEXT:    add w8, w9, w8
1180; CHECK-CVT-NEXT:    add w8, w10, w8
1181; CHECK-CVT-NEXT:    lsr w8, w8, #16
1182; CHECK-CVT-NEXT:    fmov s0, w8
1183; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1184; CHECK-CVT-NEXT:    ret
1185;
1186; CHECK-BF16-LABEL: test_sqrt:
1187; CHECK-BF16:       // %bb.0:
1188; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1189; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1190; CHECK-BF16-NEXT:    fsqrt s0, s0
1191; CHECK-BF16-NEXT:    bfcvt h0, s0
1192; CHECK-BF16-NEXT:    ret
1193  %r = call bfloat @llvm.sqrt.f16(bfloat %a)
1194  ret bfloat %r
1195}
1196
1197define bfloat @test_powi(bfloat %a, i32 %b) #0 {
1198; CHECK-CVT-LABEL: test_powi:
1199; CHECK-CVT:       // %bb.0:
1200; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1201; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1202; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1203; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1204; CHECK-CVT-NEXT:    bl __powisf2
1205; CHECK-CVT-NEXT:    fmov w9, s0
1206; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1207; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1208; CHECK-CVT-NEXT:    add w8, w9, w8
1209; CHECK-CVT-NEXT:    add w8, w10, w8
1210; CHECK-CVT-NEXT:    lsr w8, w8, #16
1211; CHECK-CVT-NEXT:    fmov s0, w8
1212; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1213; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1214; CHECK-CVT-NEXT:    ret
1215;
1216; CHECK-BF16-LABEL: test_powi:
1217; CHECK-BF16:       // %bb.0:
1218; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1219; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1220; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1221; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1222; CHECK-BF16-NEXT:    bl __powisf2
1223; CHECK-BF16-NEXT:    bfcvt h0, s0
1224; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1225; CHECK-BF16-NEXT:    ret
1226  %r = call bfloat @llvm.powi.f16.i32(bfloat %a, i32 %b)
1227  ret bfloat %r
1228}
1229
1230
1231define bfloat @test_sin(bfloat %a) #0 {
1232; CHECK-CVT-LABEL: test_sin:
1233; CHECK-CVT:       // %bb.0:
1234; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1235; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1236; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1237; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1238; CHECK-CVT-NEXT:    bl sinf
1239; CHECK-CVT-NEXT:    fmov w9, s0
1240; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1241; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1242; CHECK-CVT-NEXT:    add w8, w9, w8
1243; CHECK-CVT-NEXT:    add w8, w10, w8
1244; CHECK-CVT-NEXT:    lsr w8, w8, #16
1245; CHECK-CVT-NEXT:    fmov s0, w8
1246; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1247; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1248; CHECK-CVT-NEXT:    ret
1249;
1250; CHECK-BF16-LABEL: test_sin:
1251; CHECK-BF16:       // %bb.0:
1252; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1253; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1254; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1255; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1256; CHECK-BF16-NEXT:    bl sinf
1257; CHECK-BF16-NEXT:    bfcvt h0, s0
1258; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1259; CHECK-BF16-NEXT:    ret
1260  %r = call bfloat @llvm.sin.f16(bfloat %a)
1261  ret bfloat %r
1262}
1263
1264define bfloat @test_cos(bfloat %a) #0 {
1265; CHECK-CVT-LABEL: test_cos:
1266; CHECK-CVT:       // %bb.0:
1267; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1268; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1269; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1270; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1271; CHECK-CVT-NEXT:    bl cosf
1272; CHECK-CVT-NEXT:    fmov w9, s0
1273; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1274; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1275; CHECK-CVT-NEXT:    add w8, w9, w8
1276; CHECK-CVT-NEXT:    add w8, w10, w8
1277; CHECK-CVT-NEXT:    lsr w8, w8, #16
1278; CHECK-CVT-NEXT:    fmov s0, w8
1279; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1280; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1281; CHECK-CVT-NEXT:    ret
1282;
1283; CHECK-BF16-LABEL: test_cos:
1284; CHECK-BF16:       // %bb.0:
1285; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1286; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1287; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1288; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1289; CHECK-BF16-NEXT:    bl cosf
1290; CHECK-BF16-NEXT:    bfcvt h0, s0
1291; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1292; CHECK-BF16-NEXT:    ret
1293  %r = call bfloat @llvm.cos.f16(bfloat %a)
1294  ret bfloat %r
1295}
1296
1297define bfloat @test_tan(bfloat %a) #0 {
1298; CHECK-CVT-LABEL: test_tan:
1299; CHECK-CVT:       // %bb.0:
1300; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1301; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1302; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1303; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1304; CHECK-CVT-NEXT:    bl tanf
1305; CHECK-CVT-NEXT:    fmov w9, s0
1306; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1307; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1308; CHECK-CVT-NEXT:    add w8, w9, w8
1309; CHECK-CVT-NEXT:    add w8, w10, w8
1310; CHECK-CVT-NEXT:    lsr w8, w8, #16
1311; CHECK-CVT-NEXT:    fmov s0, w8
1312; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1313; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1314; CHECK-CVT-NEXT:    ret
1315;
1316; CHECK-BF16-LABEL: test_tan:
1317; CHECK-BF16:       // %bb.0:
1318; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1319; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1320; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1321; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1322; CHECK-BF16-NEXT:    bl tanf
1323; CHECK-BF16-NEXT:    bfcvt h0, s0
1324; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1325; CHECK-BF16-NEXT:    ret
1326  %r = call bfloat @llvm.tan.f16(bfloat %a)
1327  ret bfloat %r
1328}
1329
1330define bfloat @test_acos(bfloat %a) #0 {
1331; CHECK-CVT-LABEL: test_acos:
1332; CHECK-CVT:       // %bb.0:
1333; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1334; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1335; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1336; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1337; CHECK-CVT-NEXT:    bl acosf
1338; CHECK-CVT-NEXT:    fmov w9, s0
1339; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1340; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1341; CHECK-CVT-NEXT:    add w8, w9, w8
1342; CHECK-CVT-NEXT:    add w8, w10, w8
1343; CHECK-CVT-NEXT:    lsr w8, w8, #16
1344; CHECK-CVT-NEXT:    fmov s0, w8
1345; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1346; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1347; CHECK-CVT-NEXT:    ret
1348;
1349; CHECK-BF16-LABEL: test_acos:
1350; CHECK-BF16:       // %bb.0:
1351; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1352; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1353; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1354; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1355; CHECK-BF16-NEXT:    bl acosf
1356; CHECK-BF16-NEXT:    bfcvt h0, s0
1357; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1358; CHECK-BF16-NEXT:    ret
1359  %r = call bfloat @llvm.acos.f16(bfloat %a)
1360  ret bfloat %r
1361}
1362
1363define bfloat @test_asin(bfloat %a) #0 {
1364; CHECK-CVT-LABEL: test_asin:
1365; CHECK-CVT:       // %bb.0:
1366; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1367; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1368; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1369; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1370; CHECK-CVT-NEXT:    bl asinf
1371; CHECK-CVT-NEXT:    fmov w9, s0
1372; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1373; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1374; CHECK-CVT-NEXT:    add w8, w9, w8
1375; CHECK-CVT-NEXT:    add w8, w10, w8
1376; CHECK-CVT-NEXT:    lsr w8, w8, #16
1377; CHECK-CVT-NEXT:    fmov s0, w8
1378; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1379; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1380; CHECK-CVT-NEXT:    ret
1381;
1382; CHECK-BF16-LABEL: test_asin:
1383; CHECK-BF16:       // %bb.0:
1384; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1385; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1386; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1387; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1388; CHECK-BF16-NEXT:    bl asinf
1389; CHECK-BF16-NEXT:    bfcvt h0, s0
1390; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1391; CHECK-BF16-NEXT:    ret
1392  %r = call bfloat @llvm.asin.f16(bfloat %a)
1393  ret bfloat %r
1394}
1395
1396define bfloat @test_atan(bfloat %a) #0 {
1397; CHECK-CVT-LABEL: test_atan:
1398; CHECK-CVT:       // %bb.0:
1399; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1400; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1401; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1402; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1403; CHECK-CVT-NEXT:    bl atanf
1404; CHECK-CVT-NEXT:    fmov w9, s0
1405; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1406; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1407; CHECK-CVT-NEXT:    add w8, w9, w8
1408; CHECK-CVT-NEXT:    add w8, w10, w8
1409; CHECK-CVT-NEXT:    lsr w8, w8, #16
1410; CHECK-CVT-NEXT:    fmov s0, w8
1411; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1412; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1413; CHECK-CVT-NEXT:    ret
1414;
1415; CHECK-BF16-LABEL: test_atan:
1416; CHECK-BF16:       // %bb.0:
1417; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1418; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1419; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1420; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1421; CHECK-BF16-NEXT:    bl atanf
1422; CHECK-BF16-NEXT:    bfcvt h0, s0
1423; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1424; CHECK-BF16-NEXT:    ret
1425  %r = call bfloat @llvm.atan.f16(bfloat %a)
1426  ret bfloat %r
1427}
1428
1429define bfloat @test_atan2(bfloat %a, bfloat %b) #0 {
1430; CHECK-CVT-LABEL: test_atan2:
1431; CHECK-CVT:       // %bb.0:
1432; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1433; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
1434; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1435; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1436; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
1437; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1438; CHECK-CVT-NEXT:    // kill: def $s1 killed $s1 killed $q1
1439; CHECK-CVT-NEXT:    bl atan2f
1440; CHECK-CVT-NEXT:    fmov w9, s0
1441; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1442; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1443; CHECK-CVT-NEXT:    add w8, w9, w8
1444; CHECK-CVT-NEXT:    add w8, w10, w8
1445; CHECK-CVT-NEXT:    lsr w8, w8, #16
1446; CHECK-CVT-NEXT:    fmov s0, w8
1447; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1448; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1449; CHECK-CVT-NEXT:    ret
1450;
1451; CHECK-BF16-LABEL: test_atan2:
1452; CHECK-BF16:       // %bb.0:
1453; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1454; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
1455; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1456; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1457; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
1458; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1459; CHECK-BF16-NEXT:    // kill: def $s1 killed $s1 killed $q1
1460; CHECK-BF16-NEXT:    bl atan2f
1461; CHECK-BF16-NEXT:    bfcvt h0, s0
1462; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1463; CHECK-BF16-NEXT:    ret
1464  %r = call bfloat @llvm.atan2.f16(bfloat %a, bfloat %b)
1465  ret bfloat %r
1466}
1467
1468define bfloat @test_cosh(bfloat %a) #0 {
1469; CHECK-CVT-LABEL: test_cosh:
1470; CHECK-CVT:       // %bb.0:
1471; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1472; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1473; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1474; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1475; CHECK-CVT-NEXT:    bl coshf
1476; CHECK-CVT-NEXT:    fmov w9, s0
1477; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1478; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1479; CHECK-CVT-NEXT:    add w8, w9, w8
1480; CHECK-CVT-NEXT:    add w8, w10, w8
1481; CHECK-CVT-NEXT:    lsr w8, w8, #16
1482; CHECK-CVT-NEXT:    fmov s0, w8
1483; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1484; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1485; CHECK-CVT-NEXT:    ret
1486;
1487; CHECK-BF16-LABEL: test_cosh:
1488; CHECK-BF16:       // %bb.0:
1489; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1490; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1491; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1492; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1493; CHECK-BF16-NEXT:    bl coshf
1494; CHECK-BF16-NEXT:    bfcvt h0, s0
1495; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1496; CHECK-BF16-NEXT:    ret
1497  %r = call bfloat @llvm.cosh.f16(bfloat %a)
1498  ret bfloat %r
1499}
1500
1501define bfloat @test_sinh(bfloat %a) #0 {
1502; CHECK-CVT-LABEL: test_sinh:
1503; CHECK-CVT:       // %bb.0:
1504; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1505; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1506; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1507; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1508; CHECK-CVT-NEXT:    bl sinhf
1509; CHECK-CVT-NEXT:    fmov w9, s0
1510; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1511; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1512; CHECK-CVT-NEXT:    add w8, w9, w8
1513; CHECK-CVT-NEXT:    add w8, w10, w8
1514; CHECK-CVT-NEXT:    lsr w8, w8, #16
1515; CHECK-CVT-NEXT:    fmov s0, w8
1516; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1517; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1518; CHECK-CVT-NEXT:    ret
1519;
1520; CHECK-BF16-LABEL: test_sinh:
1521; CHECK-BF16:       // %bb.0:
1522; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1523; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1524; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1525; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1526; CHECK-BF16-NEXT:    bl sinhf
1527; CHECK-BF16-NEXT:    bfcvt h0, s0
1528; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1529; CHECK-BF16-NEXT:    ret
1530  %r = call bfloat @llvm.sinh.f16(bfloat %a)
1531  ret bfloat %r
1532}
1533
1534define bfloat @test_tanh(bfloat %a) #0 {
1535; CHECK-CVT-LABEL: test_tanh:
1536; CHECK-CVT:       // %bb.0:
1537; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1538; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1539; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1540; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1541; CHECK-CVT-NEXT:    bl tanhf
1542; CHECK-CVT-NEXT:    fmov w9, s0
1543; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1544; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1545; CHECK-CVT-NEXT:    add w8, w9, w8
1546; CHECK-CVT-NEXT:    add w8, w10, w8
1547; CHECK-CVT-NEXT:    lsr w8, w8, #16
1548; CHECK-CVT-NEXT:    fmov s0, w8
1549; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1550; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1551; CHECK-CVT-NEXT:    ret
1552;
1553; CHECK-BF16-LABEL: test_tanh:
1554; CHECK-BF16:       // %bb.0:
1555; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1556; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1557; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1558; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1559; CHECK-BF16-NEXT:    bl tanhf
1560; CHECK-BF16-NEXT:    bfcvt h0, s0
1561; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1562; CHECK-BF16-NEXT:    ret
1563  %r = call bfloat @llvm.tanh.f16(bfloat %a)
1564  ret bfloat %r
1565}
1566
1567define bfloat @test_pow(bfloat %a, bfloat %b) #0 {
1568; CHECK-CVT-LABEL: test_pow:
1569; CHECK-CVT:       // %bb.0:
1570; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1571; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
1572; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1573; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1574; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
1575; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1576; CHECK-CVT-NEXT:    // kill: def $s1 killed $s1 killed $q1
1577; CHECK-CVT-NEXT:    bl powf
1578; CHECK-CVT-NEXT:    fmov w9, s0
1579; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1580; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1581; CHECK-CVT-NEXT:    add w8, w9, w8
1582; CHECK-CVT-NEXT:    add w8, w10, w8
1583; CHECK-CVT-NEXT:    lsr w8, w8, #16
1584; CHECK-CVT-NEXT:    fmov s0, w8
1585; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1586; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1587; CHECK-CVT-NEXT:    ret
1588;
1589; CHECK-BF16-LABEL: test_pow:
1590; CHECK-BF16:       // %bb.0:
1591; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1592; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
1593; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1594; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1595; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
1596; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1597; CHECK-BF16-NEXT:    // kill: def $s1 killed $s1 killed $q1
1598; CHECK-BF16-NEXT:    bl powf
1599; CHECK-BF16-NEXT:    bfcvt h0, s0
1600; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1601; CHECK-BF16-NEXT:    ret
1602  %r = call bfloat @llvm.pow.f16(bfloat %a, bfloat %b)
1603  ret bfloat %r
1604}
1605
1606define bfloat @test_exp(bfloat %a) #0 {
1607; CHECK-CVT-LABEL: test_exp:
1608; CHECK-CVT:       // %bb.0:
1609; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1610; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1611; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1612; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1613; CHECK-CVT-NEXT:    bl expf
1614; CHECK-CVT-NEXT:    fmov w9, s0
1615; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1616; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1617; CHECK-CVT-NEXT:    add w8, w9, w8
1618; CHECK-CVT-NEXT:    add w8, w10, w8
1619; CHECK-CVT-NEXT:    lsr w8, w8, #16
1620; CHECK-CVT-NEXT:    fmov s0, w8
1621; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1622; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1623; CHECK-CVT-NEXT:    ret
1624;
1625; CHECK-BF16-LABEL: test_exp:
1626; CHECK-BF16:       // %bb.0:
1627; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1628; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1629; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1630; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1631; CHECK-BF16-NEXT:    bl expf
1632; CHECK-BF16-NEXT:    bfcvt h0, s0
1633; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1634; CHECK-BF16-NEXT:    ret
1635  %r = call bfloat @llvm.exp.f16(bfloat %a)
1636  ret bfloat %r
1637}
1638
1639define bfloat @test_exp2(bfloat %a) #0 {
1640; CHECK-CVT-LABEL: test_exp2:
1641; CHECK-CVT:       // %bb.0:
1642; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1643; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1644; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1645; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1646; CHECK-CVT-NEXT:    bl exp2f
1647; CHECK-CVT-NEXT:    fmov w9, s0
1648; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1649; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1650; CHECK-CVT-NEXT:    add w8, w9, w8
1651; CHECK-CVT-NEXT:    add w8, w10, w8
1652; CHECK-CVT-NEXT:    lsr w8, w8, #16
1653; CHECK-CVT-NEXT:    fmov s0, w8
1654; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1655; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1656; CHECK-CVT-NEXT:    ret
1657;
1658; CHECK-BF16-LABEL: test_exp2:
1659; CHECK-BF16:       // %bb.0:
1660; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1661; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1662; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1663; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1664; CHECK-BF16-NEXT:    bl exp2f
1665; CHECK-BF16-NEXT:    bfcvt h0, s0
1666; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1667; CHECK-BF16-NEXT:    ret
1668  %r = call bfloat @llvm.exp2.f16(bfloat %a)
1669  ret bfloat %r
1670}
1671
1672define bfloat @test_log(bfloat %a) #0 {
1673; CHECK-CVT-LABEL: test_log:
1674; CHECK-CVT:       // %bb.0:
1675; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1676; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1677; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1678; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1679; CHECK-CVT-NEXT:    bl logf
1680; CHECK-CVT-NEXT:    fmov w9, s0
1681; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1682; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1683; CHECK-CVT-NEXT:    add w8, w9, w8
1684; CHECK-CVT-NEXT:    add w8, w10, w8
1685; CHECK-CVT-NEXT:    lsr w8, w8, #16
1686; CHECK-CVT-NEXT:    fmov s0, w8
1687; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1688; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1689; CHECK-CVT-NEXT:    ret
1690;
1691; CHECK-BF16-LABEL: test_log:
1692; CHECK-BF16:       // %bb.0:
1693; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1694; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1695; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1696; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1697; CHECK-BF16-NEXT:    bl logf
1698; CHECK-BF16-NEXT:    bfcvt h0, s0
1699; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1700; CHECK-BF16-NEXT:    ret
1701  %r = call bfloat @llvm.log.f16(bfloat %a)
1702  ret bfloat %r
1703}
1704
1705define bfloat @test_log10(bfloat %a) #0 {
1706; CHECK-CVT-LABEL: test_log10:
1707; CHECK-CVT:       // %bb.0:
1708; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1709; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1710; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1711; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1712; CHECK-CVT-NEXT:    bl log10f
1713; CHECK-CVT-NEXT:    fmov w9, s0
1714; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1715; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1716; CHECK-CVT-NEXT:    add w8, w9, w8
1717; CHECK-CVT-NEXT:    add w8, w10, w8
1718; CHECK-CVT-NEXT:    lsr w8, w8, #16
1719; CHECK-CVT-NEXT:    fmov s0, w8
1720; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1721; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1722; CHECK-CVT-NEXT:    ret
1723;
1724; CHECK-BF16-LABEL: test_log10:
1725; CHECK-BF16:       // %bb.0:
1726; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1727; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1728; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1729; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1730; CHECK-BF16-NEXT:    bl log10f
1731; CHECK-BF16-NEXT:    bfcvt h0, s0
1732; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1733; CHECK-BF16-NEXT:    ret
1734  %r = call bfloat @llvm.log10.f16(bfloat %a)
1735  ret bfloat %r
1736}
1737
1738define bfloat @test_log2(bfloat %a) #0 {
1739; CHECK-CVT-LABEL: test_log2:
1740; CHECK-CVT:       // %bb.0:
1741; CHECK-CVT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1742; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1743; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1744; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
1745; CHECK-CVT-NEXT:    bl log2f
1746; CHECK-CVT-NEXT:    fmov w9, s0
1747; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1748; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1749; CHECK-CVT-NEXT:    add w8, w9, w8
1750; CHECK-CVT-NEXT:    add w8, w10, w8
1751; CHECK-CVT-NEXT:    lsr w8, w8, #16
1752; CHECK-CVT-NEXT:    fmov s0, w8
1753; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1754; CHECK-CVT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1755; CHECK-CVT-NEXT:    ret
1756;
1757; CHECK-BF16-LABEL: test_log2:
1758; CHECK-BF16:       // %bb.0:
1759; CHECK-BF16-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1760; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1761; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1762; CHECK-BF16-NEXT:    // kill: def $s0 killed $s0 killed $q0
1763; CHECK-BF16-NEXT:    bl log2f
1764; CHECK-BF16-NEXT:    bfcvt h0, s0
1765; CHECK-BF16-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1766; CHECK-BF16-NEXT:    ret
1767  %r = call bfloat @llvm.log2.f16(bfloat %a)
1768  ret bfloat %r
1769}
1770
1771define bfloat @test_fma(bfloat %a, bfloat %b, bfloat %c) #0 {
1772; CHECK-CVT-LABEL: test_fma:
1773; CHECK-CVT:       // %bb.0:
1774; CHECK-CVT-NEXT:    // kill: def $h2 killed $h2 def $d2
1775; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
1776; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1777; CHECK-CVT-NEXT:    mov w10, #32767 // =0x7fff
1778; CHECK-CVT-NEXT:    shll v2.4s, v2.4h, #16
1779; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
1780; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1781; CHECK-CVT-NEXT:    fmadd s0, s0, s1, s2
1782; CHECK-CVT-NEXT:    fmov w8, s0
1783; CHECK-CVT-NEXT:    ubfx w9, w8, #16, #1
1784; CHECK-CVT-NEXT:    add w8, w8, w10
1785; CHECK-CVT-NEXT:    add w8, w9, w8
1786; CHECK-CVT-NEXT:    lsr w8, w8, #16
1787; CHECK-CVT-NEXT:    fmov s0, w8
1788; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1789; CHECK-CVT-NEXT:    ret
1790;
1791; CHECK-BF16-LABEL: test_fma:
1792; CHECK-BF16:       // %bb.0:
1793; CHECK-BF16-NEXT:    // kill: def $h2 killed $h2 def $d2
1794; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
1795; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1796; CHECK-BF16-NEXT:    shll v2.4s, v2.4h, #16
1797; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
1798; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1799; CHECK-BF16-NEXT:    fmadd s0, s0, s1, s2
1800; CHECK-BF16-NEXT:    bfcvt h0, s0
1801; CHECK-BF16-NEXT:    ret
1802  %r = call bfloat @llvm.fma.f16(bfloat %a, bfloat %b, bfloat %c)
1803  ret bfloat %r
1804}
1805
1806define bfloat @test_fabs(bfloat %a) #0 {
1807; CHECK-LABEL: test_fabs:
1808; CHECK:       // %bb.0:
1809; CHECK-NEXT:    // kill: def $h0 killed $h0 def $s0
1810; CHECK-NEXT:    fmov w8, s0
1811; CHECK-NEXT:    and w8, w8, #0x7fff
1812; CHECK-NEXT:    fmov s0, w8
1813; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $s0
1814; CHECK-NEXT:    ret
1815  %r = call bfloat @llvm.fabs.f16(bfloat %a)
1816  ret bfloat %r
1817}
1818
1819define bfloat @test_minnum(bfloat %a, bfloat %b) #0 {
1820; CHECK-CVT-LABEL: test_minnum:
1821; CHECK-CVT:       // %bb.0:
1822; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
1823; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1824; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1825; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
1826; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1827; CHECK-CVT-NEXT:    fminnm s0, s0, s1
1828; CHECK-CVT-NEXT:    fmov w9, s0
1829; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1830; CHECK-CVT-NEXT:    add w8, w9, w8
1831; CHECK-CVT-NEXT:    add w8, w10, w8
1832; CHECK-CVT-NEXT:    lsr w8, w8, #16
1833; CHECK-CVT-NEXT:    fmov s0, w8
1834; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1835; CHECK-CVT-NEXT:    ret
1836;
1837; CHECK-BF16-LABEL: test_minnum:
1838; CHECK-BF16:       // %bb.0:
1839; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
1840; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1841; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
1842; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1843; CHECK-BF16-NEXT:    fminnm s0, s0, s1
1844; CHECK-BF16-NEXT:    bfcvt h0, s0
1845; CHECK-BF16-NEXT:    ret
1846  %r = call bfloat @llvm.minnum.f16(bfloat %a, bfloat %b)
1847  ret bfloat %r
1848}
1849
1850define bfloat @test_maxnum(bfloat %a, bfloat %b) #0 {
1851; CHECK-CVT-LABEL: test_maxnum:
1852; CHECK-CVT:       // %bb.0:
1853; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
1854; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1855; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
1856; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
1857; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1858; CHECK-CVT-NEXT:    fmaxnm s0, s0, s1
1859; CHECK-CVT-NEXT:    fmov w9, s0
1860; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
1861; CHECK-CVT-NEXT:    add w8, w9, w8
1862; CHECK-CVT-NEXT:    add w8, w10, w8
1863; CHECK-CVT-NEXT:    lsr w8, w8, #16
1864; CHECK-CVT-NEXT:    fmov s0, w8
1865; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1866; CHECK-CVT-NEXT:    ret
1867;
1868; CHECK-BF16-LABEL: test_maxnum:
1869; CHECK-BF16:       // %bb.0:
1870; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
1871; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
1872; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
1873; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
1874; CHECK-BF16-NEXT:    fmaxnm s0, s0, s1
1875; CHECK-BF16-NEXT:    bfcvt h0, s0
1876; CHECK-BF16-NEXT:    ret
1877  %r = call bfloat @llvm.maxnum.f16(bfloat %a, bfloat %b)
1878  ret bfloat %r
1879}
1880
1881define bfloat @test_copysign(bfloat %a, bfloat %b) #0 {
1882; CHECK-CVT-LABEL: test_copysign:
1883; CHECK-CVT:       // %bb.0:
1884; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
1885; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1886; CHECK-CVT-NEXT:    mvni v2.4s, #128, lsl #24
1887; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
1888; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1889; CHECK-CVT-NEXT:    bif v0.16b, v1.16b, v2.16b
1890; CHECK-CVT-NEXT:    fmov w8, s0
1891; CHECK-CVT-NEXT:    lsr w8, w8, #16
1892; CHECK-CVT-NEXT:    fmov s0, w8
1893; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1894; CHECK-CVT-NEXT:    ret
1895;
1896; CHECK-SD-LABEL: test_copysign:
1897; CHECK-SD:       // %bb.0:
1898; CHECK-SD-NEXT:    // kill: def $h1 killed $h1 def $d1
1899; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 def $d0
1900; CHECK-SD-NEXT:    mvni v2.4s, #128, lsl #24
1901; CHECK-SD-NEXT:    shll v1.4s, v1.4h, #16
1902; CHECK-SD-NEXT:    shll v0.4s, v0.4h, #16
1903; CHECK-SD-NEXT:    bif v0.16b, v1.16b, v2.16b
1904; CHECK-SD-NEXT:    bfcvt h0, s0
1905; CHECK-SD-NEXT:    ret
1906;
1907; CHECK-GI-LABEL: test_copysign:
1908; CHECK-GI:       // %bb.0:
1909; CHECK-GI-NEXT:    mvni v2.8h, #128, lsl #8
1910; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 def $q0
1911; CHECK-GI-NEXT:    // kill: def $h1 killed $h1 def $q1
1912; CHECK-GI-NEXT:    bif v0.16b, v1.16b, v2.16b
1913; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 killed $q0
1914; CHECK-GI-NEXT:    ret
1915  %r = call bfloat @llvm.copysign.f16(bfloat %a, bfloat %b)
1916  ret bfloat %r
1917}
1918
1919define bfloat @test_copysign_f32(bfloat %a, float %b) #0 {
1920; CHECK-CVT-LABEL: test_copysign_f32:
1921; CHECK-CVT:       // %bb.0:
1922; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1923; CHECK-CVT-NEXT:    mvni v2.4s, #128, lsl #24
1924; CHECK-CVT-NEXT:    // kill: def $s1 killed $s1 def $q1
1925; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1926; CHECK-CVT-NEXT:    bif v0.16b, v1.16b, v2.16b
1927; CHECK-CVT-NEXT:    fmov w8, s0
1928; CHECK-CVT-NEXT:    lsr w8, w8, #16
1929; CHECK-CVT-NEXT:    fmov s0, w8
1930; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1931; CHECK-CVT-NEXT:    ret
1932;
1933; CHECK-SD-LABEL: test_copysign_f32:
1934; CHECK-SD:       // %bb.0:
1935; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 def $d0
1936; CHECK-SD-NEXT:    mvni v2.4s, #128, lsl #24
1937; CHECK-SD-NEXT:    // kill: def $s1 killed $s1 def $q1
1938; CHECK-SD-NEXT:    shll v0.4s, v0.4h, #16
1939; CHECK-SD-NEXT:    bif v0.16b, v1.16b, v2.16b
1940; CHECK-SD-NEXT:    bfcvt h0, s0
1941; CHECK-SD-NEXT:    ret
1942;
1943; CHECK-GI-LABEL: test_copysign_f32:
1944; CHECK-GI:       // %bb.0:
1945; CHECK-GI-NEXT:    bfcvt h1, s1
1946; CHECK-GI-NEXT:    mvni v2.8h, #128, lsl #8
1947; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 def $q0
1948; CHECK-GI-NEXT:    bif v0.16b, v1.16b, v2.16b
1949; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 killed $q0
1950; CHECK-GI-NEXT:    ret
1951  %tb = fptrunc float %b to bfloat
1952  %r = call bfloat @llvm.copysign.f16(bfloat %a, bfloat %tb)
1953  ret bfloat %r
1954}
1955
1956define bfloat @test_copysign_f64(bfloat %a, double %b) #0 {
1957; CHECK-CVT-LABEL: test_copysign_f64:
1958; CHECK-CVT:       // %bb.0:
1959; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
1960; CHECK-CVT-NEXT:    fcvt s1, d1
1961; CHECK-CVT-NEXT:    mvni v2.4s, #128, lsl #24
1962; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
1963; CHECK-CVT-NEXT:    bif v0.16b, v1.16b, v2.16b
1964; CHECK-CVT-NEXT:    fmov w8, s0
1965; CHECK-CVT-NEXT:    lsr w8, w8, #16
1966; CHECK-CVT-NEXT:    fmov s0, w8
1967; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
1968; CHECK-CVT-NEXT:    ret
1969;
1970; CHECK-SD-LABEL: test_copysign_f64:
1971; CHECK-SD:       // %bb.0:
1972; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 def $d0
1973; CHECK-SD-NEXT:    fcvt s1, d1
1974; CHECK-SD-NEXT:    mvni v2.4s, #128, lsl #24
1975; CHECK-SD-NEXT:    shll v0.4s, v0.4h, #16
1976; CHECK-SD-NEXT:    bif v0.16b, v1.16b, v2.16b
1977; CHECK-SD-NEXT:    bfcvt h0, s0
1978; CHECK-SD-NEXT:    ret
1979;
1980; CHECK-GI-LABEL: test_copysign_f64:
1981; CHECK-GI:       // %bb.0:
1982; CHECK-GI-NEXT:    fcvtxn s1, d1
1983; CHECK-GI-NEXT:    mvni v2.8h, #128, lsl #8
1984; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 def $q0
1985; CHECK-GI-NEXT:    bfcvt h1, s1
1986; CHECK-GI-NEXT:    bif v0.16b, v1.16b, v2.16b
1987; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 killed $q0
1988; CHECK-GI-NEXT:    ret
1989  %tb = fptrunc double %b to bfloat
1990  %r = call bfloat @llvm.copysign.f16(bfloat %a, bfloat %tb)
1991  ret bfloat %r
1992}
1993
1994; away the (fpext (fp_round <result>)) here.
1995
1996define float @test_copysign_extended(bfloat %a, bfloat %b) #0 {
1997; CHECK-CVT-LABEL: test_copysign_extended:
1998; CHECK-CVT:       // %bb.0:
1999; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
2000; CHECK-CVT-NEXT:    movi v2.4s, #16
2001; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
2002; CHECK-CVT-NEXT:    ushll v0.4s, v0.4h, #0
2003; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
2004; CHECK-CVT-NEXT:    ushl v0.4s, v0.4s, v2.4s
2005; CHECK-CVT-NEXT:    mvni v2.4s, #128, lsl #24
2006; CHECK-CVT-NEXT:    bif v0.16b, v1.16b, v2.16b
2007; CHECK-CVT-NEXT:    fmov w8, s0
2008; CHECK-CVT-NEXT:    lsr w8, w8, #16
2009; CHECK-CVT-NEXT:    fmov s0, w8
2010; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
2011; CHECK-CVT-NEXT:    // kill: def $s0 killed $s0 killed $q0
2012; CHECK-CVT-NEXT:    ret
2013;
2014; CHECK-SD-LABEL: test_copysign_extended:
2015; CHECK-SD:       // %bb.0:
2016; CHECK-SD-NEXT:    // kill: def $h0 killed $h0 def $d0
2017; CHECK-SD-NEXT:    movi v2.4s, #16
2018; CHECK-SD-NEXT:    // kill: def $h1 killed $h1 def $d1
2019; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
2020; CHECK-SD-NEXT:    shll v1.4s, v1.4h, #16
2021; CHECK-SD-NEXT:    ushl v0.4s, v0.4s, v2.4s
2022; CHECK-SD-NEXT:    mvni v2.4s, #128, lsl #24
2023; CHECK-SD-NEXT:    bif v0.16b, v1.16b, v2.16b
2024; CHECK-SD-NEXT:    bfcvt h0, s0
2025; CHECK-SD-NEXT:    shll v0.4s, v0.4h, #16
2026; CHECK-SD-NEXT:    // kill: def $s0 killed $s0 killed $q0
2027; CHECK-SD-NEXT:    ret
2028;
2029; CHECK-GI-LABEL: test_copysign_extended:
2030; CHECK-GI:       // %bb.0:
2031; CHECK-GI-NEXT:    mvni v2.8h, #128, lsl #8
2032; CHECK-GI-NEXT:    // kill: def $h0 killed $h0 def $q0
2033; CHECK-GI-NEXT:    // kill: def $h1 killed $h1 def $q1
2034; CHECK-GI-NEXT:    bif v0.16b, v1.16b, v2.16b
2035; CHECK-GI-NEXT:    shll v0.4s, v0.4h, #16
2036; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 killed $q0
2037; CHECK-GI-NEXT:    ret
2038  %r = call bfloat @llvm.copysign.f16(bfloat %a, bfloat %b)
2039  %xr = fpext bfloat %r to float
2040  ret float %xr
2041}
2042
2043define bfloat @test_floor(bfloat %a) #0 {
2044; CHECK-CVT-LABEL: test_floor:
2045; CHECK-CVT:       // %bb.0:
2046; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
2047; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
2048; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
2049; CHECK-CVT-NEXT:    frintm s0, s0
2050; CHECK-CVT-NEXT:    fmov w9, s0
2051; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
2052; CHECK-CVT-NEXT:    add w8, w9, w8
2053; CHECK-CVT-NEXT:    add w8, w10, w8
2054; CHECK-CVT-NEXT:    lsr w8, w8, #16
2055; CHECK-CVT-NEXT:    fmov s0, w8
2056; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
2057; CHECK-CVT-NEXT:    ret
2058;
2059; CHECK-BF16-LABEL: test_floor:
2060; CHECK-BF16:       // %bb.0:
2061; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
2062; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
2063; CHECK-BF16-NEXT:    frintm s0, s0
2064; CHECK-BF16-NEXT:    bfcvt h0, s0
2065; CHECK-BF16-NEXT:    ret
2066  %r = call bfloat @llvm.floor.f16(bfloat %a)
2067  ret bfloat %r
2068}
2069
2070define bfloat @test_ceil(bfloat %a) #0 {
2071; CHECK-CVT-LABEL: test_ceil:
2072; CHECK-CVT:       // %bb.0:
2073; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
2074; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
2075; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
2076; CHECK-CVT-NEXT:    frintp s0, s0
2077; CHECK-CVT-NEXT:    fmov w9, s0
2078; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
2079; CHECK-CVT-NEXT:    add w8, w9, w8
2080; CHECK-CVT-NEXT:    add w8, w10, w8
2081; CHECK-CVT-NEXT:    lsr w8, w8, #16
2082; CHECK-CVT-NEXT:    fmov s0, w8
2083; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
2084; CHECK-CVT-NEXT:    ret
2085;
2086; CHECK-BF16-LABEL: test_ceil:
2087; CHECK-BF16:       // %bb.0:
2088; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
2089; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
2090; CHECK-BF16-NEXT:    frintp s0, s0
2091; CHECK-BF16-NEXT:    bfcvt h0, s0
2092; CHECK-BF16-NEXT:    ret
2093  %r = call bfloat @llvm.ceil.f16(bfloat %a)
2094  ret bfloat %r
2095}
2096
2097define bfloat @test_trunc(bfloat %a) #0 {
2098; CHECK-CVT-LABEL: test_trunc:
2099; CHECK-CVT:       // %bb.0:
2100; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
2101; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
2102; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
2103; CHECK-CVT-NEXT:    frintz s0, s0
2104; CHECK-CVT-NEXT:    fmov w9, s0
2105; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
2106; CHECK-CVT-NEXT:    add w8, w9, w8
2107; CHECK-CVT-NEXT:    add w8, w10, w8
2108; CHECK-CVT-NEXT:    lsr w8, w8, #16
2109; CHECK-CVT-NEXT:    fmov s0, w8
2110; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
2111; CHECK-CVT-NEXT:    ret
2112;
2113; CHECK-BF16-LABEL: test_trunc:
2114; CHECK-BF16:       // %bb.0:
2115; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
2116; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
2117; CHECK-BF16-NEXT:    frintz s0, s0
2118; CHECK-BF16-NEXT:    bfcvt h0, s0
2119; CHECK-BF16-NEXT:    ret
2120  %r = call bfloat @llvm.trunc.f16(bfloat %a)
2121  ret bfloat %r
2122}
2123
2124define bfloat @test_rint(bfloat %a) #0 {
2125; CHECK-CVT-LABEL: test_rint:
2126; CHECK-CVT:       // %bb.0:
2127; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
2128; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
2129; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
2130; CHECK-CVT-NEXT:    frintx s0, s0
2131; CHECK-CVT-NEXT:    fmov w9, s0
2132; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
2133; CHECK-CVT-NEXT:    add w8, w9, w8
2134; CHECK-CVT-NEXT:    add w8, w10, w8
2135; CHECK-CVT-NEXT:    lsr w8, w8, #16
2136; CHECK-CVT-NEXT:    fmov s0, w8
2137; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
2138; CHECK-CVT-NEXT:    ret
2139;
2140; CHECK-BF16-LABEL: test_rint:
2141; CHECK-BF16:       // %bb.0:
2142; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
2143; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
2144; CHECK-BF16-NEXT:    frintx s0, s0
2145; CHECK-BF16-NEXT:    bfcvt h0, s0
2146; CHECK-BF16-NEXT:    ret
2147  %r = call bfloat @llvm.rint.f16(bfloat %a)
2148  ret bfloat %r
2149}
2150
2151define bfloat @test_nearbyint(bfloat %a) #0 {
2152; CHECK-CVT-LABEL: test_nearbyint:
2153; CHECK-CVT:       // %bb.0:
2154; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
2155; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
2156; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
2157; CHECK-CVT-NEXT:    frinti s0, s0
2158; CHECK-CVT-NEXT:    fmov w9, s0
2159; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
2160; CHECK-CVT-NEXT:    add w8, w9, w8
2161; CHECK-CVT-NEXT:    add w8, w10, w8
2162; CHECK-CVT-NEXT:    lsr w8, w8, #16
2163; CHECK-CVT-NEXT:    fmov s0, w8
2164; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
2165; CHECK-CVT-NEXT:    ret
2166;
2167; CHECK-BF16-LABEL: test_nearbyint:
2168; CHECK-BF16:       // %bb.0:
2169; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
2170; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
2171; CHECK-BF16-NEXT:    frinti s0, s0
2172; CHECK-BF16-NEXT:    bfcvt h0, s0
2173; CHECK-BF16-NEXT:    ret
2174  %r = call bfloat @llvm.nearbyint.f16(bfloat %a)
2175  ret bfloat %r
2176}
2177
2178define bfloat @test_round(bfloat %a) #0 {
2179; CHECK-CVT-LABEL: test_round:
2180; CHECK-CVT:       // %bb.0:
2181; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
2182; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
2183; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
2184; CHECK-CVT-NEXT:    frinta s0, s0
2185; CHECK-CVT-NEXT:    fmov w9, s0
2186; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
2187; CHECK-CVT-NEXT:    add w8, w9, w8
2188; CHECK-CVT-NEXT:    add w8, w10, w8
2189; CHECK-CVT-NEXT:    lsr w8, w8, #16
2190; CHECK-CVT-NEXT:    fmov s0, w8
2191; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
2192; CHECK-CVT-NEXT:    ret
2193;
2194; CHECK-BF16-LABEL: test_round:
2195; CHECK-BF16:       // %bb.0:
2196; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
2197; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
2198; CHECK-BF16-NEXT:    frinta s0, s0
2199; CHECK-BF16-NEXT:    bfcvt h0, s0
2200; CHECK-BF16-NEXT:    ret
2201  %r = call bfloat @llvm.round.f16(bfloat %a)
2202  ret bfloat %r
2203}
2204
2205define bfloat @test_roundeven(bfloat %a) #0 {
2206; CHECK-CVT-LABEL: test_roundeven:
2207; CHECK-CVT:       // %bb.0:
2208; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
2209; CHECK-CVT-NEXT:    mov w8, #32767 // =0x7fff
2210; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
2211; CHECK-CVT-NEXT:    frintn s0, s0
2212; CHECK-CVT-NEXT:    fmov w9, s0
2213; CHECK-CVT-NEXT:    ubfx w10, w9, #16, #1
2214; CHECK-CVT-NEXT:    add w8, w9, w8
2215; CHECK-CVT-NEXT:    add w8, w10, w8
2216; CHECK-CVT-NEXT:    lsr w8, w8, #16
2217; CHECK-CVT-NEXT:    fmov s0, w8
2218; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
2219; CHECK-CVT-NEXT:    ret
2220;
2221; CHECK-BF16-LABEL: test_roundeven:
2222; CHECK-BF16:       // %bb.0:
2223; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
2224; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
2225; CHECK-BF16-NEXT:    frintn s0, s0
2226; CHECK-BF16-NEXT:    bfcvt h0, s0
2227; CHECK-BF16-NEXT:    ret
2228  %r = call bfloat @llvm.roundeven.f16(bfloat %a)
2229  ret bfloat %r
2230}
2231
2232define bfloat @test_fmuladd(bfloat %a, bfloat %b, bfloat %c) #0 {
2233; CHECK-CVT-LABEL: test_fmuladd:
2234; CHECK-CVT:       // %bb.0:
2235; CHECK-CVT-NEXT:    // kill: def $h1 killed $h1 def $d1
2236; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 def $d0
2237; CHECK-CVT-NEXT:    mov w10, #32767 // =0x7fff
2238; CHECK-CVT-NEXT:    // kill: def $h2 killed $h2 def $d2
2239; CHECK-CVT-NEXT:    shll v1.4s, v1.4h, #16
2240; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
2241; CHECK-CVT-NEXT:    fmul s0, s0, s1
2242; CHECK-CVT-NEXT:    shll v1.4s, v2.4h, #16
2243; CHECK-CVT-NEXT:    fmov w8, s0
2244; CHECK-CVT-NEXT:    ubfx w9, w8, #16, #1
2245; CHECK-CVT-NEXT:    add w8, w8, w10
2246; CHECK-CVT-NEXT:    add w8, w9, w8
2247; CHECK-CVT-NEXT:    lsr w8, w8, #16
2248; CHECK-CVT-NEXT:    fmov s0, w8
2249; CHECK-CVT-NEXT:    shll v0.4s, v0.4h, #16
2250; CHECK-CVT-NEXT:    fadd s0, s0, s1
2251; CHECK-CVT-NEXT:    fmov w8, s0
2252; CHECK-CVT-NEXT:    ubfx w9, w8, #16, #1
2253; CHECK-CVT-NEXT:    add w8, w8, w10
2254; CHECK-CVT-NEXT:    add w8, w9, w8
2255; CHECK-CVT-NEXT:    lsr w8, w8, #16
2256; CHECK-CVT-NEXT:    fmov s0, w8
2257; CHECK-CVT-NEXT:    // kill: def $h0 killed $h0 killed $s0
2258; CHECK-CVT-NEXT:    ret
2259;
2260; CHECK-BF16-LABEL: test_fmuladd:
2261; CHECK-BF16:       // %bb.0:
2262; CHECK-BF16-NEXT:    // kill: def $h1 killed $h1 def $d1
2263; CHECK-BF16-NEXT:    // kill: def $h0 killed $h0 def $d0
2264; CHECK-BF16-NEXT:    // kill: def $h2 killed $h2 def $d2
2265; CHECK-BF16-NEXT:    shll v1.4s, v1.4h, #16
2266; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
2267; CHECK-BF16-NEXT:    fmul s0, s0, s1
2268; CHECK-BF16-NEXT:    shll v1.4s, v2.4h, #16
2269; CHECK-BF16-NEXT:    bfcvt h0, s0
2270; CHECK-BF16-NEXT:    shll v0.4s, v0.4h, #16
2271; CHECK-BF16-NEXT:    fadd s0, s0, s1
2272; CHECK-BF16-NEXT:    bfcvt h0, s0
2273; CHECK-BF16-NEXT:    ret
2274  %r = call bfloat @llvm.fmuladd.f16(bfloat %a, bfloat %b, bfloat %c)
2275  ret bfloat %r
2276}
2277
2278attributes #0 = { nounwind }
2279