Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / RISCV / half-arith-strict.ll
blob02cd91c70759404e5ab12ab2c2b96ec8ca84d207
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+zfh -verify-machineinstrs \
3 ; RUN:   -disable-strictnode-mutation -target-abi ilp32f < %s | FileCheck %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \
5 ; RUN:   -disable-strictnode-mutation -target-abi lp64f < %s | FileCheck %s
6 ; RUN: llc -mtriple=riscv32 -mattr=+zhinx -verify-machineinstrs \
7 ; RUN:   -disable-strictnode-mutation -target-abi ilp32 < %s \
8 ; RUN:   | FileCheck -check-prefix=CHECK-ZHINX %s
9 ; RUN: llc -mtriple=riscv64 -mattr=+zhinx -verify-machineinstrs \
10 ; RUN:   -disable-strictnode-mutation -target-abi lp64 < %s \
11 ; RUN:   | FileCheck -check-prefix=CHECK-ZHINX %s
12 ; RUN: llc -mtriple=riscv32 -mattr=+zfhmin -verify-machineinstrs \
13 ; RUN:   -disable-strictnode-mutation -target-abi ilp32f < %s \
14 ; RUN:   | FileCheck -check-prefix=CHECK-ZFHMIN %s
15 ; RUN: llc -mtriple=riscv64 -mattr=+zfhmin -verify-machineinstrs \
16 ; RUN:   -disable-strictnode-mutation -target-abi lp64f < %s \
17 ; RUN:  | FileCheck -check-prefix=CHECK-ZFHMIN %s
18 ; RUN: llc -mtriple=riscv32 -mattr=+zhinxmin -verify-machineinstrs \
19 ; RUN:   -disable-strictnode-mutation -target-abi ilp32 < %s \
20 ; RUN:   | FileCheck -check-prefix=CHECK-ZHINXMIN %s
21 ; RUN: llc -mtriple=riscv64 -mattr=+zhinxmin -verify-machineinstrs \
22 ; RUN:   -disable-strictnode-mutation -target-abi lp64 < %s \
23 ; RUN:   | FileCheck -check-prefix=CHECK-ZHINXMIN %s
25 ; FIXME: We can't test without Zfh because soft promote legalization isn't
26 ; implemented in SelectionDAG for STRICT nodes.
28 define half @fadd_h(half %a, half %b) nounwind strictfp {
29 ; CHECK-LABEL: fadd_h:
30 ; CHECK:       # %bb.0:
31 ; CHECK-NEXT:    fadd.h fa0, fa0, fa1
32 ; CHECK-NEXT:    ret
34 ; CHECK-ZHINX-LABEL: fadd_h:
35 ; CHECK-ZHINX:       # %bb.0:
36 ; CHECK-ZHINX-NEXT:    fadd.h a0, a0, a1
37 ; CHECK-ZHINX-NEXT:    ret
39 ; CHECK-ZFHMIN-LABEL: fadd_h:
40 ; CHECK-ZFHMIN:       # %bb.0:
41 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
42 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
43 ; CHECK-ZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
44 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
45 ; CHECK-ZFHMIN-NEXT:    ret
47 ; CHECK-ZHINXMIN-LABEL: fadd_h:
48 ; CHECK-ZHINXMIN:       # %bb.0:
49 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
50 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
51 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, a1
52 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
53 ; CHECK-ZHINXMIN-NEXT:    ret
54   %1 = call half @llvm.experimental.constrained.fadd.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
55   ret half %1
57 declare half @llvm.experimental.constrained.fadd.f16(half, half, metadata, metadata)
59 define half @fsub_h(half %a, half %b) nounwind strictfp {
60 ; CHECK-LABEL: fsub_h:
61 ; CHECK:       # %bb.0:
62 ; CHECK-NEXT:    fsub.h fa0, fa0, fa1
63 ; CHECK-NEXT:    ret
65 ; CHECK-ZHINX-LABEL: fsub_h:
66 ; CHECK-ZHINX:       # %bb.0:
67 ; CHECK-ZHINX-NEXT:    fsub.h a0, a0, a1
68 ; CHECK-ZHINX-NEXT:    ret
70 ; CHECK-ZFHMIN-LABEL: fsub_h:
71 ; CHECK-ZFHMIN:       # %bb.0:
72 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
73 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
74 ; CHECK-ZFHMIN-NEXT:    fsub.s fa5, fa4, fa5
75 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
76 ; CHECK-ZFHMIN-NEXT:    ret
78 ; CHECK-ZHINXMIN-LABEL: fsub_h:
79 ; CHECK-ZHINXMIN:       # %bb.0:
80 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
81 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
82 ; CHECK-ZHINXMIN-NEXT:    fsub.s a0, a0, a1
83 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
84 ; CHECK-ZHINXMIN-NEXT:    ret
85   %1 = call half @llvm.experimental.constrained.fsub.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
86   ret half %1
88 declare half @llvm.experimental.constrained.fsub.f16(half, half, metadata, metadata)
90 define half @fmul_h(half %a, half %b) nounwind strictfp {
91 ; CHECK-LABEL: fmul_h:
92 ; CHECK:       # %bb.0:
93 ; CHECK-NEXT:    fmul.h fa0, fa0, fa1
94 ; CHECK-NEXT:    ret
96 ; CHECK-ZHINX-LABEL: fmul_h:
97 ; CHECK-ZHINX:       # %bb.0:
98 ; CHECK-ZHINX-NEXT:    fmul.h a0, a0, a1
99 ; CHECK-ZHINX-NEXT:    ret
101 ; CHECK-ZFHMIN-LABEL: fmul_h:
102 ; CHECK-ZFHMIN:       # %bb.0:
103 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
104 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
105 ; CHECK-ZFHMIN-NEXT:    fmul.s fa5, fa4, fa5
106 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
107 ; CHECK-ZFHMIN-NEXT:    ret
109 ; CHECK-ZHINXMIN-LABEL: fmul_h:
110 ; CHECK-ZHINXMIN:       # %bb.0:
111 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
112 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
113 ; CHECK-ZHINXMIN-NEXT:    fmul.s a0, a0, a1
114 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
115 ; CHECK-ZHINXMIN-NEXT:    ret
116   %1 = call half @llvm.experimental.constrained.fmul.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
117   ret half %1
119 declare half @llvm.experimental.constrained.fmul.f16(half, half, metadata, metadata)
121 define half @fdiv_h(half %a, half %b) nounwind strictfp {
122 ; CHECK-LABEL: fdiv_h:
123 ; CHECK:       # %bb.0:
124 ; CHECK-NEXT:    fdiv.h fa0, fa0, fa1
125 ; CHECK-NEXT:    ret
127 ; CHECK-ZHINX-LABEL: fdiv_h:
128 ; CHECK-ZHINX:       # %bb.0:
129 ; CHECK-ZHINX-NEXT:    fdiv.h a0, a0, a1
130 ; CHECK-ZHINX-NEXT:    ret
132 ; CHECK-ZFHMIN-LABEL: fdiv_h:
133 ; CHECK-ZFHMIN:       # %bb.0:
134 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
135 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
136 ; CHECK-ZFHMIN-NEXT:    fdiv.s fa5, fa4, fa5
137 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
138 ; CHECK-ZFHMIN-NEXT:    ret
140 ; CHECK-ZHINXMIN-LABEL: fdiv_h:
141 ; CHECK-ZHINXMIN:       # %bb.0:
142 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
143 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
144 ; CHECK-ZHINXMIN-NEXT:    fdiv.s a0, a0, a1
145 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
146 ; CHECK-ZHINXMIN-NEXT:    ret
147   %1 = call half @llvm.experimental.constrained.fdiv.f16(half %a, half %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
148   ret half %1
150 declare half @llvm.experimental.constrained.fdiv.f16(half, half, metadata, metadata)
152 define half @fsqrt_h(half %a) nounwind strictfp {
153 ; CHECK-LABEL: fsqrt_h:
154 ; CHECK:       # %bb.0:
155 ; CHECK-NEXT:    fsqrt.h fa0, fa0
156 ; CHECK-NEXT:    ret
158 ; CHECK-ZHINX-LABEL: fsqrt_h:
159 ; CHECK-ZHINX:       # %bb.0:
160 ; CHECK-ZHINX-NEXT:    fsqrt.h a0, a0
161 ; CHECK-ZHINX-NEXT:    ret
163 ; CHECK-ZFHMIN-LABEL: fsqrt_h:
164 ; CHECK-ZFHMIN:       # %bb.0:
165 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
166 ; CHECK-ZFHMIN-NEXT:    fsqrt.s fa5, fa5
167 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
168 ; CHECK-ZFHMIN-NEXT:    ret
170 ; CHECK-ZHINXMIN-LABEL: fsqrt_h:
171 ; CHECK-ZHINXMIN:       # %bb.0:
172 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
173 ; CHECK-ZHINXMIN-NEXT:    fsqrt.s a0, a0
174 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
175 ; CHECK-ZHINXMIN-NEXT:    ret
176   %1 = call half @llvm.experimental.constrained.sqrt.f16(half %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
177   ret half %1
179 declare half @llvm.experimental.constrained.sqrt.f16(half, metadata, metadata)
181 ; FIXME: fminnum/fmaxnum need libcalls to handle SNaN, but we don't have f16
182 ; libcalls and don't support promotion yet.
183 ;define half @fmin_h(half %a, half %b) nounwind strictfp {
184 ;  %1 = call half @llvm.experimental.constrained.minnum.f16(half %a, half %b, metadata !"fpexcept.strict") strictfp
185 ;  ret half %1
187 ;declare half @llvm.experimental.constrained.minnum.f16(half, half, metadata) strictfp
189 ;define half @fmax_h(half %a, half %b) nounwind strictfp {
190 ;  %1 = call half @llvm.experimental.constrained.maxnum.f16(half %a, half %b, metadata !"fpexcept.strict") strictfp
191 ;  ret half %1
193 ;declare half @llvm.experimental.constrained.maxnum.f16(half, half, metadata) strictfp
195 define half @fmadd_h(half %a, half %b, half %c) nounwind strictfp {
196 ; CHECK-LABEL: fmadd_h:
197 ; CHECK:       # %bb.0:
198 ; CHECK-NEXT:    fmadd.h fa0, fa0, fa1, fa2
199 ; CHECK-NEXT:    ret
201 ; CHECK-ZHINX-LABEL: fmadd_h:
202 ; CHECK-ZHINX:       # %bb.0:
203 ; CHECK-ZHINX-NEXT:    fmadd.h a0, a0, a1, a2
204 ; CHECK-ZHINX-NEXT:    ret
206 ; CHECK-ZFHMIN-LABEL: fmadd_h:
207 ; CHECK-ZFHMIN:       # %bb.0:
208 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa2
209 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa1
210 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa3, fa0
211 ; CHECK-ZFHMIN-NEXT:    fmadd.s fa5, fa3, fa4, fa5
212 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
213 ; CHECK-ZFHMIN-NEXT:    ret
215 ; CHECK-ZHINXMIN-LABEL: fmadd_h:
216 ; CHECK-ZHINXMIN:       # %bb.0:
217 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
218 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
219 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
220 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
221 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
222 ; CHECK-ZHINXMIN-NEXT:    ret
223   %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %b, half %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
224   ret half %1
226 declare half @llvm.experimental.constrained.fma.f16(half, half, half, metadata, metadata) strictfp
228 define half @fmsub_h(half %a, half %b, half %c) nounwind strictfp {
229 ; CHECK-LABEL: fmsub_h:
230 ; CHECK:       # %bb.0:
231 ; CHECK-NEXT:    fmv.h.x fa5, zero
232 ; CHECK-NEXT:    fadd.h fa5, fa2, fa5
233 ; CHECK-NEXT:    fmsub.h fa0, fa0, fa1, fa5
234 ; CHECK-NEXT:    ret
236 ; CHECK-ZHINX-LABEL: fmsub_h:
237 ; CHECK-ZHINX:       # %bb.0:
238 ; CHECK-ZHINX-NEXT:    fadd.h a2, a2, zero
239 ; CHECK-ZHINX-NEXT:    fmsub.h a0, a0, a1, a2
240 ; CHECK-ZHINX-NEXT:    ret
242 ; CHECK-ZFHMIN-LABEL: fmsub_h:
243 ; CHECK-ZFHMIN:       # %bb.0:
244 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa2
245 ; CHECK-ZFHMIN-NEXT:    fmv.w.x fa4, zero
246 ; CHECK-ZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
247 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa5, fa5
248 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa5
249 ; CHECK-ZFHMIN-NEXT:    fneg.s fa5, fa5
250 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa5, fa5
251 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa5
252 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa1
253 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa3, fa0
254 ; CHECK-ZFHMIN-NEXT:    fmadd.s fa5, fa3, fa4, fa5
255 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
256 ; CHECK-ZFHMIN-NEXT:    ret
258 ; CHECK-ZHINXMIN-LABEL: fmsub_h:
259 ; CHECK-ZHINXMIN:       # %bb.0:
260 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
261 ; CHECK-ZHINXMIN-NEXT:    fadd.s a2, a2, zero
262 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
263 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
264 ; CHECK-ZHINXMIN-NEXT:    fneg.s a2, a2
265 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
266 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
267 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
268 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
269 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
270 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
271 ; CHECK-ZHINXMIN-NEXT:    ret
272   %c_ = fadd half 0.0, %c ; avoid negation using xor
273   %negc = fneg half %c_
274   %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %b, half %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
275   ret half %1
278 define half @fnmadd_h(half %a, half %b, half %c) nounwind strictfp {
279 ; CHECK-LABEL: fnmadd_h:
280 ; CHECK:       # %bb.0:
281 ; CHECK-NEXT:    fmv.h.x fa5, zero
282 ; CHECK-NEXT:    fadd.h fa4, fa0, fa5
283 ; CHECK-NEXT:    fadd.h fa5, fa2, fa5
284 ; CHECK-NEXT:    fnmadd.h fa0, fa4, fa1, fa5
285 ; CHECK-NEXT:    ret
287 ; CHECK-ZHINX-LABEL: fnmadd_h:
288 ; CHECK-ZHINX:       # %bb.0:
289 ; CHECK-ZHINX-NEXT:    fadd.h a0, a0, zero
290 ; CHECK-ZHINX-NEXT:    fadd.h a2, a2, zero
291 ; CHECK-ZHINX-NEXT:    fnmadd.h a0, a0, a1, a2
292 ; CHECK-ZHINX-NEXT:    ret
294 ; CHECK-ZFHMIN-LABEL: fnmadd_h:
295 ; CHECK-ZFHMIN:       # %bb.0:
296 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
297 ; CHECK-ZFHMIN-NEXT:    fmv.w.x fa4, zero
298 ; CHECK-ZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
299 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa5, fa5
300 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa3, fa2
301 ; CHECK-ZFHMIN-NEXT:    fadd.s fa4, fa3, fa4
302 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa4, fa4
303 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa5
304 ; CHECK-ZFHMIN-NEXT:    fneg.s fa5, fa5
305 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa5, fa5
306 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa4
307 ; CHECK-ZFHMIN-NEXT:    fneg.s fa4, fa4
308 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa4, fa4
309 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa4
310 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa5
311 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa3, fa1
312 ; CHECK-ZFHMIN-NEXT:    fmadd.s fa5, fa5, fa3, fa4
313 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
314 ; CHECK-ZFHMIN-NEXT:    ret
316 ; CHECK-ZHINXMIN-LABEL: fnmadd_h:
317 ; CHECK-ZHINXMIN:       # %bb.0:
318 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
319 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, zero
320 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
321 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
322 ; CHECK-ZHINXMIN-NEXT:    fadd.s a2, a2, zero
323 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
324 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
325 ; CHECK-ZHINXMIN-NEXT:    fneg.s a0, a0
326 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
327 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
328 ; CHECK-ZHINXMIN-NEXT:    fneg.s a2, a2
329 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
330 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
331 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
332 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
333 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
334 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
335 ; CHECK-ZHINXMIN-NEXT:    ret
336   %a_ = fadd half 0.0, %a
337   %c_ = fadd half 0.0, %c
338   %nega = fneg half %a_
339   %negc = fneg half %c_
340   %1 = call half @llvm.experimental.constrained.fma.f16(half %nega, half %b, half %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
341   ret half %1
344 define half @fnmadd_h_2(half %a, half %b, half %c) nounwind strictfp {
345 ; CHECK-LABEL: fnmadd_h_2:
346 ; CHECK:       # %bb.0:
347 ; CHECK-NEXT:    fmv.h.x fa5, zero
348 ; CHECK-NEXT:    fadd.h fa4, fa1, fa5
349 ; CHECK-NEXT:    fadd.h fa5, fa2, fa5
350 ; CHECK-NEXT:    fnmadd.h fa0, fa4, fa0, fa5
351 ; CHECK-NEXT:    ret
353 ; CHECK-ZHINX-LABEL: fnmadd_h_2:
354 ; CHECK-ZHINX:       # %bb.0:
355 ; CHECK-ZHINX-NEXT:    fadd.h a1, a1, zero
356 ; CHECK-ZHINX-NEXT:    fadd.h a2, a2, zero
357 ; CHECK-ZHINX-NEXT:    fnmadd.h a0, a1, a0, a2
358 ; CHECK-ZHINX-NEXT:    ret
360 ; CHECK-ZFHMIN-LABEL: fnmadd_h_2:
361 ; CHECK-ZFHMIN:       # %bb.0:
362 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
363 ; CHECK-ZFHMIN-NEXT:    fmv.w.x fa4, zero
364 ; CHECK-ZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
365 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa5, fa5
366 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa3, fa2
367 ; CHECK-ZFHMIN-NEXT:    fadd.s fa4, fa3, fa4
368 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa4, fa4
369 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa5
370 ; CHECK-ZFHMIN-NEXT:    fneg.s fa5, fa5
371 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa5, fa5
372 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa4
373 ; CHECK-ZFHMIN-NEXT:    fneg.s fa4, fa4
374 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa4, fa4
375 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa4
376 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa5
377 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa3, fa0
378 ; CHECK-ZFHMIN-NEXT:    fmadd.s fa5, fa3, fa5, fa4
379 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
380 ; CHECK-ZFHMIN-NEXT:    ret
382 ; CHECK-ZHINXMIN-LABEL: fnmadd_h_2:
383 ; CHECK-ZHINXMIN:       # %bb.0:
384 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
385 ; CHECK-ZHINXMIN-NEXT:    fadd.s a1, a1, zero
386 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
387 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
388 ; CHECK-ZHINXMIN-NEXT:    fadd.s a2, a2, zero
389 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
390 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
391 ; CHECK-ZHINXMIN-NEXT:    fneg.s a1, a1
392 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
393 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
394 ; CHECK-ZHINXMIN-NEXT:    fneg.s a2, a2
395 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
396 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
397 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
398 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
399 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
400 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
401 ; CHECK-ZHINXMIN-NEXT:    ret
402   %b_ = fadd half 0.0, %b
403   %c_ = fadd half 0.0, %c
404   %negb = fneg half %b_
405   %negc = fneg half %c_
406   %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %negb, half %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
407   ret half %1
410 define half @fnmsub_h(half %a, half %b, half %c) nounwind strictfp {
411 ; CHECK-LABEL: fnmsub_h:
412 ; CHECK:       # %bb.0:
413 ; CHECK-NEXT:    fmv.h.x fa5, zero
414 ; CHECK-NEXT:    fadd.h fa5, fa0, fa5
415 ; CHECK-NEXT:    fnmsub.h fa0, fa5, fa1, fa2
416 ; CHECK-NEXT:    ret
418 ; CHECK-ZHINX-LABEL: fnmsub_h:
419 ; CHECK-ZHINX:       # %bb.0:
420 ; CHECK-ZHINX-NEXT:    fadd.h a0, a0, zero
421 ; CHECK-ZHINX-NEXT:    fnmsub.h a0, a0, a1, a2
422 ; CHECK-ZHINX-NEXT:    ret
424 ; CHECK-ZFHMIN-LABEL: fnmsub_h:
425 ; CHECK-ZFHMIN:       # %bb.0:
426 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
427 ; CHECK-ZFHMIN-NEXT:    fmv.w.x fa4, zero
428 ; CHECK-ZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
429 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa5, fa5
430 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa5
431 ; CHECK-ZFHMIN-NEXT:    fneg.s fa5, fa5
432 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa5, fa5
433 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa5
434 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa2
435 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa3, fa1
436 ; CHECK-ZFHMIN-NEXT:    fmadd.s fa5, fa5, fa3, fa4
437 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
438 ; CHECK-ZFHMIN-NEXT:    ret
440 ; CHECK-ZHINXMIN-LABEL: fnmsub_h:
441 ; CHECK-ZHINXMIN:       # %bb.0:
442 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
443 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, zero
444 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
445 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
446 ; CHECK-ZHINXMIN-NEXT:    fneg.s a0, a0
447 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
448 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
449 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
450 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
451 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
452 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
453 ; CHECK-ZHINXMIN-NEXT:    ret
454   %a_ = fadd half 0.0, %a
455   %nega = fneg half %a_
456   %1 = call half @llvm.experimental.constrained.fma.f16(half %nega, half %b, half %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
457   ret half %1
460 define half @fnmsub_h_2(half %a, half %b, half %c) nounwind strictfp {
461 ; CHECK-LABEL: fnmsub_h_2:
462 ; CHECK:       # %bb.0:
463 ; CHECK-NEXT:    fmv.h.x fa5, zero
464 ; CHECK-NEXT:    fadd.h fa5, fa1, fa5
465 ; CHECK-NEXT:    fnmsub.h fa0, fa5, fa0, fa2
466 ; CHECK-NEXT:    ret
468 ; CHECK-ZHINX-LABEL: fnmsub_h_2:
469 ; CHECK-ZHINX:       # %bb.0:
470 ; CHECK-ZHINX-NEXT:    fadd.h a1, a1, zero
471 ; CHECK-ZHINX-NEXT:    fnmsub.h a0, a1, a0, a2
472 ; CHECK-ZHINX-NEXT:    ret
474 ; CHECK-ZFHMIN-LABEL: fnmsub_h_2:
475 ; CHECK-ZFHMIN:       # %bb.0:
476 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
477 ; CHECK-ZFHMIN-NEXT:    fmv.w.x fa4, zero
478 ; CHECK-ZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
479 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa5, fa5
480 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa5
481 ; CHECK-ZFHMIN-NEXT:    fneg.s fa5, fa5
482 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa5, fa5
483 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa5, fa5
484 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa4, fa2
485 ; CHECK-ZFHMIN-NEXT:    fcvt.s.h fa3, fa0
486 ; CHECK-ZFHMIN-NEXT:    fmadd.s fa5, fa3, fa5, fa4
487 ; CHECK-ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
488 ; CHECK-ZFHMIN-NEXT:    ret
490 ; CHECK-ZHINXMIN-LABEL: fnmsub_h_2:
491 ; CHECK-ZHINXMIN:       # %bb.0:
492 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
493 ; CHECK-ZHINXMIN-NEXT:    fadd.s a1, a1, zero
494 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
495 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
496 ; CHECK-ZHINXMIN-NEXT:    fneg.s a1, a1
497 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
498 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
499 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
500 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
501 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
502 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
503 ; CHECK-ZHINXMIN-NEXT:    ret
504   %b_ = fadd half 0.0, %b
505   %negb = fneg half %b_
506   %1 = call half @llvm.experimental.constrained.fma.f16(half %a, half %negb, half %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
507   ret half %1