Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / bfloat-arith.ll
blob632e933c595671d4e056c09e14886a084c673f77
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2 ; RUN: llc -mtriple=riscv32 -mattr=+zfbfmin -verify-machineinstrs \
3 ; RUN:   -target-abi ilp32f < %s | FileCheck -check-prefixes=CHECK,RV32IZFBFMIN %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+zfbfmin -verify-machineinstrs \
5 ; RUN:   -target-abi lp64f < %s | FileCheck -check-prefixes=CHECK,RV64IZFBFMIN %s
7 ; These tests descend from float-arith.ll, where each function was targeted at
8 ; a particular RISC-V FPU instruction.
10 define bfloat @fadd_s(bfloat %a, bfloat %b) nounwind {
11 ; CHECK-LABEL: fadd_s:
12 ; CHECK:       # %bb.0:
13 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa1
14 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa0
15 ; CHECK-NEXT:    fadd.s fa5, fa4, fa5
16 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
17 ; CHECK-NEXT:    ret
18   %1 = fadd bfloat %a, %b
19   ret bfloat %1
22 define bfloat @fsub_s(bfloat %a, bfloat %b) nounwind {
23 ; CHECK-LABEL: fsub_s:
24 ; CHECK:       # %bb.0:
25 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa1
26 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa0
27 ; CHECK-NEXT:    fsub.s fa5, fa4, fa5
28 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
29 ; CHECK-NEXT:    ret
30   %1 = fsub bfloat %a, %b
31   ret bfloat %1
34 define bfloat @fmul_s(bfloat %a, bfloat %b) nounwind {
35 ; CHECK-LABEL: fmul_s:
36 ; CHECK:       # %bb.0:
37 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa1
38 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa0
39 ; CHECK-NEXT:    fmul.s fa5, fa4, fa5
40 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
41 ; CHECK-NEXT:    ret
42   %1 = fmul bfloat %a, %b
43   ret bfloat %1
46 define bfloat @fdiv_s(bfloat %a, bfloat %b) nounwind {
47 ; CHECK-LABEL: fdiv_s:
48 ; CHECK:       # %bb.0:
49 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa1
50 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa0
51 ; CHECK-NEXT:    fdiv.s fa5, fa4, fa5
52 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
53 ; CHECK-NEXT:    ret
54   %1 = fdiv bfloat %a, %b
55   ret bfloat %1
58 declare bfloat @llvm.sqrt.bf16(bfloat)
60 define bfloat @fsqrt_s(bfloat %a) nounwind {
61 ; CHECK-LABEL: fsqrt_s:
62 ; CHECK:       # %bb.0:
63 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa0
64 ; CHECK-NEXT:    fsqrt.s fa5, fa5
65 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
66 ; CHECK-NEXT:    ret
67   %1 = call bfloat @llvm.sqrt.bf16(bfloat %a)
68   ret bfloat %1
71 declare bfloat @llvm.copysign.bf16(bfloat, bfloat)
73 define bfloat @fsgnj_s(bfloat %a, bfloat %b) nounwind {
74 ; RV32IZFBFMIN-LABEL: fsgnj_s:
75 ; RV32IZFBFMIN:       # %bb.0:
76 ; RV32IZFBFMIN-NEXT:    addi sp, sp, -16
77 ; RV32IZFBFMIN-NEXT:    fsh fa1, 12(sp)
78 ; RV32IZFBFMIN-NEXT:    fsh fa0, 8(sp)
79 ; RV32IZFBFMIN-NEXT:    lbu a0, 13(sp)
80 ; RV32IZFBFMIN-NEXT:    lbu a1, 9(sp)
81 ; RV32IZFBFMIN-NEXT:    andi a0, a0, 128
82 ; RV32IZFBFMIN-NEXT:    andi a1, a1, 127
83 ; RV32IZFBFMIN-NEXT:    or a0, a1, a0
84 ; RV32IZFBFMIN-NEXT:    sb a0, 9(sp)
85 ; RV32IZFBFMIN-NEXT:    flh fa0, 8(sp)
86 ; RV32IZFBFMIN-NEXT:    addi sp, sp, 16
87 ; RV32IZFBFMIN-NEXT:    ret
89 ; RV64IZFBFMIN-LABEL: fsgnj_s:
90 ; RV64IZFBFMIN:       # %bb.0:
91 ; RV64IZFBFMIN-NEXT:    addi sp, sp, -16
92 ; RV64IZFBFMIN-NEXT:    fsh fa1, 8(sp)
93 ; RV64IZFBFMIN-NEXT:    fsh fa0, 0(sp)
94 ; RV64IZFBFMIN-NEXT:    lbu a0, 9(sp)
95 ; RV64IZFBFMIN-NEXT:    lbu a1, 1(sp)
96 ; RV64IZFBFMIN-NEXT:    andi a0, a0, 128
97 ; RV64IZFBFMIN-NEXT:    andi a1, a1, 127
98 ; RV64IZFBFMIN-NEXT:    or a0, a1, a0
99 ; RV64IZFBFMIN-NEXT:    sb a0, 1(sp)
100 ; RV64IZFBFMIN-NEXT:    flh fa0, 0(sp)
101 ; RV64IZFBFMIN-NEXT:    addi sp, sp, 16
102 ; RV64IZFBFMIN-NEXT:    ret
103   %1 = call bfloat @llvm.copysign.bf16(bfloat %a, bfloat %b)
104   ret bfloat %1
107 define i32 @fneg_s(bfloat %a, bfloat %b) nounwind {
108 ; CHECK-LABEL: fneg_s:
109 ; CHECK:       # %bb.0:
110 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa0
111 ; CHECK-NEXT:    fadd.s fa5, fa5, fa5
112 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
113 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
114 ; CHECK-NEXT:    fneg.s fa4, fa5
115 ; CHECK-NEXT:    fcvt.bf16.s fa4, fa4
116 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa4
117 ; CHECK-NEXT:    feq.s a0, fa5, fa4
118 ; CHECK-NEXT:    ret
119   %1 = fadd bfloat %a, %a
120   %2 = fneg bfloat %1
121   %3 = fcmp oeq bfloat %1, %2
122   %4 = zext i1 %3 to i32
123   ret i32 %4
126 define bfloat @fsgnjn_s(bfloat %a, bfloat %b) nounwind {
127 ; RV32IZFBFMIN-LABEL: fsgnjn_s:
128 ; RV32IZFBFMIN:       # %bb.0:
129 ; RV32IZFBFMIN-NEXT:    addi sp, sp, -16
130 ; RV32IZFBFMIN-NEXT:    fcvt.s.bf16 fa5, fa1
131 ; RV32IZFBFMIN-NEXT:    fcvt.s.bf16 fa4, fa0
132 ; RV32IZFBFMIN-NEXT:    fadd.s fa5, fa4, fa5
133 ; RV32IZFBFMIN-NEXT:    fcvt.bf16.s fa5, fa5
134 ; RV32IZFBFMIN-NEXT:    fcvt.s.bf16 fa5, fa5
135 ; RV32IZFBFMIN-NEXT:    fneg.s fa5, fa5
136 ; RV32IZFBFMIN-NEXT:    fcvt.bf16.s fa5, fa5
137 ; RV32IZFBFMIN-NEXT:    fsh fa0, 8(sp)
138 ; RV32IZFBFMIN-NEXT:    fsh fa5, 12(sp)
139 ; RV32IZFBFMIN-NEXT:    lbu a0, 9(sp)
140 ; RV32IZFBFMIN-NEXT:    lbu a1, 13(sp)
141 ; RV32IZFBFMIN-NEXT:    andi a0, a0, 127
142 ; RV32IZFBFMIN-NEXT:    andi a1, a1, 128
143 ; RV32IZFBFMIN-NEXT:    or a0, a0, a1
144 ; RV32IZFBFMIN-NEXT:    sb a0, 9(sp)
145 ; RV32IZFBFMIN-NEXT:    flh fa0, 8(sp)
146 ; RV32IZFBFMIN-NEXT:    addi sp, sp, 16
147 ; RV32IZFBFMIN-NEXT:    ret
149 ; RV64IZFBFMIN-LABEL: fsgnjn_s:
150 ; RV64IZFBFMIN:       # %bb.0:
151 ; RV64IZFBFMIN-NEXT:    addi sp, sp, -16
152 ; RV64IZFBFMIN-NEXT:    fcvt.s.bf16 fa5, fa1
153 ; RV64IZFBFMIN-NEXT:    fcvt.s.bf16 fa4, fa0
154 ; RV64IZFBFMIN-NEXT:    fadd.s fa5, fa4, fa5
155 ; RV64IZFBFMIN-NEXT:    fcvt.bf16.s fa5, fa5
156 ; RV64IZFBFMIN-NEXT:    fcvt.s.bf16 fa5, fa5
157 ; RV64IZFBFMIN-NEXT:    fneg.s fa5, fa5
158 ; RV64IZFBFMIN-NEXT:    fcvt.bf16.s fa5, fa5
159 ; RV64IZFBFMIN-NEXT:    fsh fa0, 0(sp)
160 ; RV64IZFBFMIN-NEXT:    fsh fa5, 8(sp)
161 ; RV64IZFBFMIN-NEXT:    lbu a0, 1(sp)
162 ; RV64IZFBFMIN-NEXT:    lbu a1, 9(sp)
163 ; RV64IZFBFMIN-NEXT:    andi a0, a0, 127
164 ; RV64IZFBFMIN-NEXT:    andi a1, a1, 128
165 ; RV64IZFBFMIN-NEXT:    or a0, a0, a1
166 ; RV64IZFBFMIN-NEXT:    sb a0, 1(sp)
167 ; RV64IZFBFMIN-NEXT:    flh fa0, 0(sp)
168 ; RV64IZFBFMIN-NEXT:    addi sp, sp, 16
169 ; RV64IZFBFMIN-NEXT:    ret
170   %1 = fadd bfloat %a, %b
171   %2 = fneg bfloat %1
172   %3 = call bfloat @llvm.copysign.bf16(bfloat %a, bfloat %2)
173   ret bfloat %3
176 declare bfloat @llvm.fabs.bf16(bfloat)
178 define bfloat @fabs_s(bfloat %a, bfloat %b) nounwind {
179 ; CHECK-LABEL: fabs_s:
180 ; CHECK:       # %bb.0:
181 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa1
182 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa0
183 ; CHECK-NEXT:    fadd.s fa5, fa4, fa5
184 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
185 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
186 ; CHECK-NEXT:    fabs.s fa4, fa5
187 ; CHECK-NEXT:    fcvt.bf16.s fa4, fa4
188 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa4
189 ; CHECK-NEXT:    fadd.s fa5, fa4, fa5
190 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
191 ; CHECK-NEXT:    ret
192   %1 = fadd bfloat %a, %b
193   %2 = call bfloat @llvm.fabs.bf16(bfloat %1)
194   %3 = fadd bfloat %2, %1
195   ret bfloat %3
198 declare bfloat @llvm.minnum.bf16(bfloat, bfloat)
200 define bfloat @fmin_s(bfloat %a, bfloat %b) nounwind {
201 ; CHECK-LABEL: fmin_s:
202 ; CHECK:       # %bb.0:
203 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa1
204 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa0
205 ; CHECK-NEXT:    fmin.s fa5, fa4, fa5
206 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
207 ; CHECK-NEXT:    ret
208   %1 = call bfloat @llvm.minnum.bf16(bfloat %a, bfloat %b)
209   ret bfloat %1
212 declare bfloat @llvm.maxnum.bf16(bfloat, bfloat)
214 define bfloat @fmax_s(bfloat %a, bfloat %b) nounwind {
215 ; CHECK-LABEL: fmax_s:
216 ; CHECK:       # %bb.0:
217 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa1
218 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa0
219 ; CHECK-NEXT:    fmax.s fa5, fa4, fa5
220 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
221 ; CHECK-NEXT:    ret
222   %1 = call bfloat @llvm.maxnum.bf16(bfloat %a, bfloat %b)
223   ret bfloat %1
226 declare bfloat @llvm.fma.bf16(bfloat, bfloat, bfloat)
228 define bfloat @fmadd_s(bfloat %a, bfloat %b, bfloat %c) nounwind {
229 ; CHECK-LABEL: fmadd_s:
230 ; CHECK:       # %bb.0:
231 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa2
232 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa1
233 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa0
234 ; CHECK-NEXT:    fmadd.s fa5, fa3, fa4, fa5
235 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
236 ; CHECK-NEXT:    ret
237   %1 = call bfloat @llvm.fma.bf16(bfloat %a, bfloat %b, bfloat %c)
238   ret bfloat %1
241 define bfloat @fmsub_s(bfloat %a, bfloat %b, bfloat %c) nounwind {
242 ; CHECK-LABEL: fmsub_s:
243 ; CHECK:       # %bb.0:
244 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa2
245 ; CHECK-NEXT:    fmv.w.x fa4, zero
246 ; CHECK-NEXT:    fadd.s fa5, fa5, fa4
247 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
248 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
249 ; CHECK-NEXT:    fneg.s fa5, fa5
250 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
251 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
252 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa1
253 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa0
254 ; CHECK-NEXT:    fmadd.s fa5, fa3, fa4, fa5
255 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
256 ; CHECK-NEXT:    ret
257   %c_ = fadd bfloat 0.0, %c ; avoid negation using xor
258   %negc = fsub bfloat -0.0, %c_
259   %1 = call bfloat @llvm.fma.bf16(bfloat %a, bfloat %b, bfloat %negc)
260   ret bfloat %1
263 define bfloat @fnmadd_s(bfloat %a, bfloat %b, bfloat %c) nounwind {
264 ; CHECK-LABEL: fnmadd_s:
265 ; CHECK:       # %bb.0:
266 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa0
267 ; CHECK-NEXT:    fmv.w.x fa4, zero
268 ; CHECK-NEXT:    fadd.s fa5, fa5, fa4
269 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
270 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa2
271 ; CHECK-NEXT:    fadd.s fa4, fa3, fa4
272 ; CHECK-NEXT:    fcvt.bf16.s fa4, fa4
273 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
274 ; CHECK-NEXT:    fneg.s fa5, fa5
275 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
276 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa4
277 ; CHECK-NEXT:    fneg.s fa4, fa4
278 ; CHECK-NEXT:    fcvt.bf16.s fa4, fa4
279 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa4
280 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
281 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa1
282 ; CHECK-NEXT:    fmadd.s fa5, fa5, fa3, fa4
283 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
284 ; CHECK-NEXT:    ret
285   %a_ = fadd bfloat 0.0, %a
286   %c_ = fadd bfloat 0.0, %c
287   %nega = fsub bfloat -0.0, %a_
288   %negc = fsub bfloat -0.0, %c_
289   %1 = call bfloat @llvm.fma.bf16(bfloat %nega, bfloat %b, bfloat %negc)
290   ret bfloat %1
293 define bfloat @fnmadd_s_2(bfloat %a, bfloat %b, bfloat %c) nounwind {
294 ; CHECK-LABEL: fnmadd_s_2:
295 ; CHECK:       # %bb.0:
296 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa1
297 ; CHECK-NEXT:    fmv.w.x fa4, zero
298 ; CHECK-NEXT:    fadd.s fa5, fa5, fa4
299 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
300 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa2
301 ; CHECK-NEXT:    fadd.s fa4, fa3, fa4
302 ; CHECK-NEXT:    fcvt.bf16.s fa4, fa4
303 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
304 ; CHECK-NEXT:    fneg.s fa5, fa5
305 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
306 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa4
307 ; CHECK-NEXT:    fneg.s fa4, fa4
308 ; CHECK-NEXT:    fcvt.bf16.s fa4, fa4
309 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa4
310 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
311 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa0
312 ; CHECK-NEXT:    fmadd.s fa5, fa3, fa5, fa4
313 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
314 ; CHECK-NEXT:    ret
315   %b_ = fadd bfloat 0.0, %b
316   %c_ = fadd bfloat 0.0, %c
317   %negb = fsub bfloat -0.0, %b_
318   %negc = fsub bfloat -0.0, %c_
319   %1 = call bfloat @llvm.fma.bf16(bfloat %a, bfloat %negb, bfloat %negc)
320   ret bfloat %1
323 define bfloat @fnmadd_s_3(bfloat %a, bfloat %b, bfloat %c) nounwind {
324 ; CHECK-LABEL: fnmadd_s_3:
325 ; CHECK:       # %bb.0:
326 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa2
327 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa1
328 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa0
329 ; CHECK-NEXT:    fmadd.s fa5, fa3, fa4, fa5
330 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
331 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
332 ; CHECK-NEXT:    fneg.s fa5, fa5
333 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
334 ; CHECK-NEXT:    ret
335   %1 = call bfloat @llvm.fma.bf16(bfloat %a, bfloat %b, bfloat %c)
336   %neg = fneg bfloat %1
337   ret bfloat %neg
341 define bfloat @fnmadd_nsz(bfloat %a, bfloat %b, bfloat %c) nounwind {
342 ; CHECK-LABEL: fnmadd_nsz:
343 ; CHECK:       # %bb.0:
344 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa2
345 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa1
346 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa0
347 ; CHECK-NEXT:    fmadd.s fa5, fa3, fa4, fa5
348 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
349 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
350 ; CHECK-NEXT:    fneg.s fa5, fa5
351 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
352 ; CHECK-NEXT:    ret
353   %1 = call nsz bfloat @llvm.fma.bf16(bfloat %a, bfloat %b, bfloat %c)
354   %neg = fneg nsz bfloat %1
355   ret bfloat %neg
358 define bfloat @fnmsub_s(bfloat %a, bfloat %b, bfloat %c) nounwind {
359 ; CHECK-LABEL: fnmsub_s:
360 ; CHECK:       # %bb.0:
361 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa0
362 ; CHECK-NEXT:    fmv.w.x fa4, zero
363 ; CHECK-NEXT:    fadd.s fa5, fa5, fa4
364 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
365 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
366 ; CHECK-NEXT:    fneg.s fa5, fa5
367 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
368 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
369 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa2
370 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa1
371 ; CHECK-NEXT:    fmadd.s fa5, fa5, fa3, fa4
372 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
373 ; CHECK-NEXT:    ret
374   %a_ = fadd bfloat 0.0, %a
375   %nega = fsub bfloat -0.0, %a_
376   %1 = call bfloat @llvm.fma.bf16(bfloat %nega, bfloat %b, bfloat %c)
377   ret bfloat %1
380 define bfloat @fnmsub_s_2(bfloat %a, bfloat %b, bfloat %c) nounwind {
381 ; CHECK-LABEL: fnmsub_s_2:
382 ; CHECK:       # %bb.0:
383 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa1
384 ; CHECK-NEXT:    fmv.w.x fa4, zero
385 ; CHECK-NEXT:    fadd.s fa5, fa5, fa4
386 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
387 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
388 ; CHECK-NEXT:    fneg.s fa5, fa5
389 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
390 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
391 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa2
392 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa0
393 ; CHECK-NEXT:    fmadd.s fa5, fa3, fa5, fa4
394 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
395 ; CHECK-NEXT:    ret
396   %b_ = fadd bfloat 0.0, %b
397   %negb = fsub bfloat -0.0, %b_
398   %1 = call bfloat @llvm.fma.bf16(bfloat %a, bfloat %negb, bfloat %c)
399   ret bfloat %1
402 define bfloat @fmadd_s_contract(bfloat %a, bfloat %b, bfloat %c) nounwind {
403 ; CHECK-LABEL: fmadd_s_contract:
404 ; CHECK:       # %bb.0:
405 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa1
406 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa0
407 ; CHECK-NEXT:    fmul.s fa5, fa4, fa5
408 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
409 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
410 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa2
411 ; CHECK-NEXT:    fadd.s fa5, fa5, fa4
412 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
413 ; CHECK-NEXT:    ret
414   %1 = fmul contract bfloat %a, %b
415   %2 = fadd contract bfloat %1, %c
416   ret bfloat %2
419 define bfloat @fmsub_s_contract(bfloat %a, bfloat %b, bfloat %c) nounwind {
420 ; CHECK-LABEL: fmsub_s_contract:
421 ; CHECK:       # %bb.0:
422 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa2
423 ; CHECK-NEXT:    fmv.w.x fa4, zero
424 ; CHECK-NEXT:    fadd.s fa5, fa5, fa4
425 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
426 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa1
427 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa0
428 ; CHECK-NEXT:    fmul.s fa4, fa3, fa4
429 ; CHECK-NEXT:    fcvt.bf16.s fa4, fa4
430 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
431 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa4
432 ; CHECK-NEXT:    fsub.s fa5, fa4, fa5
433 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
434 ; CHECK-NEXT:    ret
435   %c_ = fadd bfloat 0.0, %c ; avoid negation using xor
436   %1 = fmul contract bfloat %a, %b
437   %2 = fsub contract bfloat %1, %c_
438   ret bfloat %2
441 define bfloat @fnmadd_s_contract(bfloat %a, bfloat %b, bfloat %c) nounwind {
442 ; CHECK-LABEL: fnmadd_s_contract:
443 ; CHECK:       # %bb.0:
444 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa0
445 ; CHECK-NEXT:    fmv.w.x fa4, zero
446 ; CHECK-NEXT:    fadd.s fa5, fa5, fa4
447 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
448 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa1
449 ; CHECK-NEXT:    fadd.s fa3, fa3, fa4
450 ; CHECK-NEXT:    fcvt.bf16.s fa3, fa3
451 ; CHECK-NEXT:    fcvt.s.bf16 fa2, fa2
452 ; CHECK-NEXT:    fadd.s fa4, fa2, fa4
453 ; CHECK-NEXT:    fcvt.bf16.s fa4, fa4
454 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa3
455 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
456 ; CHECK-NEXT:    fmul.s fa5, fa5, fa3
457 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
458 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
459 ; CHECK-NEXT:    fneg.s fa5, fa5
460 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
461 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
462 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa4
463 ; CHECK-NEXT:    fsub.s fa5, fa5, fa4
464 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
465 ; CHECK-NEXT:    ret
466   %a_ = fadd bfloat 0.0, %a ; avoid negation using xor
467   %b_ = fadd bfloat 0.0, %b ; avoid negation using xor
468   %c_ = fadd bfloat 0.0, %c ; avoid negation using xor
469   %1 = fmul contract bfloat %a_, %b_
470   %2 = fneg bfloat %1
471   %3 = fsub contract bfloat %2, %c_
472   ret bfloat %3
475 define bfloat @fnmsub_s_contract(bfloat %a, bfloat %b, bfloat %c) nounwind {
476 ; CHECK-LABEL: fnmsub_s_contract:
477 ; CHECK:       # %bb.0:
478 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa0
479 ; CHECK-NEXT:    fmv.w.x fa4, zero
480 ; CHECK-NEXT:    fadd.s fa5, fa5, fa4
481 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
482 ; CHECK-NEXT:    fcvt.s.bf16 fa3, fa1
483 ; CHECK-NEXT:    fadd.s fa4, fa3, fa4
484 ; CHECK-NEXT:    fcvt.bf16.s fa4, fa4
485 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa4
486 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
487 ; CHECK-NEXT:    fmul.s fa5, fa5, fa4
488 ; CHECK-NEXT:    fcvt.bf16.s fa5, fa5
489 ; CHECK-NEXT:    fcvt.s.bf16 fa5, fa5
490 ; CHECK-NEXT:    fcvt.s.bf16 fa4, fa2
491 ; CHECK-NEXT:    fsub.s fa5, fa4, fa5
492 ; CHECK-NEXT:    fcvt.bf16.s fa0, fa5
493 ; CHECK-NEXT:    ret
494   %a_ = fadd bfloat 0.0, %a ; avoid negation using xor
495   %b_ = fadd bfloat 0.0, %b ; avoid negation using xor
496   %1 = fmul contract bfloat %a_, %b_
497   %2 = fsub contract bfloat %c, %1
498   ret bfloat %2