Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / RISCV / half-arith.ll
blobf54adaa24b1bb52746ce109f9d4bacddd9ad272a
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+zfh -verify-machineinstrs \
3 ; RUN:   -target-abi ilp32f < %s | FileCheck -check-prefix=CHECKIZFH %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \
5 ; RUN:   -target-abi lp64f < %s | FileCheck -check-prefix=CHECKIZFH %s
6 ; RUN: llc -mtriple=riscv32 -mattr=+zhinx -verify-machineinstrs \
7 ; RUN:   -target-abi ilp32 < %s | FileCheck -check-prefix=CHECK-ZHINX %s
8 ; RUN: llc -mtriple=riscv64 -mattr=+zhinx -verify-machineinstrs \
9 ; RUN:   -target-abi lp64 < %s | FileCheck -check-prefix=CHECK-ZHINX %s
10 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
11 ; RUN:   | FileCheck -check-prefix=RV32I %s
12 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
13 ; RUN:   | FileCheck -check-prefix=RV64I %s
14 ; RUN: llc -mtriple=riscv32 -mattr=+zfhmin -verify-machineinstrs \
15 ; RUN:   -target-abi ilp32f < %s | FileCheck -check-prefixes=CHECKIZFHMIN,CHECK-RV32-FSGNJ %s
16 ; RUN: llc -mtriple=riscv64 -mattr=+zfhmin -verify-machineinstrs \
17 ; RUN:   -target-abi lp64f < %s | FileCheck --check-prefixes=CHECKIZFHMIN,CHECK-RV64-FSGNJ %s
18 ; RUN: llc -mtriple=riscv32 -mattr=+zhinxmin -verify-machineinstrs \
19 ; RUN:   -target-abi ilp32 < %s | FileCheck --check-prefixes=CHECKZHINXMIN %s
20 ; RUN: llc -mtriple=riscv64 -mattr=+zhinxmin -verify-machineinstrs \
21 ; RUN:   -target-abi lp64 < %s | FileCheck --check-prefixes=CHECKZHINXMIN %s
23 ; These tests are each targeted at a particular RISC-V FPU instruction.
24 ; Compares and conversions can be found in half-fcmp.ll and half-convert.ll
25 ; respectively. Some other half-*.ll files in this folder exercise LLVM IR
26 ; instructions that don't directly match a RISC-V instruction.
28 define half @fadd_s(half %a, half %b) nounwind {
29 ; CHECKIZFH-LABEL: fadd_s:
30 ; CHECKIZFH:       # %bb.0:
31 ; CHECKIZFH-NEXT:    fadd.h fa0, fa0, fa1
32 ; CHECKIZFH-NEXT:    ret
34 ; CHECK-ZHINX-LABEL: fadd_s:
35 ; CHECK-ZHINX:       # %bb.0:
36 ; CHECK-ZHINX-NEXT:    fadd.h a0, a0, a1
37 ; CHECK-ZHINX-NEXT:    ret
39 ; RV32I-LABEL: fadd_s:
40 ; RV32I:       # %bb.0:
41 ; RV32I-NEXT:    addi sp, sp, -16
42 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
43 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
44 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
45 ; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
46 ; RV32I-NEXT:    mv s0, a1
47 ; RV32I-NEXT:    lui a1, 16
48 ; RV32I-NEXT:    addi s2, a1, -1
49 ; RV32I-NEXT:    and a0, a0, s2
50 ; RV32I-NEXT:    call __extendhfsf2
51 ; RV32I-NEXT:    mv s1, a0
52 ; RV32I-NEXT:    and a0, s0, s2
53 ; RV32I-NEXT:    call __extendhfsf2
54 ; RV32I-NEXT:    mv a1, a0
55 ; RV32I-NEXT:    mv a0, s1
56 ; RV32I-NEXT:    call __addsf3
57 ; RV32I-NEXT:    call __truncsfhf2
58 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
59 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
60 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
61 ; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
62 ; RV32I-NEXT:    addi sp, sp, 16
63 ; RV32I-NEXT:    ret
65 ; RV64I-LABEL: fadd_s:
66 ; RV64I:       # %bb.0:
67 ; RV64I-NEXT:    addi sp, sp, -32
68 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
69 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
70 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
71 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
72 ; RV64I-NEXT:    mv s0, a1
73 ; RV64I-NEXT:    lui a1, 16
74 ; RV64I-NEXT:    addiw s2, a1, -1
75 ; RV64I-NEXT:    and a0, a0, s2
76 ; RV64I-NEXT:    call __extendhfsf2
77 ; RV64I-NEXT:    mv s1, a0
78 ; RV64I-NEXT:    and a0, s0, s2
79 ; RV64I-NEXT:    call __extendhfsf2
80 ; RV64I-NEXT:    mv a1, a0
81 ; RV64I-NEXT:    mv a0, s1
82 ; RV64I-NEXT:    call __addsf3
83 ; RV64I-NEXT:    call __truncsfhf2
84 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
85 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
86 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
87 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
88 ; RV64I-NEXT:    addi sp, sp, 32
89 ; RV64I-NEXT:    ret
91 ; CHECKIZFHMIN-LABEL: fadd_s:
92 ; CHECKIZFHMIN:       # %bb.0:
93 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
94 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa0
95 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
96 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
97 ; CHECKIZFHMIN-NEXT:    ret
99 ; CHECKZHINXMIN-LABEL: fadd_s:
100 ; CHECKZHINXMIN:       # %bb.0:
101 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
102 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
103 ; CHECKZHINXMIN-NEXT:    fadd.s a0, a0, a1
104 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
105 ; CHECKZHINXMIN-NEXT:    ret
106 ; CHECK-ZHINXMIN-LABEL: fadd_s:
107 ; CHECK-ZHINXMIN:       # %bb.0:
108 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
109 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
110 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, a1
111 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
112 ; CHECK-ZHINXMIN-NEXT:    ret
113   %1 = fadd half %a, %b
114   ret half %1
117 define half @fsub_s(half %a, half %b) nounwind {
118 ; CHECKIZFH-LABEL: fsub_s:
119 ; CHECKIZFH:       # %bb.0:
120 ; CHECKIZFH-NEXT:    fsub.h fa0, fa0, fa1
121 ; CHECKIZFH-NEXT:    ret
123 ; CHECK-ZHINX-LABEL: fsub_s:
124 ; CHECK-ZHINX:       # %bb.0:
125 ; CHECK-ZHINX-NEXT:    fsub.h a0, a0, a1
126 ; CHECK-ZHINX-NEXT:    ret
128 ; RV32I-LABEL: fsub_s:
129 ; RV32I:       # %bb.0:
130 ; RV32I-NEXT:    addi sp, sp, -16
131 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
132 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
133 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
134 ; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
135 ; RV32I-NEXT:    mv s0, a1
136 ; RV32I-NEXT:    lui a1, 16
137 ; RV32I-NEXT:    addi s2, a1, -1
138 ; RV32I-NEXT:    and a0, a0, s2
139 ; RV32I-NEXT:    call __extendhfsf2
140 ; RV32I-NEXT:    mv s1, a0
141 ; RV32I-NEXT:    and a0, s0, s2
142 ; RV32I-NEXT:    call __extendhfsf2
143 ; RV32I-NEXT:    mv a1, a0
144 ; RV32I-NEXT:    mv a0, s1
145 ; RV32I-NEXT:    call __subsf3
146 ; RV32I-NEXT:    call __truncsfhf2
147 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
148 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
149 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
150 ; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
151 ; RV32I-NEXT:    addi sp, sp, 16
152 ; RV32I-NEXT:    ret
154 ; RV64I-LABEL: fsub_s:
155 ; RV64I:       # %bb.0:
156 ; RV64I-NEXT:    addi sp, sp, -32
157 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
158 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
159 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
160 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
161 ; RV64I-NEXT:    mv s0, a1
162 ; RV64I-NEXT:    lui a1, 16
163 ; RV64I-NEXT:    addiw s2, a1, -1
164 ; RV64I-NEXT:    and a0, a0, s2
165 ; RV64I-NEXT:    call __extendhfsf2
166 ; RV64I-NEXT:    mv s1, a0
167 ; RV64I-NEXT:    and a0, s0, s2
168 ; RV64I-NEXT:    call __extendhfsf2
169 ; RV64I-NEXT:    mv a1, a0
170 ; RV64I-NEXT:    mv a0, s1
171 ; RV64I-NEXT:    call __subsf3
172 ; RV64I-NEXT:    call __truncsfhf2
173 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
174 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
175 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
176 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
177 ; RV64I-NEXT:    addi sp, sp, 32
178 ; RV64I-NEXT:    ret
180 ; CHECKIZFHMIN-LABEL: fsub_s:
181 ; CHECKIZFHMIN:       # %bb.0:
182 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
183 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa0
184 ; CHECKIZFHMIN-NEXT:    fsub.s fa5, fa4, fa5
185 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
186 ; CHECKIZFHMIN-NEXT:    ret
188 ; CHECKZHINXMIN-LABEL: fsub_s:
189 ; CHECKZHINXMIN:       # %bb.0:
190 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
191 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
192 ; CHECKZHINXMIN-NEXT:    fsub.s a0, a0, a1
193 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
194 ; CHECKZHINXMIN-NEXT:    ret
195 ; CHECK-ZHINXMIN-LABEL: fsub_s:
196 ; CHECK-ZHINXMIN:       # %bb.0:
197 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
198 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
199 ; CHECK-ZHINXMIN-NEXT:    fsub.s a0, a0, a1
200 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
201 ; CHECK-ZHINXMIN-NEXT:    ret
202   %1 = fsub half %a, %b
203   ret half %1
206 define half @fmul_s(half %a, half %b) nounwind {
207 ; CHECKIZFH-LABEL: fmul_s:
208 ; CHECKIZFH:       # %bb.0:
209 ; CHECKIZFH-NEXT:    fmul.h fa0, fa0, fa1
210 ; CHECKIZFH-NEXT:    ret
212 ; CHECK-ZHINX-LABEL: fmul_s:
213 ; CHECK-ZHINX:       # %bb.0:
214 ; CHECK-ZHINX-NEXT:    fmul.h a0, a0, a1
215 ; CHECK-ZHINX-NEXT:    ret
217 ; RV32I-LABEL: fmul_s:
218 ; RV32I:       # %bb.0:
219 ; RV32I-NEXT:    addi sp, sp, -16
220 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
221 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
222 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
223 ; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
224 ; RV32I-NEXT:    mv s0, a1
225 ; RV32I-NEXT:    lui a1, 16
226 ; RV32I-NEXT:    addi s2, a1, -1
227 ; RV32I-NEXT:    and a0, a0, s2
228 ; RV32I-NEXT:    call __extendhfsf2
229 ; RV32I-NEXT:    mv s1, a0
230 ; RV32I-NEXT:    and a0, s0, s2
231 ; RV32I-NEXT:    call __extendhfsf2
232 ; RV32I-NEXT:    mv a1, a0
233 ; RV32I-NEXT:    mv a0, s1
234 ; RV32I-NEXT:    call __mulsf3
235 ; RV32I-NEXT:    call __truncsfhf2
236 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
237 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
238 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
239 ; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
240 ; RV32I-NEXT:    addi sp, sp, 16
241 ; RV32I-NEXT:    ret
243 ; RV64I-LABEL: fmul_s:
244 ; RV64I:       # %bb.0:
245 ; RV64I-NEXT:    addi sp, sp, -32
246 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
247 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
248 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
249 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
250 ; RV64I-NEXT:    mv s0, a1
251 ; RV64I-NEXT:    lui a1, 16
252 ; RV64I-NEXT:    addiw s2, a1, -1
253 ; RV64I-NEXT:    and a0, a0, s2
254 ; RV64I-NEXT:    call __extendhfsf2
255 ; RV64I-NEXT:    mv s1, a0
256 ; RV64I-NEXT:    and a0, s0, s2
257 ; RV64I-NEXT:    call __extendhfsf2
258 ; RV64I-NEXT:    mv a1, a0
259 ; RV64I-NEXT:    mv a0, s1
260 ; RV64I-NEXT:    call __mulsf3
261 ; RV64I-NEXT:    call __truncsfhf2
262 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
263 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
264 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
265 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
266 ; RV64I-NEXT:    addi sp, sp, 32
267 ; RV64I-NEXT:    ret
269 ; CHECKIZFHMIN-LABEL: fmul_s:
270 ; CHECKIZFHMIN:       # %bb.0:
271 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
272 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa0
273 ; CHECKIZFHMIN-NEXT:    fmul.s fa5, fa4, fa5
274 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
275 ; CHECKIZFHMIN-NEXT:    ret
277 ; CHECKZHINXMIN-LABEL: fmul_s:
278 ; CHECKZHINXMIN:       # %bb.0:
279 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
280 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
281 ; CHECKZHINXMIN-NEXT:    fmul.s a0, a0, a1
282 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
283 ; CHECKZHINXMIN-NEXT:    ret
284 ; CHECK-ZHINXMIN-LABEL: fmul_s:
285 ; CHECK-ZHINXMIN:       # %bb.0:
286 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
287 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
288 ; CHECK-ZHINXMIN-NEXT:    fmul.s a0, a0, a1
289 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
290 ; CHECK-ZHINXMIN-NEXT:    ret
291   %1 = fmul half %a, %b
292   ret half %1
295 define half @fdiv_s(half %a, half %b) nounwind {
296 ; CHECKIZFH-LABEL: fdiv_s:
297 ; CHECKIZFH:       # %bb.0:
298 ; CHECKIZFH-NEXT:    fdiv.h fa0, fa0, fa1
299 ; CHECKIZFH-NEXT:    ret
301 ; CHECK-ZHINX-LABEL: fdiv_s:
302 ; CHECK-ZHINX:       # %bb.0:
303 ; CHECK-ZHINX-NEXT:    fdiv.h a0, a0, a1
304 ; CHECK-ZHINX-NEXT:    ret
306 ; RV32I-LABEL: fdiv_s:
307 ; RV32I:       # %bb.0:
308 ; RV32I-NEXT:    addi sp, sp, -16
309 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
310 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
311 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
312 ; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
313 ; RV32I-NEXT:    mv s0, a1
314 ; RV32I-NEXT:    lui a1, 16
315 ; RV32I-NEXT:    addi s2, a1, -1
316 ; RV32I-NEXT:    and a0, a0, s2
317 ; RV32I-NEXT:    call __extendhfsf2
318 ; RV32I-NEXT:    mv s1, a0
319 ; RV32I-NEXT:    and a0, s0, s2
320 ; RV32I-NEXT:    call __extendhfsf2
321 ; RV32I-NEXT:    mv a1, a0
322 ; RV32I-NEXT:    mv a0, s1
323 ; RV32I-NEXT:    call __divsf3
324 ; RV32I-NEXT:    call __truncsfhf2
325 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
326 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
327 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
328 ; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
329 ; RV32I-NEXT:    addi sp, sp, 16
330 ; RV32I-NEXT:    ret
332 ; RV64I-LABEL: fdiv_s:
333 ; RV64I:       # %bb.0:
334 ; RV64I-NEXT:    addi sp, sp, -32
335 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
336 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
337 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
338 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
339 ; RV64I-NEXT:    mv s0, a1
340 ; RV64I-NEXT:    lui a1, 16
341 ; RV64I-NEXT:    addiw s2, a1, -1
342 ; RV64I-NEXT:    and a0, a0, s2
343 ; RV64I-NEXT:    call __extendhfsf2
344 ; RV64I-NEXT:    mv s1, a0
345 ; RV64I-NEXT:    and a0, s0, s2
346 ; RV64I-NEXT:    call __extendhfsf2
347 ; RV64I-NEXT:    mv a1, a0
348 ; RV64I-NEXT:    mv a0, s1
349 ; RV64I-NEXT:    call __divsf3
350 ; RV64I-NEXT:    call __truncsfhf2
351 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
352 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
353 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
354 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
355 ; RV64I-NEXT:    addi sp, sp, 32
356 ; RV64I-NEXT:    ret
358 ; CHECKIZFHMIN-LABEL: fdiv_s:
359 ; CHECKIZFHMIN:       # %bb.0:
360 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
361 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa0
362 ; CHECKIZFHMIN-NEXT:    fdiv.s fa5, fa4, fa5
363 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
364 ; CHECKIZFHMIN-NEXT:    ret
366 ; CHECKZHINXMIN-LABEL: fdiv_s:
367 ; CHECKZHINXMIN:       # %bb.0:
368 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
369 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
370 ; CHECKZHINXMIN-NEXT:    fdiv.s a0, a0, a1
371 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
372 ; CHECKZHINXMIN-NEXT:    ret
373 ; CHECK-ZHINXMIN-LABEL: fdiv_s:
374 ; CHECK-ZHINXMIN:       # %bb.0:
375 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
376 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
377 ; CHECK-ZHINXMIN-NEXT:    fdiv.s a0, a0, a1
378 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
379 ; CHECK-ZHINXMIN-NEXT:    ret
380   %1 = fdiv half %a, %b
381   ret half %1
384 declare half @llvm.sqrt.f16(half)
386 define half @fsqrt_s(half %a) nounwind {
387 ; CHECKIZFH-LABEL: fsqrt_s:
388 ; CHECKIZFH:       # %bb.0:
389 ; CHECKIZFH-NEXT:    fsqrt.h fa0, fa0
390 ; CHECKIZFH-NEXT:    ret
392 ; CHECK-ZHINX-LABEL: fsqrt_s:
393 ; CHECK-ZHINX:       # %bb.0:
394 ; CHECK-ZHINX-NEXT:    fsqrt.h a0, a0
395 ; CHECK-ZHINX-NEXT:    ret
397 ; RV32I-LABEL: fsqrt_s:
398 ; RV32I:       # %bb.0:
399 ; RV32I-NEXT:    addi sp, sp, -16
400 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
401 ; RV32I-NEXT:    slli a0, a0, 16
402 ; RV32I-NEXT:    srli a0, a0, 16
403 ; RV32I-NEXT:    call __extendhfsf2
404 ; RV32I-NEXT:    call sqrtf
405 ; RV32I-NEXT:    call __truncsfhf2
406 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
407 ; RV32I-NEXT:    addi sp, sp, 16
408 ; RV32I-NEXT:    ret
410 ; RV64I-LABEL: fsqrt_s:
411 ; RV64I:       # %bb.0:
412 ; RV64I-NEXT:    addi sp, sp, -16
413 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
414 ; RV64I-NEXT:    slli a0, a0, 48
415 ; RV64I-NEXT:    srli a0, a0, 48
416 ; RV64I-NEXT:    call __extendhfsf2
417 ; RV64I-NEXT:    call sqrtf
418 ; RV64I-NEXT:    call __truncsfhf2
419 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
420 ; RV64I-NEXT:    addi sp, sp, 16
421 ; RV64I-NEXT:    ret
423 ; CHECKIZFHMIN-LABEL: fsqrt_s:
424 ; CHECKIZFHMIN:       # %bb.0:
425 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa0
426 ; CHECKIZFHMIN-NEXT:    fsqrt.s fa5, fa5
427 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
428 ; CHECKIZFHMIN-NEXT:    ret
430 ; CHECKZHINXMIN-LABEL: fsqrt_s:
431 ; CHECKZHINXMIN:       # %bb.0:
432 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
433 ; CHECKZHINXMIN-NEXT:    fsqrt.s a0, a0
434 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
435 ; CHECKZHINXMIN-NEXT:    ret
436 ; CHECK-ZHINXMIN-LABEL: fsqrt_s:
437 ; CHECK-ZHINXMIN:       # %bb.0:
438 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
439 ; CHECK-ZHINXMIN-NEXT:    fsqrt.s a0, a0
440 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
441 ; CHECK-ZHINXMIN-NEXT:    ret
442   %1 = call half @llvm.sqrt.f16(half %a)
443   ret half %1
446 declare half @llvm.copysign.f16(half, half)
448 define half @fsgnj_s(half %a, half %b) nounwind {
449 ; CHECKIZFH-LABEL: fsgnj_s:
450 ; CHECKIZFH:       # %bb.0:
451 ; CHECKIZFH-NEXT:    fsgnj.h fa0, fa0, fa1
452 ; CHECKIZFH-NEXT:    ret
454 ; CHECK-ZHINX-LABEL: fsgnj_s:
455 ; CHECK-ZHINX:       # %bb.0:
456 ; CHECK-ZHINX-NEXT:    fsgnj.h a0, a0, a1
457 ; CHECK-ZHINX-NEXT:    ret
459 ; RV32I-LABEL: fsgnj_s:
460 ; RV32I:       # %bb.0:
461 ; RV32I-NEXT:    lui a2, 1048568
462 ; RV32I-NEXT:    and a1, a1, a2
463 ; RV32I-NEXT:    slli a0, a0, 17
464 ; RV32I-NEXT:    srli a0, a0, 17
465 ; RV32I-NEXT:    or a0, a0, a1
466 ; RV32I-NEXT:    ret
468 ; RV64I-LABEL: fsgnj_s:
469 ; RV64I:       # %bb.0:
470 ; RV64I-NEXT:    lui a2, 1048568
471 ; RV64I-NEXT:    and a1, a1, a2
472 ; RV64I-NEXT:    slli a0, a0, 49
473 ; RV64I-NEXT:    srli a0, a0, 49
474 ; RV64I-NEXT:    or a0, a0, a1
475 ; RV64I-NEXT:    ret
477 ; CHECK-RV32-FSGNJ-LABEL: fsgnj_s:
478 ; CHECK-RV32-FSGNJ:       # %bb.0:
479 ; CHECK-RV32-FSGNJ-NEXT:    addi sp, sp, -16
480 ; CHECK-RV32-FSGNJ-NEXT:    fsh fa1, 12(sp)
481 ; CHECK-RV32-FSGNJ-NEXT:    fsh fa0, 8(sp)
482 ; CHECK-RV32-FSGNJ-NEXT:    lbu a0, 13(sp)
483 ; CHECK-RV32-FSGNJ-NEXT:    lbu a1, 9(sp)
484 ; CHECK-RV32-FSGNJ-NEXT:    andi a0, a0, 128
485 ; CHECK-RV32-FSGNJ-NEXT:    andi a1, a1, 127
486 ; CHECK-RV32-FSGNJ-NEXT:    or a0, a1, a0
487 ; CHECK-RV32-FSGNJ-NEXT:    sb a0, 9(sp)
488 ; CHECK-RV32-FSGNJ-NEXT:    flh fa0, 8(sp)
489 ; CHECK-RV32-FSGNJ-NEXT:    addi sp, sp, 16
490 ; CHECK-RV32-FSGNJ-NEXT:    ret
492 ; CHECK-RV64-FSGNJ-LABEL: fsgnj_s:
493 ; CHECK-RV64-FSGNJ:       # %bb.0:
494 ; CHECK-RV64-FSGNJ-NEXT:    addi sp, sp, -16
495 ; CHECK-RV64-FSGNJ-NEXT:    fsh fa1, 8(sp)
496 ; CHECK-RV64-FSGNJ-NEXT:    fsh fa0, 0(sp)
497 ; CHECK-RV64-FSGNJ-NEXT:    lbu a0, 9(sp)
498 ; CHECK-RV64-FSGNJ-NEXT:    lbu a1, 1(sp)
499 ; CHECK-RV64-FSGNJ-NEXT:    andi a0, a0, 128
500 ; CHECK-RV64-FSGNJ-NEXT:    andi a1, a1, 127
501 ; CHECK-RV64-FSGNJ-NEXT:    or a0, a1, a0
502 ; CHECK-RV64-FSGNJ-NEXT:    sb a0, 1(sp)
503 ; CHECK-RV64-FSGNJ-NEXT:    flh fa0, 0(sp)
504 ; CHECK-RV64-FSGNJ-NEXT:    addi sp, sp, 16
505 ; CHECK-RV64-FSGNJ-NEXT:    ret
506 ; CHECK-ZHINXMIN-LABEL: fsgnj_s:
507 ; CHECK-ZHINXMIN:       # %bb.0:
508 ; CHECK-ZHINXMIN-NEXT:    addi sp, sp, -16
509 ; CHECK-ZHINXMIN-NEXT:    addi a2, sp, 12
510 ; CHECK-ZHINXMIN-NEXT:    sh a1, 0(a2)
511 ; CHECK-ZHINXMIN-NEXT:    addi a1, sp, 8
512 ; CHECK-ZHINXMIN-NEXT:    sh a0, 0(a1)
513 ; CHECK-ZHINXMIN-NEXT:    lbu a0, 13(sp)
514 ; CHECK-ZHINXMIN-NEXT:    lbu a2, 9(sp)
515 ; CHECK-ZHINXMIN-NEXT:    andi a0, a0, 128
516 ; CHECK-ZHINXMIN-NEXT:    andi a2, a2, 127
517 ; CHECK-ZHINXMIN-NEXT:    or a0, a2, a0
518 ; CHECK-ZHINXMIN-NEXT:    sb a0, 9(sp)
519 ; CHECK-ZHINXMIN-NEXT:    lh a0, 0(a1)
520 ; CHECK-ZHINXMIN-NEXT:    addi sp, sp, 16
521 ; CHECK-ZHINXMIN-NEXT:    ret
522 ; CHECKFSGNJ-LABEL: fsgnj_s:
523 ; CHECKFSGNJ:       # %bb.0:
524 ; CHECKFSGNJ-NEXT:    addi sp, sp, -16
525 ; CHECKFSGNJ-NEXT:    fsh fa1, 12(sp)
526 ; CHECKFSGNJ-NEXT:    fsh fa0, 8(sp)
527 ; CHECKFSGNJ-NEXT:    lbu a0, 13(sp)
528 ; CHECKFSGNJ-NEXT:    lbu a1, 9(sp)
529 ; CHECKFSGNJ-NEXT:    andi a0, a0, 128
530 ; CHECKFSGNJ-NEXT:    andi a1, a1, 127
531 ; CHECKFSGNJ-NEXT:    or a0, a1, a0
532 ; CHECKFSGNJ-NEXT:    sb a0, 9(sp)
533 ; CHECKFSGNJ-NEXT:    flh fa0, 8(sp)
534 ; CHECKFSGNJ-NEXT:    addi sp, sp, 16
535 ; CHECKFSGNJ-NEXT:    ret
536 ; CHECK64FSGNJ-LABEL: fsgnj_s:
537 ; CHECK64FSGNJ:       # %bb.0:
538 ; CHECK64FSGNJ-NEXT:    addi sp, sp, -16
539 ; CHECK64FSGNJ-NEXT:    fsh fa1, 8(sp)
540 ; CHECK64FSGNJ-NEXT:    fsh fa0, 0(sp)
541 ; CHECK64FSGNJ-NEXT:    lbu a0, 9(sp)
542 ; CHECK64FSGNJ-NEXT:    lbu a1, 1(sp)
543 ; CHECK64FSGNJ-NEXT:    andi a0, a0, 128
544 ; CHECK64FSGNJ-NEXT:    andi a1, a1, 127
545 ; CHECK64FSGNJ-NEXT:    or a0, a1, a0
546 ; CHECK64FSGNJ-NEXT:    sb a0, 1(sp)
547 ; CHECK64FSGNJ-NEXT:    flh fa0, 0(sp)
548 ; CHECK64FSGNJ-NEXT:    addi sp, sp, 16
549 ; CHECK64FSGNJ-NEXT:    ret
550   %1 = call half @llvm.copysign.f16(half %a, half %b)
551   ret half %1
554 ; This function performs extra work to ensure that
555 ; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
556 define i32 @fneg_s(half %a, half %b) nounwind {
557 ; CHECKIZFH-LABEL: fneg_s:
558 ; CHECKIZFH:       # %bb.0:
559 ; CHECKIZFH-NEXT:    fadd.h fa5, fa0, fa0
560 ; CHECKIZFH-NEXT:    fneg.h fa4, fa5
561 ; CHECKIZFH-NEXT:    feq.h a0, fa5, fa4
562 ; CHECKIZFH-NEXT:    ret
564 ; CHECK-ZHINX-LABEL: fneg_s:
565 ; CHECK-ZHINX:       # %bb.0:
566 ; CHECK-ZHINX-NEXT:    fadd.h a0, a0, a0
567 ; CHECK-ZHINX-NEXT:    fneg.h a1, a0
568 ; CHECK-ZHINX-NEXT:    feq.h a0, a0, a1
569 ; CHECK-ZHINX-NEXT:    ret
571 ; RV32I-LABEL: fneg_s:
572 ; RV32I:       # %bb.0:
573 ; RV32I-NEXT:    addi sp, sp, -16
574 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
575 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
576 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
577 ; RV32I-NEXT:    lui a1, 16
578 ; RV32I-NEXT:    addi s1, a1, -1
579 ; RV32I-NEXT:    and a0, a0, s1
580 ; RV32I-NEXT:    call __extendhfsf2
581 ; RV32I-NEXT:    mv a1, a0
582 ; RV32I-NEXT:    call __addsf3
583 ; RV32I-NEXT:    call __truncsfhf2
584 ; RV32I-NEXT:    and a0, a0, s1
585 ; RV32I-NEXT:    call __extendhfsf2
586 ; RV32I-NEXT:    mv s0, a0
587 ; RV32I-NEXT:    lui a0, 524288
588 ; RV32I-NEXT:    xor a0, s0, a0
589 ; RV32I-NEXT:    call __truncsfhf2
590 ; RV32I-NEXT:    and a0, a0, s1
591 ; RV32I-NEXT:    call __extendhfsf2
592 ; RV32I-NEXT:    mv a1, a0
593 ; RV32I-NEXT:    mv a0, s0
594 ; RV32I-NEXT:    call __eqsf2
595 ; RV32I-NEXT:    seqz a0, a0
596 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
597 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
598 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
599 ; RV32I-NEXT:    addi sp, sp, 16
600 ; RV32I-NEXT:    ret
602 ; RV64I-LABEL: fneg_s:
603 ; RV64I:       # %bb.0:
604 ; RV64I-NEXT:    addi sp, sp, -32
605 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
606 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
607 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
608 ; RV64I-NEXT:    lui a1, 16
609 ; RV64I-NEXT:    addiw s1, a1, -1
610 ; RV64I-NEXT:    and a0, a0, s1
611 ; RV64I-NEXT:    call __extendhfsf2
612 ; RV64I-NEXT:    mv a1, a0
613 ; RV64I-NEXT:    call __addsf3
614 ; RV64I-NEXT:    call __truncsfhf2
615 ; RV64I-NEXT:    and a0, a0, s1
616 ; RV64I-NEXT:    call __extendhfsf2
617 ; RV64I-NEXT:    mv s0, a0
618 ; RV64I-NEXT:    lui a0, 524288
619 ; RV64I-NEXT:    xor a0, s0, a0
620 ; RV64I-NEXT:    call __truncsfhf2
621 ; RV64I-NEXT:    and a0, a0, s1
622 ; RV64I-NEXT:    call __extendhfsf2
623 ; RV64I-NEXT:    mv a1, a0
624 ; RV64I-NEXT:    mv a0, s0
625 ; RV64I-NEXT:    call __eqsf2
626 ; RV64I-NEXT:    seqz a0, a0
627 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
628 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
629 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
630 ; RV64I-NEXT:    addi sp, sp, 32
631 ; RV64I-NEXT:    ret
633 ; CHECKIZFHMIN-LABEL: fneg_s:
634 ; CHECKIZFHMIN:       # %bb.0:
635 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa0
636 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa5, fa5
637 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
638 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
639 ; CHECKIZFHMIN-NEXT:    fneg.s fa4, fa5
640 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa4, fa4
641 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa4
642 ; CHECKIZFHMIN-NEXT:    feq.s a0, fa5, fa4
643 ; CHECKIZFHMIN-NEXT:    ret
645 ; CHECKZHINXMIN-LABEL: fneg_s:
646 ; CHECKZHINXMIN:       # %bb.0:
647 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
648 ; CHECKZHINXMIN-NEXT:    fadd.s a0, a0, a0
649 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
650 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
651 ; CHECKZHINXMIN-NEXT:    fneg.s a1, a0
652 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a1, a1
653 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
654 ; CHECKZHINXMIN-NEXT:    feq.s a0, a0, a1
655 ; CHECKZHINXMIN-NEXT:    ret
656 ; CHECK-ZHINXMIN-LABEL: fneg_s:
657 ; CHECK-ZHINXMIN:       # %bb.0:
658 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
659 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, a0
660 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
661 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
662 ; CHECK-ZHINXMIN-NEXT:    fneg.s a1, a0
663 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
664 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
665 ; CHECK-ZHINXMIN-NEXT:    feq.s a0, a0, a1
666 ; CHECK-ZHINXMIN-NEXT:    ret
667   %1 = fadd half %a, %a
668   %2 = fneg half %1
669   %3 = fcmp oeq half %1, %2
670   %4 = zext i1 %3 to i32
671   ret i32 %4
674 ; This function performs extra work to ensure that
675 ; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
676 define half @fsgnjn_s(half %a, half %b) nounwind {
677 ; CHECKIZFH-LABEL: fsgnjn_s:
678 ; CHECKIZFH:       # %bb.0:
679 ; CHECKIZFH-NEXT:    fadd.h fa5, fa0, fa1
680 ; CHECKIZFH-NEXT:    fsgnjn.h fa0, fa0, fa5
681 ; CHECKIZFH-NEXT:    ret
683 ; CHECK-ZHINX-LABEL: fsgnjn_s:
684 ; CHECK-ZHINX:       # %bb.0:
685 ; CHECK-ZHINX-NEXT:    fadd.h a1, a0, a1
686 ; CHECK-ZHINX-NEXT:    fsgnjn.h a0, a0, a1
687 ; CHECK-ZHINX-NEXT:    ret
689 ; RV32I-LABEL: fsgnjn_s:
690 ; RV32I:       # %bb.0:
691 ; RV32I-NEXT:    addi sp, sp, -32
692 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
693 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
694 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
695 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
696 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
697 ; RV32I-NEXT:    mv s0, a1
698 ; RV32I-NEXT:    mv s1, a0
699 ; RV32I-NEXT:    lui a0, 16
700 ; RV32I-NEXT:    addi s3, a0, -1
701 ; RV32I-NEXT:    and a0, s1, s3
702 ; RV32I-NEXT:    call __extendhfsf2
703 ; RV32I-NEXT:    mv s2, a0
704 ; RV32I-NEXT:    and a0, s0, s3
705 ; RV32I-NEXT:    call __extendhfsf2
706 ; RV32I-NEXT:    mv a1, a0
707 ; RV32I-NEXT:    mv a0, s2
708 ; RV32I-NEXT:    call __addsf3
709 ; RV32I-NEXT:    call __truncsfhf2
710 ; RV32I-NEXT:    and a0, a0, s3
711 ; RV32I-NEXT:    call __extendhfsf2
712 ; RV32I-NEXT:    lui a1, 524288
713 ; RV32I-NEXT:    xor a0, a0, a1
714 ; RV32I-NEXT:    call __truncsfhf2
715 ; RV32I-NEXT:    lui a1, 1048568
716 ; RV32I-NEXT:    and a0, a0, a1
717 ; RV32I-NEXT:    slli s1, s1, 17
718 ; RV32I-NEXT:    srli s1, s1, 17
719 ; RV32I-NEXT:    or a0, s1, a0
720 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
721 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
722 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
723 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
724 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
725 ; RV32I-NEXT:    addi sp, sp, 32
726 ; RV32I-NEXT:    ret
728 ; RV64I-LABEL: fsgnjn_s:
729 ; RV64I:       # %bb.0:
730 ; RV64I-NEXT:    addi sp, sp, -48
731 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
732 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
733 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
734 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
735 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
736 ; RV64I-NEXT:    mv s0, a1
737 ; RV64I-NEXT:    mv s1, a0
738 ; RV64I-NEXT:    lui a0, 16
739 ; RV64I-NEXT:    addiw s3, a0, -1
740 ; RV64I-NEXT:    and a0, s1, s3
741 ; RV64I-NEXT:    call __extendhfsf2
742 ; RV64I-NEXT:    mv s2, a0
743 ; RV64I-NEXT:    and a0, s0, s3
744 ; RV64I-NEXT:    call __extendhfsf2
745 ; RV64I-NEXT:    mv a1, a0
746 ; RV64I-NEXT:    mv a0, s2
747 ; RV64I-NEXT:    call __addsf3
748 ; RV64I-NEXT:    call __truncsfhf2
749 ; RV64I-NEXT:    and a0, a0, s3
750 ; RV64I-NEXT:    call __extendhfsf2
751 ; RV64I-NEXT:    lui a1, 524288
752 ; RV64I-NEXT:    xor a0, a0, a1
753 ; RV64I-NEXT:    call __truncsfhf2
754 ; RV64I-NEXT:    lui a1, 1048568
755 ; RV64I-NEXT:    and a0, a0, a1
756 ; RV64I-NEXT:    slli s1, s1, 49
757 ; RV64I-NEXT:    srli s1, s1, 49
758 ; RV64I-NEXT:    or a0, s1, a0
759 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
760 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
761 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
762 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
763 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
764 ; RV64I-NEXT:    addi sp, sp, 48
765 ; RV64I-NEXT:    ret
767 ; CHECK-RV32-FSGNJ-LABEL: fsgnjn_s:
768 ; CHECK-RV32-FSGNJ:       # %bb.0:
769 ; CHECK-RV32-FSGNJ-NEXT:    addi sp, sp, -16
770 ; CHECK-RV32-FSGNJ-NEXT:    fcvt.s.h fa5, fa1
771 ; CHECK-RV32-FSGNJ-NEXT:    fcvt.s.h fa4, fa0
772 ; CHECK-RV32-FSGNJ-NEXT:    fadd.s fa5, fa4, fa5
773 ; CHECK-RV32-FSGNJ-NEXT:    fcvt.h.s fa5, fa5
774 ; CHECK-RV32-FSGNJ-NEXT:    fcvt.s.h fa5, fa5
775 ; CHECK-RV32-FSGNJ-NEXT:    fneg.s fa5, fa5
776 ; CHECK-RV32-FSGNJ-NEXT:    fcvt.h.s fa5, fa5
777 ; CHECK-RV32-FSGNJ-NEXT:    fsh fa0, 8(sp)
778 ; CHECK-RV32-FSGNJ-NEXT:    fsh fa5, 12(sp)
779 ; CHECK-RV32-FSGNJ-NEXT:    lbu a0, 9(sp)
780 ; CHECK-RV32-FSGNJ-NEXT:    lbu a1, 13(sp)
781 ; CHECK-RV32-FSGNJ-NEXT:    andi a0, a0, 127
782 ; CHECK-RV32-FSGNJ-NEXT:    andi a1, a1, 128
783 ; CHECK-RV32-FSGNJ-NEXT:    or a0, a0, a1
784 ; CHECK-RV32-FSGNJ-NEXT:    sb a0, 9(sp)
785 ; CHECK-RV32-FSGNJ-NEXT:    flh fa0, 8(sp)
786 ; CHECK-RV32-FSGNJ-NEXT:    addi sp, sp, 16
787 ; CHECK-RV32-FSGNJ-NEXT:    ret
789 ; CHECK-RV64-FSGNJ-LABEL: fsgnjn_s:
790 ; CHECK-RV64-FSGNJ:       # %bb.0:
791 ; CHECK-RV64-FSGNJ-NEXT:    addi sp, sp, -16
792 ; CHECK-RV64-FSGNJ-NEXT:    fcvt.s.h fa5, fa1
793 ; CHECK-RV64-FSGNJ-NEXT:    fcvt.s.h fa4, fa0
794 ; CHECK-RV64-FSGNJ-NEXT:    fadd.s fa5, fa4, fa5
795 ; CHECK-RV64-FSGNJ-NEXT:    fcvt.h.s fa5, fa5
796 ; CHECK-RV64-FSGNJ-NEXT:    fcvt.s.h fa5, fa5
797 ; CHECK-RV64-FSGNJ-NEXT:    fneg.s fa5, fa5
798 ; CHECK-RV64-FSGNJ-NEXT:    fcvt.h.s fa5, fa5
799 ; CHECK-RV64-FSGNJ-NEXT:    fsh fa0, 0(sp)
800 ; CHECK-RV64-FSGNJ-NEXT:    fsh fa5, 8(sp)
801 ; CHECK-RV64-FSGNJ-NEXT:    lbu a0, 1(sp)
802 ; CHECK-RV64-FSGNJ-NEXT:    lbu a1, 9(sp)
803 ; CHECK-RV64-FSGNJ-NEXT:    andi a0, a0, 127
804 ; CHECK-RV64-FSGNJ-NEXT:    andi a1, a1, 128
805 ; CHECK-RV64-FSGNJ-NEXT:    or a0, a0, a1
806 ; CHECK-RV64-FSGNJ-NEXT:    sb a0, 1(sp)
807 ; CHECK-RV64-FSGNJ-NEXT:    flh fa0, 0(sp)
808 ; CHECK-RV64-FSGNJ-NEXT:    addi sp, sp, 16
809 ; CHECK-RV64-FSGNJ-NEXT:    ret
810 ; CHECK-ZHINXMIN-LABEL: fsgnjn_s:
811 ; CHECK-ZHINXMIN:       # %bb.0:
812 ; CHECK-ZHINXMIN-NEXT:    addi sp, sp, -16
813 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
814 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a0
815 ; CHECK-ZHINXMIN-NEXT:    fadd.s a1, a2, a1
816 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
817 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
818 ; CHECK-ZHINXMIN-NEXT:    fneg.s a1, a1
819 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
820 ; CHECK-ZHINXMIN-NEXT:    addi a2, sp, 8
821 ; CHECK-ZHINXMIN-NEXT:    sh a0, 0(a2)
822 ; CHECK-ZHINXMIN-NEXT:    addi a0, sp, 12
823 ; CHECK-ZHINXMIN-NEXT:    sh a1, 0(a0)
824 ; CHECK-ZHINXMIN-NEXT:    lbu a0, 9(sp)
825 ; CHECK-ZHINXMIN-NEXT:    lbu a1, 13(sp)
826 ; CHECK-ZHINXMIN-NEXT:    andi a0, a0, 127
827 ; CHECK-ZHINXMIN-NEXT:    andi a1, a1, 128
828 ; CHECK-ZHINXMIN-NEXT:    or a0, a0, a1
829 ; CHECK-ZHINXMIN-NEXT:    sb a0, 9(sp)
830 ; CHECK-ZHINXMIN-NEXT:    lh a0, 0(a2)
831 ; CHECK-ZHINXMIN-NEXT:    addi sp, sp, 16
832 ; CHECK-ZHINXMIN-NEXT:    ret
833 ; CHECKFSGNJ-LABEL: fsgnjn_s:
834 ; CHECKFSGNJ:       # %bb.0:
835 ; CHECKFSGNJ-NEXT:    addi sp, sp, -16
836 ; CHECKFSGNJ-NEXT:    fcvt.s.h ft0, fa1
837 ; CHECKFSGNJ-NEXT:    fcvt.s.h ft1, fa0
838 ; CHECKFSGNJ-NEXT:    fadd.s ft0, ft1, ft0
839 ; CHECKFSGNJ-NEXT:    fcvt.h.s ft0, ft0
840 ; CHECKFSGNJ-NEXT:    fcvt.s.h ft0, ft0
841 ; CHECKFSGNJ-NEXT:    fneg.s ft0, ft0
842 ; CHECKFSGNJ-NEXT:    fcvt.h.s ft0, ft0
843 ; CHECKFSGNJ-NEXT:    fsh fa0, 8(sp)
844 ; CHECKFSGNJ-NEXT:    fsh ft0, 12(sp)
845 ; CHECKFSGNJ-NEXT:    lbu a0, 9(sp)
846 ; CHECKFSGNJ-NEXT:    lbu a1, 13(sp)
847 ; CHECKFSGNJ-NEXT:    andi a0, a0, 127
848 ; CHECKFSGNJ-NEXT:    andi a1, a1, 128
849 ; CHECKFSGNJ-NEXT:    or a0, a0, a1
850 ; CHECKFSGNJ-NEXT:    sb a0, 9(sp)
851 ; CHECKFSGNJ-NEXT:    flh fa0, 8(sp)
852 ; CHECKFSGNJ-NEXT:    addi sp, sp, 16
853 ; CHECKFSGNJ-NEXT:    ret
854 ; CHECK64FSGNJ-LABEL: fsgnjn_s:
855 ; CHECK64FSGNJ:       # %bb.0:
856 ; CHECK64FSGNJ-NEXT:    addi sp, sp, -16
857 ; CHECK64FSGNJ-NEXT:    fcvt.s.h ft0, fa1
858 ; CHECK64FSGNJ-NEXT:    fcvt.s.h ft1, fa0
859 ; CHECK64FSGNJ-NEXT:    fadd.s ft0, ft1, ft0
860 ; CHECK64FSGNJ-NEXT:    fcvt.h.s ft0, ft0
861 ; CHECK64FSGNJ-NEXT:    fcvt.s.h ft0, ft0
862 ; CHECK64FSGNJ-NEXT:    fneg.s ft0, ft0
863 ; CHECK64FSGNJ-NEXT:    fcvt.h.s ft0, ft0
864 ; CHECK64FSGNJ-NEXT:    fsh fa0, 0(sp)
865 ; CHECK64FSGNJ-NEXT:    fsh ft0, 8(sp)
866 ; CHECK64FSGNJ-NEXT:    lbu a0, 1(sp)
867 ; CHECK64FSGNJ-NEXT:    lbu a1, 9(sp)
868 ; CHECK64FSGNJ-NEXT:    andi a0, a0, 127
869 ; CHECK64FSGNJ-NEXT:    andi a1, a1, 128
870 ; CHECK64FSGNJ-NEXT:    or a0, a0, a1
871 ; CHECK64FSGNJ-NEXT:    sb a0, 1(sp)
872 ; CHECK64FSGNJ-NEXT:    flh fa0, 0(sp)
873 ; CHECK64FSGNJ-NEXT:    addi sp, sp, 16
874 ; CHECK64FSGNJ-NEXT:    ret
875   %1 = fadd half %a, %b
876   %2 = fneg half %1
877   %3 = call half @llvm.copysign.f16(half %a, half %2)
878   ret half %3
881 declare half @llvm.fabs.f16(half)
883 ; This function performs extra work to ensure that
884 ; DAGCombiner::visitBITCAST doesn't replace the fabs with an and.
885 define half @fabs_s(half %a, half %b) nounwind {
886 ; CHECKIZFH-LABEL: fabs_s:
887 ; CHECKIZFH:       # %bb.0:
888 ; CHECKIZFH-NEXT:    fadd.h fa5, fa0, fa1
889 ; CHECKIZFH-NEXT:    fabs.h fa4, fa5
890 ; CHECKIZFH-NEXT:    fadd.h fa0, fa4, fa5
891 ; CHECKIZFH-NEXT:    ret
893 ; CHECK-ZHINX-LABEL: fabs_s:
894 ; CHECK-ZHINX:       # %bb.0:
895 ; CHECK-ZHINX-NEXT:    fadd.h a0, a0, a1
896 ; CHECK-ZHINX-NEXT:    fabs.h a1, a0
897 ; CHECK-ZHINX-NEXT:    fadd.h a0, a1, a0
898 ; CHECK-ZHINX-NEXT:    ret
900 ; RV32I-LABEL: fabs_s:
901 ; RV32I:       # %bb.0:
902 ; RV32I-NEXT:    addi sp, sp, -16
903 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
904 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
905 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
906 ; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
907 ; RV32I-NEXT:    mv s0, a1
908 ; RV32I-NEXT:    lui a1, 16
909 ; RV32I-NEXT:    addi s2, a1, -1
910 ; RV32I-NEXT:    and a0, a0, s2
911 ; RV32I-NEXT:    call __extendhfsf2
912 ; RV32I-NEXT:    mv s1, a0
913 ; RV32I-NEXT:    and a0, s0, s2
914 ; RV32I-NEXT:    call __extendhfsf2
915 ; RV32I-NEXT:    mv a1, a0
916 ; RV32I-NEXT:    mv a0, s1
917 ; RV32I-NEXT:    call __addsf3
918 ; RV32I-NEXT:    call __truncsfhf2
919 ; RV32I-NEXT:    and a0, a0, s2
920 ; RV32I-NEXT:    call __extendhfsf2
921 ; RV32I-NEXT:    mv s0, a0
922 ; RV32I-NEXT:    slli a0, a0, 1
923 ; RV32I-NEXT:    srli a0, a0, 1
924 ; RV32I-NEXT:    call __truncsfhf2
925 ; RV32I-NEXT:    and a0, a0, s2
926 ; RV32I-NEXT:    call __extendhfsf2
927 ; RV32I-NEXT:    mv a1, s0
928 ; RV32I-NEXT:    call __addsf3
929 ; RV32I-NEXT:    call __truncsfhf2
930 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
931 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
932 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
933 ; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
934 ; RV32I-NEXT:    addi sp, sp, 16
935 ; RV32I-NEXT:    ret
937 ; RV64I-LABEL: fabs_s:
938 ; RV64I:       # %bb.0:
939 ; RV64I-NEXT:    addi sp, sp, -32
940 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
941 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
942 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
943 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
944 ; RV64I-NEXT:    mv s0, a1
945 ; RV64I-NEXT:    lui a1, 16
946 ; RV64I-NEXT:    addiw s2, a1, -1
947 ; RV64I-NEXT:    and a0, a0, s2
948 ; RV64I-NEXT:    call __extendhfsf2
949 ; RV64I-NEXT:    mv s1, a0
950 ; RV64I-NEXT:    and a0, s0, s2
951 ; RV64I-NEXT:    call __extendhfsf2
952 ; RV64I-NEXT:    mv a1, a0
953 ; RV64I-NEXT:    mv a0, s1
954 ; RV64I-NEXT:    call __addsf3
955 ; RV64I-NEXT:    call __truncsfhf2
956 ; RV64I-NEXT:    and a0, a0, s2
957 ; RV64I-NEXT:    call __extendhfsf2
958 ; RV64I-NEXT:    mv s0, a0
959 ; RV64I-NEXT:    slli a0, a0, 33
960 ; RV64I-NEXT:    srli a0, a0, 33
961 ; RV64I-NEXT:    call __truncsfhf2
962 ; RV64I-NEXT:    and a0, a0, s2
963 ; RV64I-NEXT:    call __extendhfsf2
964 ; RV64I-NEXT:    mv a1, s0
965 ; RV64I-NEXT:    call __addsf3
966 ; RV64I-NEXT:    call __truncsfhf2
967 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
968 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
969 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
970 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
971 ; RV64I-NEXT:    addi sp, sp, 32
972 ; RV64I-NEXT:    ret
974 ; CHECKIZFHMIN-LABEL: fabs_s:
975 ; CHECKIZFHMIN:       # %bb.0:
976 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
977 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa0
978 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
979 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
980 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
981 ; CHECKIZFHMIN-NEXT:    fabs.s fa4, fa5
982 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa4, fa4
983 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa4
984 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
985 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
986 ; CHECKIZFHMIN-NEXT:    ret
988 ; CHECKZHINXMIN-LABEL: fabs_s:
989 ; CHECKZHINXMIN:       # %bb.0:
990 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
991 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
992 ; CHECKZHINXMIN-NEXT:    fadd.s a0, a0, a1
993 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
994 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
995 ; CHECKZHINXMIN-NEXT:    fabs.s a1, a0
996 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a1, a1
997 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
998 ; CHECKZHINXMIN-NEXT:    fadd.s a0, a1, a0
999 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
1000 ; CHECKZHINXMIN-NEXT:    ret
1001 ; CHECK-ZHINXMIN-LABEL: fabs_s:
1002 ; CHECK-ZHINXMIN:       # %bb.0:
1003 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1004 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1005 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, a1
1006 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1007 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1008 ; CHECK-ZHINXMIN-NEXT:    fabs.s a1, a0
1009 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
1010 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1011 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a1, a0
1012 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1013 ; CHECK-ZHINXMIN-NEXT:    ret
1014   %1 = fadd half %a, %b
1015   %2 = call half @llvm.fabs.f16(half %1)
1016   %3 = fadd half %2, %1
1017   ret half %3
1020 declare half @llvm.minnum.f16(half, half)
1022 define half @fmin_s(half %a, half %b) nounwind {
1023 ; CHECKIZFH-LABEL: fmin_s:
1024 ; CHECKIZFH:       # %bb.0:
1025 ; CHECKIZFH-NEXT:    fmin.h fa0, fa0, fa1
1026 ; CHECKIZFH-NEXT:    ret
1028 ; CHECK-ZHINX-LABEL: fmin_s:
1029 ; CHECK-ZHINX:       # %bb.0:
1030 ; CHECK-ZHINX-NEXT:    fmin.h a0, a0, a1
1031 ; CHECK-ZHINX-NEXT:    ret
1033 ; RV32I-LABEL: fmin_s:
1034 ; RV32I:       # %bb.0:
1035 ; RV32I-NEXT:    addi sp, sp, -16
1036 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
1037 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
1038 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
1039 ; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
1040 ; RV32I-NEXT:    mv s0, a1
1041 ; RV32I-NEXT:    lui a1, 16
1042 ; RV32I-NEXT:    addi s2, a1, -1
1043 ; RV32I-NEXT:    and a0, a0, s2
1044 ; RV32I-NEXT:    call __extendhfsf2
1045 ; RV32I-NEXT:    mv s1, a0
1046 ; RV32I-NEXT:    and a0, s0, s2
1047 ; RV32I-NEXT:    call __extendhfsf2
1048 ; RV32I-NEXT:    mv a1, a0
1049 ; RV32I-NEXT:    mv a0, s1
1050 ; RV32I-NEXT:    call fminf
1051 ; RV32I-NEXT:    call __truncsfhf2
1052 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
1053 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
1054 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
1055 ; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
1056 ; RV32I-NEXT:    addi sp, sp, 16
1057 ; RV32I-NEXT:    ret
1059 ; RV64I-LABEL: fmin_s:
1060 ; RV64I:       # %bb.0:
1061 ; RV64I-NEXT:    addi sp, sp, -32
1062 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1063 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1064 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1065 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1066 ; RV64I-NEXT:    mv s0, a1
1067 ; RV64I-NEXT:    lui a1, 16
1068 ; RV64I-NEXT:    addiw s2, a1, -1
1069 ; RV64I-NEXT:    and a0, a0, s2
1070 ; RV64I-NEXT:    call __extendhfsf2
1071 ; RV64I-NEXT:    mv s1, a0
1072 ; RV64I-NEXT:    and a0, s0, s2
1073 ; RV64I-NEXT:    call __extendhfsf2
1074 ; RV64I-NEXT:    mv a1, a0
1075 ; RV64I-NEXT:    mv a0, s1
1076 ; RV64I-NEXT:    call fminf
1077 ; RV64I-NEXT:    call __truncsfhf2
1078 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1079 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1080 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1081 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1082 ; RV64I-NEXT:    addi sp, sp, 32
1083 ; RV64I-NEXT:    ret
1085 ; CHECKIZFHMIN-LABEL: fmin_s:
1086 ; CHECKIZFHMIN:       # %bb.0:
1087 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
1088 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa0
1089 ; CHECKIZFHMIN-NEXT:    fmin.s fa5, fa4, fa5
1090 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
1091 ; CHECKIZFHMIN-NEXT:    ret
1093 ; CHECKZHINXMIN-LABEL: fmin_s:
1094 ; CHECKZHINXMIN:       # %bb.0:
1095 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
1096 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
1097 ; CHECKZHINXMIN-NEXT:    fmin.s a0, a0, a1
1098 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
1099 ; CHECKZHINXMIN-NEXT:    ret
1100 ; CHECK-ZHINXMIN-LABEL: fmin_s:
1101 ; CHECK-ZHINXMIN:       # %bb.0:
1102 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1103 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1104 ; CHECK-ZHINXMIN-NEXT:    fmin.s a0, a0, a1
1105 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1106 ; CHECK-ZHINXMIN-NEXT:    ret
1107   %1 = call half @llvm.minnum.f16(half %a, half %b)
1108   ret half %1
1111 declare half @llvm.maxnum.f16(half, half)
1113 define half @fmax_s(half %a, half %b) nounwind {
1114 ; CHECKIZFH-LABEL: fmax_s:
1115 ; CHECKIZFH:       # %bb.0:
1116 ; CHECKIZFH-NEXT:    fmax.h fa0, fa0, fa1
1117 ; CHECKIZFH-NEXT:    ret
1119 ; CHECK-ZHINX-LABEL: fmax_s:
1120 ; CHECK-ZHINX:       # %bb.0:
1121 ; CHECK-ZHINX-NEXT:    fmax.h a0, a0, a1
1122 ; CHECK-ZHINX-NEXT:    ret
1124 ; RV32I-LABEL: fmax_s:
1125 ; RV32I:       # %bb.0:
1126 ; RV32I-NEXT:    addi sp, sp, -16
1127 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
1128 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
1129 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
1130 ; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
1131 ; RV32I-NEXT:    mv s0, a1
1132 ; RV32I-NEXT:    lui a1, 16
1133 ; RV32I-NEXT:    addi s2, a1, -1
1134 ; RV32I-NEXT:    and a0, a0, s2
1135 ; RV32I-NEXT:    call __extendhfsf2
1136 ; RV32I-NEXT:    mv s1, a0
1137 ; RV32I-NEXT:    and a0, s0, s2
1138 ; RV32I-NEXT:    call __extendhfsf2
1139 ; RV32I-NEXT:    mv a1, a0
1140 ; RV32I-NEXT:    mv a0, s1
1141 ; RV32I-NEXT:    call fmaxf
1142 ; RV32I-NEXT:    call __truncsfhf2
1143 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
1144 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
1145 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
1146 ; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
1147 ; RV32I-NEXT:    addi sp, sp, 16
1148 ; RV32I-NEXT:    ret
1150 ; RV64I-LABEL: fmax_s:
1151 ; RV64I:       # %bb.0:
1152 ; RV64I-NEXT:    addi sp, sp, -32
1153 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1154 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1155 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1156 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1157 ; RV64I-NEXT:    mv s0, a1
1158 ; RV64I-NEXT:    lui a1, 16
1159 ; RV64I-NEXT:    addiw s2, a1, -1
1160 ; RV64I-NEXT:    and a0, a0, s2
1161 ; RV64I-NEXT:    call __extendhfsf2
1162 ; RV64I-NEXT:    mv s1, a0
1163 ; RV64I-NEXT:    and a0, s0, s2
1164 ; RV64I-NEXT:    call __extendhfsf2
1165 ; RV64I-NEXT:    mv a1, a0
1166 ; RV64I-NEXT:    mv a0, s1
1167 ; RV64I-NEXT:    call fmaxf
1168 ; RV64I-NEXT:    call __truncsfhf2
1169 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1170 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1171 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1172 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1173 ; RV64I-NEXT:    addi sp, sp, 32
1174 ; RV64I-NEXT:    ret
1176 ; CHECKIZFHMIN-LABEL: fmax_s:
1177 ; CHECKIZFHMIN:       # %bb.0:
1178 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
1179 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa0
1180 ; CHECKIZFHMIN-NEXT:    fmax.s fa5, fa4, fa5
1181 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
1182 ; CHECKIZFHMIN-NEXT:    ret
1184 ; CHECKZHINXMIN-LABEL: fmax_s:
1185 ; CHECKZHINXMIN:       # %bb.0:
1186 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
1187 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
1188 ; CHECKZHINXMIN-NEXT:    fmax.s a0, a0, a1
1189 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
1190 ; CHECKZHINXMIN-NEXT:    ret
1191 ; CHECK-ZHINXMIN-LABEL: fmax_s:
1192 ; CHECK-ZHINXMIN:       # %bb.0:
1193 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1194 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1195 ; CHECK-ZHINXMIN-NEXT:    fmax.s a0, a0, a1
1196 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1197 ; CHECK-ZHINXMIN-NEXT:    ret
1198   %1 = call half @llvm.maxnum.f16(half %a, half %b)
1199   ret half %1
1202 declare half @llvm.fma.f16(half, half, half)
1204 define half @fmadd_s(half %a, half %b, half %c) nounwind {
1205 ; CHECKIZFH-LABEL: fmadd_s:
1206 ; CHECKIZFH:       # %bb.0:
1207 ; CHECKIZFH-NEXT:    fmadd.h fa0, fa0, fa1, fa2
1208 ; CHECKIZFH-NEXT:    ret
1210 ; CHECK-ZHINX-LABEL: fmadd_s:
1211 ; CHECK-ZHINX:       # %bb.0:
1212 ; CHECK-ZHINX-NEXT:    fmadd.h a0, a0, a1, a2
1213 ; CHECK-ZHINX-NEXT:    ret
1215 ; RV32I-LABEL: fmadd_s:
1216 ; RV32I:       # %bb.0:
1217 ; RV32I-NEXT:    addi sp, sp, -32
1218 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1219 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1220 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1221 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1222 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1223 ; RV32I-NEXT:    mv s0, a2
1224 ; RV32I-NEXT:    mv s1, a1
1225 ; RV32I-NEXT:    lui a1, 16
1226 ; RV32I-NEXT:    addi s3, a1, -1
1227 ; RV32I-NEXT:    and a0, a0, s3
1228 ; RV32I-NEXT:    call __extendhfsf2
1229 ; RV32I-NEXT:    mv s2, a0
1230 ; RV32I-NEXT:    and a0, s1, s3
1231 ; RV32I-NEXT:    call __extendhfsf2
1232 ; RV32I-NEXT:    mv s1, a0
1233 ; RV32I-NEXT:    and a0, s0, s3
1234 ; RV32I-NEXT:    call __extendhfsf2
1235 ; RV32I-NEXT:    mv a2, a0
1236 ; RV32I-NEXT:    mv a0, s2
1237 ; RV32I-NEXT:    mv a1, s1
1238 ; RV32I-NEXT:    call fmaf
1239 ; RV32I-NEXT:    call __truncsfhf2
1240 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1241 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1242 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1243 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1244 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1245 ; RV32I-NEXT:    addi sp, sp, 32
1246 ; RV32I-NEXT:    ret
1248 ; RV64I-LABEL: fmadd_s:
1249 ; RV64I:       # %bb.0:
1250 ; RV64I-NEXT:    addi sp, sp, -48
1251 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1252 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1253 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1254 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1255 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1256 ; RV64I-NEXT:    mv s0, a2
1257 ; RV64I-NEXT:    mv s1, a1
1258 ; RV64I-NEXT:    lui a1, 16
1259 ; RV64I-NEXT:    addiw s3, a1, -1
1260 ; RV64I-NEXT:    and a0, a0, s3
1261 ; RV64I-NEXT:    call __extendhfsf2
1262 ; RV64I-NEXT:    mv s2, a0
1263 ; RV64I-NEXT:    and a0, s1, s3
1264 ; RV64I-NEXT:    call __extendhfsf2
1265 ; RV64I-NEXT:    mv s1, a0
1266 ; RV64I-NEXT:    and a0, s0, s3
1267 ; RV64I-NEXT:    call __extendhfsf2
1268 ; RV64I-NEXT:    mv a2, a0
1269 ; RV64I-NEXT:    mv a0, s2
1270 ; RV64I-NEXT:    mv a1, s1
1271 ; RV64I-NEXT:    call fmaf
1272 ; RV64I-NEXT:    call __truncsfhf2
1273 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1274 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1275 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1276 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1277 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1278 ; RV64I-NEXT:    addi sp, sp, 48
1279 ; RV64I-NEXT:    ret
1281 ; CHECKIZFHMIN-LABEL: fmadd_s:
1282 ; CHECKIZFHMIN:       # %bb.0:
1283 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa2
1284 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa1
1285 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa0
1286 ; CHECKIZFHMIN-NEXT:    fmadd.s fa5, fa3, fa4, fa5
1287 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
1288 ; CHECKIZFHMIN-NEXT:    ret
1290 ; CHECKZHINXMIN-LABEL: fmadd_s:
1291 ; CHECKZHINXMIN:       # %bb.0:
1292 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1293 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
1294 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
1295 ; CHECKZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
1296 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
1297 ; CHECKZHINXMIN-NEXT:    ret
1298 ; CHECK-ZHINXMIN-LABEL: fmadd_s:
1299 ; CHECK-ZHINXMIN:       # %bb.0:
1300 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1301 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1302 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1303 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
1304 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1305 ; CHECK-ZHINXMIN-NEXT:    ret
1306   %1 = call half @llvm.fma.f16(half %a, half %b, half %c)
1307   ret half %1
1310 define half @fmsub_s(half %a, half %b, half %c) nounwind {
1311 ; CHECKIZFH-LABEL: fmsub_s:
1312 ; CHECKIZFH:       # %bb.0:
1313 ; CHECKIZFH-NEXT:    fmv.h.x fa5, zero
1314 ; CHECKIZFH-NEXT:    fadd.h fa5, fa2, fa5
1315 ; CHECKIZFH-NEXT:    fmsub.h fa0, fa0, fa1, fa5
1316 ; CHECKIZFH-NEXT:    ret
1318 ; CHECK-ZHINX-LABEL: fmsub_s:
1319 ; CHECK-ZHINX:       # %bb.0:
1320 ; CHECK-ZHINX-NEXT:    fadd.h a2, a2, zero
1321 ; CHECK-ZHINX-NEXT:    fmsub.h a0, a0, a1, a2
1322 ; CHECK-ZHINX-NEXT:    ret
1324 ; RV32I-LABEL: fmsub_s:
1325 ; RV32I:       # %bb.0:
1326 ; RV32I-NEXT:    addi sp, sp, -32
1327 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1328 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1329 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1330 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1331 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1332 ; RV32I-NEXT:    mv s0, a1
1333 ; RV32I-NEXT:    mv s1, a0
1334 ; RV32I-NEXT:    lui a0, 16
1335 ; RV32I-NEXT:    addi s3, a0, -1
1336 ; RV32I-NEXT:    and a0, a2, s3
1337 ; RV32I-NEXT:    call __extendhfsf2
1338 ; RV32I-NEXT:    li a1, 0
1339 ; RV32I-NEXT:    call __addsf3
1340 ; RV32I-NEXT:    call __truncsfhf2
1341 ; RV32I-NEXT:    and a0, a0, s3
1342 ; RV32I-NEXT:    call __extendhfsf2
1343 ; RV32I-NEXT:    lui a1, 524288
1344 ; RV32I-NEXT:    xor a0, a0, a1
1345 ; RV32I-NEXT:    call __truncsfhf2
1346 ; RV32I-NEXT:    mv s2, a0
1347 ; RV32I-NEXT:    and a0, s1, s3
1348 ; RV32I-NEXT:    call __extendhfsf2
1349 ; RV32I-NEXT:    mv s1, a0
1350 ; RV32I-NEXT:    and a0, s0, s3
1351 ; RV32I-NEXT:    call __extendhfsf2
1352 ; RV32I-NEXT:    mv s0, a0
1353 ; RV32I-NEXT:    and a0, s2, s3
1354 ; RV32I-NEXT:    call __extendhfsf2
1355 ; RV32I-NEXT:    mv a2, a0
1356 ; RV32I-NEXT:    mv a0, s1
1357 ; RV32I-NEXT:    mv a1, s0
1358 ; RV32I-NEXT:    call fmaf
1359 ; RV32I-NEXT:    call __truncsfhf2
1360 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1361 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1362 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1363 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1364 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1365 ; RV32I-NEXT:    addi sp, sp, 32
1366 ; RV32I-NEXT:    ret
1368 ; RV64I-LABEL: fmsub_s:
1369 ; RV64I:       # %bb.0:
1370 ; RV64I-NEXT:    addi sp, sp, -48
1371 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1372 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1373 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1374 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1375 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1376 ; RV64I-NEXT:    mv s0, a1
1377 ; RV64I-NEXT:    mv s1, a0
1378 ; RV64I-NEXT:    lui a0, 16
1379 ; RV64I-NEXT:    addiw s3, a0, -1
1380 ; RV64I-NEXT:    and a0, a2, s3
1381 ; RV64I-NEXT:    call __extendhfsf2
1382 ; RV64I-NEXT:    li a1, 0
1383 ; RV64I-NEXT:    call __addsf3
1384 ; RV64I-NEXT:    call __truncsfhf2
1385 ; RV64I-NEXT:    and a0, a0, s3
1386 ; RV64I-NEXT:    call __extendhfsf2
1387 ; RV64I-NEXT:    lui a1, 524288
1388 ; RV64I-NEXT:    xor a0, a0, a1
1389 ; RV64I-NEXT:    call __truncsfhf2
1390 ; RV64I-NEXT:    mv s2, a0
1391 ; RV64I-NEXT:    and a0, s1, s3
1392 ; RV64I-NEXT:    call __extendhfsf2
1393 ; RV64I-NEXT:    mv s1, a0
1394 ; RV64I-NEXT:    and a0, s0, s3
1395 ; RV64I-NEXT:    call __extendhfsf2
1396 ; RV64I-NEXT:    mv s0, a0
1397 ; RV64I-NEXT:    and a0, s2, s3
1398 ; RV64I-NEXT:    call __extendhfsf2
1399 ; RV64I-NEXT:    mv a2, a0
1400 ; RV64I-NEXT:    mv a0, s1
1401 ; RV64I-NEXT:    mv a1, s0
1402 ; RV64I-NEXT:    call fmaf
1403 ; RV64I-NEXT:    call __truncsfhf2
1404 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1405 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1406 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1407 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1408 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1409 ; RV64I-NEXT:    addi sp, sp, 48
1410 ; RV64I-NEXT:    ret
1412 ; CHECKIZFHMIN-LABEL: fmsub_s:
1413 ; CHECKIZFHMIN:       # %bb.0:
1414 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa2
1415 ; CHECKIZFHMIN-NEXT:    fmv.w.x fa4, zero
1416 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
1417 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
1418 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
1419 ; CHECKIZFHMIN-NEXT:    fneg.s fa5, fa5
1420 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
1421 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
1422 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa1
1423 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa0
1424 ; CHECKIZFHMIN-NEXT:    fmadd.s fa5, fa3, fa4, fa5
1425 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
1426 ; CHECKIZFHMIN-NEXT:    ret
1428 ; CHECKZHINXMIN-LABEL: fmsub_s:
1429 ; CHECKZHINXMIN:       # %bb.0:
1430 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1431 ; CHECKZHINXMIN-NEXT:    fadd.s a2, a2, zero
1432 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a2, a2
1433 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1434 ; CHECKZHINXMIN-NEXT:    fneg.s a2, a2
1435 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a2, a2
1436 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1437 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
1438 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
1439 ; CHECKZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
1440 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
1441 ; CHECKZHINXMIN-NEXT:    ret
1442 ; CHECK-ZHINXMIN-LABEL: fmsub_s:
1443 ; CHECK-ZHINXMIN:       # %bb.0:
1444 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1445 ; CHECK-ZHINXMIN-NEXT:    fadd.s a2, a2, zero
1446 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
1447 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1448 ; CHECK-ZHINXMIN-NEXT:    fneg.s a2, a2
1449 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
1450 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1451 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1452 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1453 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
1454 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1455 ; CHECK-ZHINXMIN-NEXT:    ret
1456   %c_ = fadd half 0.0, %c ; avoid negation using xor
1457   %negc = fsub half -0.0, %c_
1458   %1 = call half @llvm.fma.f16(half %a, half %b, half %negc)
1459   ret half %1
1462 define half @fnmadd_s(half %a, half %b, half %c) nounwind {
1463 ; CHECKIZFH-LABEL: fnmadd_s:
1464 ; CHECKIZFH:       # %bb.0:
1465 ; CHECKIZFH-NEXT:    fmv.h.x fa5, zero
1466 ; CHECKIZFH-NEXT:    fadd.h fa4, fa0, fa5
1467 ; CHECKIZFH-NEXT:    fadd.h fa5, fa2, fa5
1468 ; CHECKIZFH-NEXT:    fnmadd.h fa0, fa4, fa1, fa5
1469 ; CHECKIZFH-NEXT:    ret
1471 ; CHECK-ZHINX-LABEL: fnmadd_s:
1472 ; CHECK-ZHINX:       # %bb.0:
1473 ; CHECK-ZHINX-NEXT:    fadd.h a0, a0, zero
1474 ; CHECK-ZHINX-NEXT:    fadd.h a2, a2, zero
1475 ; CHECK-ZHINX-NEXT:    fnmadd.h a0, a0, a1, a2
1476 ; CHECK-ZHINX-NEXT:    ret
1478 ; RV32I-LABEL: fnmadd_s:
1479 ; RV32I:       # %bb.0:
1480 ; RV32I-NEXT:    addi sp, sp, -32
1481 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1482 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1483 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1484 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1485 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1486 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1487 ; RV32I-NEXT:    mv s1, a2
1488 ; RV32I-NEXT:    mv s0, a1
1489 ; RV32I-NEXT:    lui s3, 16
1490 ; RV32I-NEXT:    addi s3, s3, -1
1491 ; RV32I-NEXT:    and a0, a0, s3
1492 ; RV32I-NEXT:    call __extendhfsf2
1493 ; RV32I-NEXT:    li a1, 0
1494 ; RV32I-NEXT:    call __addsf3
1495 ; RV32I-NEXT:    call __truncsfhf2
1496 ; RV32I-NEXT:    mv s2, a0
1497 ; RV32I-NEXT:    and a0, s1, s3
1498 ; RV32I-NEXT:    call __extendhfsf2
1499 ; RV32I-NEXT:    li a1, 0
1500 ; RV32I-NEXT:    call __addsf3
1501 ; RV32I-NEXT:    call __truncsfhf2
1502 ; RV32I-NEXT:    mv s1, a0
1503 ; RV32I-NEXT:    and a0, s2, s3
1504 ; RV32I-NEXT:    call __extendhfsf2
1505 ; RV32I-NEXT:    lui s4, 524288
1506 ; RV32I-NEXT:    xor a0, a0, s4
1507 ; RV32I-NEXT:    call __truncsfhf2
1508 ; RV32I-NEXT:    mv s2, a0
1509 ; RV32I-NEXT:    and a0, s1, s3
1510 ; RV32I-NEXT:    call __extendhfsf2
1511 ; RV32I-NEXT:    xor a0, a0, s4
1512 ; RV32I-NEXT:    call __truncsfhf2
1513 ; RV32I-NEXT:    mv s1, a0
1514 ; RV32I-NEXT:    and a0, s0, s3
1515 ; RV32I-NEXT:    call __extendhfsf2
1516 ; RV32I-NEXT:    mv s0, a0
1517 ; RV32I-NEXT:    and a0, s2, s3
1518 ; RV32I-NEXT:    call __extendhfsf2
1519 ; RV32I-NEXT:    mv s2, a0
1520 ; RV32I-NEXT:    and a0, s1, s3
1521 ; RV32I-NEXT:    call __extendhfsf2
1522 ; RV32I-NEXT:    mv a2, a0
1523 ; RV32I-NEXT:    mv a0, s2
1524 ; RV32I-NEXT:    mv a1, s0
1525 ; RV32I-NEXT:    call fmaf
1526 ; RV32I-NEXT:    call __truncsfhf2
1527 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1528 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1529 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1530 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1531 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1532 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1533 ; RV32I-NEXT:    addi sp, sp, 32
1534 ; RV32I-NEXT:    ret
1536 ; RV64I-LABEL: fnmadd_s:
1537 ; RV64I:       # %bb.0:
1538 ; RV64I-NEXT:    addi sp, sp, -48
1539 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1540 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1541 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1542 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1543 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1544 ; RV64I-NEXT:    sd s4, 0(sp) # 8-byte Folded Spill
1545 ; RV64I-NEXT:    mv s1, a2
1546 ; RV64I-NEXT:    mv s0, a1
1547 ; RV64I-NEXT:    lui s3, 16
1548 ; RV64I-NEXT:    addiw s3, s3, -1
1549 ; RV64I-NEXT:    and a0, a0, s3
1550 ; RV64I-NEXT:    call __extendhfsf2
1551 ; RV64I-NEXT:    li a1, 0
1552 ; RV64I-NEXT:    call __addsf3
1553 ; RV64I-NEXT:    call __truncsfhf2
1554 ; RV64I-NEXT:    mv s2, a0
1555 ; RV64I-NEXT:    and a0, s1, s3
1556 ; RV64I-NEXT:    call __extendhfsf2
1557 ; RV64I-NEXT:    li a1, 0
1558 ; RV64I-NEXT:    call __addsf3
1559 ; RV64I-NEXT:    call __truncsfhf2
1560 ; RV64I-NEXT:    mv s1, a0
1561 ; RV64I-NEXT:    and a0, s2, s3
1562 ; RV64I-NEXT:    call __extendhfsf2
1563 ; RV64I-NEXT:    lui s4, 524288
1564 ; RV64I-NEXT:    xor a0, a0, s4
1565 ; RV64I-NEXT:    call __truncsfhf2
1566 ; RV64I-NEXT:    mv s2, a0
1567 ; RV64I-NEXT:    and a0, s1, s3
1568 ; RV64I-NEXT:    call __extendhfsf2
1569 ; RV64I-NEXT:    xor a0, a0, s4
1570 ; RV64I-NEXT:    call __truncsfhf2
1571 ; RV64I-NEXT:    mv s1, a0
1572 ; RV64I-NEXT:    and a0, s0, s3
1573 ; RV64I-NEXT:    call __extendhfsf2
1574 ; RV64I-NEXT:    mv s0, a0
1575 ; RV64I-NEXT:    and a0, s2, s3
1576 ; RV64I-NEXT:    call __extendhfsf2
1577 ; RV64I-NEXT:    mv s2, a0
1578 ; RV64I-NEXT:    and a0, s1, s3
1579 ; RV64I-NEXT:    call __extendhfsf2
1580 ; RV64I-NEXT:    mv a2, a0
1581 ; RV64I-NEXT:    mv a0, s2
1582 ; RV64I-NEXT:    mv a1, s0
1583 ; RV64I-NEXT:    call fmaf
1584 ; RV64I-NEXT:    call __truncsfhf2
1585 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1586 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1587 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1588 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1589 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1590 ; RV64I-NEXT:    ld s4, 0(sp) # 8-byte Folded Reload
1591 ; RV64I-NEXT:    addi sp, sp, 48
1592 ; RV64I-NEXT:    ret
1594 ; CHECKIZFHMIN-LABEL: fnmadd_s:
1595 ; CHECKIZFHMIN:       # %bb.0:
1596 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa0
1597 ; CHECKIZFHMIN-NEXT:    fmv.w.x fa4, zero
1598 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
1599 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
1600 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa2
1601 ; CHECKIZFHMIN-NEXT:    fadd.s fa4, fa3, fa4
1602 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa4, fa4
1603 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
1604 ; CHECKIZFHMIN-NEXT:    fneg.s fa5, fa5
1605 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
1606 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa4
1607 ; CHECKIZFHMIN-NEXT:    fneg.s fa4, fa4
1608 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa4, fa4
1609 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa4
1610 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
1611 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa1
1612 ; CHECKIZFHMIN-NEXT:    fmadd.s fa5, fa5, fa3, fa4
1613 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
1614 ; CHECKIZFHMIN-NEXT:    ret
1616 ; CHECKZHINXMIN-LABEL: fnmadd_s:
1617 ; CHECKZHINXMIN:       # %bb.0:
1618 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
1619 ; CHECKZHINXMIN-NEXT:    fadd.s a0, a0, zero
1620 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
1621 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1622 ; CHECKZHINXMIN-NEXT:    fadd.s a2, a2, zero
1623 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a2, a2
1624 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
1625 ; CHECKZHINXMIN-NEXT:    fneg.s a0, a0
1626 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
1627 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1628 ; CHECKZHINXMIN-NEXT:    fneg.s a2, a2
1629 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a2, a2
1630 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1631 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
1632 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
1633 ; CHECKZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
1634 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
1635 ; CHECKZHINXMIN-NEXT:    ret
1636 ; CHECK-ZHINXMIN-LABEL: fnmadd_s:
1637 ; CHECK-ZHINXMIN:       # %bb.0:
1638 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1639 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, zero
1640 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1641 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1642 ; CHECK-ZHINXMIN-NEXT:    fadd.s a2, a2, zero
1643 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
1644 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1645 ; CHECK-ZHINXMIN-NEXT:    fneg.s a0, a0
1646 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1647 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1648 ; CHECK-ZHINXMIN-NEXT:    fneg.s a2, a2
1649 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
1650 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1651 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1652 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1653 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
1654 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1655 ; CHECK-ZHINXMIN-NEXT:    ret
1656   %a_ = fadd half 0.0, %a
1657   %c_ = fadd half 0.0, %c
1658   %nega = fsub half -0.0, %a_
1659   %negc = fsub half -0.0, %c_
1660   %1 = call half @llvm.fma.f16(half %nega, half %b, half %negc)
1661   ret half %1
1664 define half @fnmadd_s_2(half %a, half %b, half %c) nounwind {
1665 ; CHECKIZFH-LABEL: fnmadd_s_2:
1666 ; CHECKIZFH:       # %bb.0:
1667 ; CHECKIZFH-NEXT:    fmv.h.x fa5, zero
1668 ; CHECKIZFH-NEXT:    fadd.h fa4, fa1, fa5
1669 ; CHECKIZFH-NEXT:    fadd.h fa5, fa2, fa5
1670 ; CHECKIZFH-NEXT:    fnmadd.h fa0, fa4, fa0, fa5
1671 ; CHECKIZFH-NEXT:    ret
1673 ; CHECK-ZHINX-LABEL: fnmadd_s_2:
1674 ; CHECK-ZHINX:       # %bb.0:
1675 ; CHECK-ZHINX-NEXT:    fadd.h a1, a1, zero
1676 ; CHECK-ZHINX-NEXT:    fadd.h a2, a2, zero
1677 ; CHECK-ZHINX-NEXT:    fnmadd.h a0, a1, a0, a2
1678 ; CHECK-ZHINX-NEXT:    ret
1680 ; RV32I-LABEL: fnmadd_s_2:
1681 ; RV32I:       # %bb.0:
1682 ; RV32I-NEXT:    addi sp, sp, -32
1683 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1684 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1685 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1686 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1687 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1688 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1689 ; RV32I-NEXT:    mv s1, a2
1690 ; RV32I-NEXT:    mv s0, a0
1691 ; RV32I-NEXT:    lui s3, 16
1692 ; RV32I-NEXT:    addi s3, s3, -1
1693 ; RV32I-NEXT:    and a0, a1, s3
1694 ; RV32I-NEXT:    call __extendhfsf2
1695 ; RV32I-NEXT:    li a1, 0
1696 ; RV32I-NEXT:    call __addsf3
1697 ; RV32I-NEXT:    call __truncsfhf2
1698 ; RV32I-NEXT:    mv s2, a0
1699 ; RV32I-NEXT:    and a0, s1, s3
1700 ; RV32I-NEXT:    call __extendhfsf2
1701 ; RV32I-NEXT:    li a1, 0
1702 ; RV32I-NEXT:    call __addsf3
1703 ; RV32I-NEXT:    call __truncsfhf2
1704 ; RV32I-NEXT:    mv s1, a0
1705 ; RV32I-NEXT:    and a0, s2, s3
1706 ; RV32I-NEXT:    call __extendhfsf2
1707 ; RV32I-NEXT:    lui s4, 524288
1708 ; RV32I-NEXT:    xor a0, a0, s4
1709 ; RV32I-NEXT:    call __truncsfhf2
1710 ; RV32I-NEXT:    mv s2, a0
1711 ; RV32I-NEXT:    and a0, s1, s3
1712 ; RV32I-NEXT:    call __extendhfsf2
1713 ; RV32I-NEXT:    xor a0, a0, s4
1714 ; RV32I-NEXT:    call __truncsfhf2
1715 ; RV32I-NEXT:    mv s1, a0
1716 ; RV32I-NEXT:    and a0, s0, s3
1717 ; RV32I-NEXT:    call __extendhfsf2
1718 ; RV32I-NEXT:    mv s0, a0
1719 ; RV32I-NEXT:    and a0, s2, s3
1720 ; RV32I-NEXT:    call __extendhfsf2
1721 ; RV32I-NEXT:    mv s2, a0
1722 ; RV32I-NEXT:    and a0, s1, s3
1723 ; RV32I-NEXT:    call __extendhfsf2
1724 ; RV32I-NEXT:    mv a2, a0
1725 ; RV32I-NEXT:    mv a0, s0
1726 ; RV32I-NEXT:    mv a1, s2
1727 ; RV32I-NEXT:    call fmaf
1728 ; RV32I-NEXT:    call __truncsfhf2
1729 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1730 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1731 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1732 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1733 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1734 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1735 ; RV32I-NEXT:    addi sp, sp, 32
1736 ; RV32I-NEXT:    ret
1738 ; RV64I-LABEL: fnmadd_s_2:
1739 ; RV64I:       # %bb.0:
1740 ; RV64I-NEXT:    addi sp, sp, -48
1741 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1742 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1743 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1744 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1745 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1746 ; RV64I-NEXT:    sd s4, 0(sp) # 8-byte Folded Spill
1747 ; RV64I-NEXT:    mv s1, a2
1748 ; RV64I-NEXT:    mv s0, a0
1749 ; RV64I-NEXT:    lui s3, 16
1750 ; RV64I-NEXT:    addiw s3, s3, -1
1751 ; RV64I-NEXT:    and a0, a1, s3
1752 ; RV64I-NEXT:    call __extendhfsf2
1753 ; RV64I-NEXT:    li a1, 0
1754 ; RV64I-NEXT:    call __addsf3
1755 ; RV64I-NEXT:    call __truncsfhf2
1756 ; RV64I-NEXT:    mv s2, a0
1757 ; RV64I-NEXT:    and a0, s1, s3
1758 ; RV64I-NEXT:    call __extendhfsf2
1759 ; RV64I-NEXT:    li a1, 0
1760 ; RV64I-NEXT:    call __addsf3
1761 ; RV64I-NEXT:    call __truncsfhf2
1762 ; RV64I-NEXT:    mv s1, a0
1763 ; RV64I-NEXT:    and a0, s2, s3
1764 ; RV64I-NEXT:    call __extendhfsf2
1765 ; RV64I-NEXT:    lui s4, 524288
1766 ; RV64I-NEXT:    xor a0, a0, s4
1767 ; RV64I-NEXT:    call __truncsfhf2
1768 ; RV64I-NEXT:    mv s2, a0
1769 ; RV64I-NEXT:    and a0, s1, s3
1770 ; RV64I-NEXT:    call __extendhfsf2
1771 ; RV64I-NEXT:    xor a0, a0, s4
1772 ; RV64I-NEXT:    call __truncsfhf2
1773 ; RV64I-NEXT:    mv s1, a0
1774 ; RV64I-NEXT:    and a0, s0, s3
1775 ; RV64I-NEXT:    call __extendhfsf2
1776 ; RV64I-NEXT:    mv s0, a0
1777 ; RV64I-NEXT:    and a0, s2, s3
1778 ; RV64I-NEXT:    call __extendhfsf2
1779 ; RV64I-NEXT:    mv s2, a0
1780 ; RV64I-NEXT:    and a0, s1, s3
1781 ; RV64I-NEXT:    call __extendhfsf2
1782 ; RV64I-NEXT:    mv a2, a0
1783 ; RV64I-NEXT:    mv a0, s0
1784 ; RV64I-NEXT:    mv a1, s2
1785 ; RV64I-NEXT:    call fmaf
1786 ; RV64I-NEXT:    call __truncsfhf2
1787 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1788 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1789 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1790 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1791 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1792 ; RV64I-NEXT:    ld s4, 0(sp) # 8-byte Folded Reload
1793 ; RV64I-NEXT:    addi sp, sp, 48
1794 ; RV64I-NEXT:    ret
1796 ; CHECKIZFHMIN-LABEL: fnmadd_s_2:
1797 ; CHECKIZFHMIN:       # %bb.0:
1798 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
1799 ; CHECKIZFHMIN-NEXT:    fmv.w.x fa4, zero
1800 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
1801 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
1802 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa2
1803 ; CHECKIZFHMIN-NEXT:    fadd.s fa4, fa3, fa4
1804 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa4, fa4
1805 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
1806 ; CHECKIZFHMIN-NEXT:    fneg.s fa5, fa5
1807 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
1808 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa4
1809 ; CHECKIZFHMIN-NEXT:    fneg.s fa4, fa4
1810 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa4, fa4
1811 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa4
1812 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
1813 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa0
1814 ; CHECKIZFHMIN-NEXT:    fmadd.s fa5, fa3, fa5, fa4
1815 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
1816 ; CHECKIZFHMIN-NEXT:    ret
1818 ; CHECKZHINXMIN-LABEL: fnmadd_s_2:
1819 ; CHECKZHINXMIN:       # %bb.0:
1820 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
1821 ; CHECKZHINXMIN-NEXT:    fadd.s a1, a1, zero
1822 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a1, a1
1823 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1824 ; CHECKZHINXMIN-NEXT:    fadd.s a2, a2, zero
1825 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a2, a2
1826 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
1827 ; CHECKZHINXMIN-NEXT:    fneg.s a1, a1
1828 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a1, a1
1829 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1830 ; CHECKZHINXMIN-NEXT:    fneg.s a2, a2
1831 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a2, a2
1832 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1833 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
1834 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
1835 ; CHECKZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
1836 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
1837 ; CHECKZHINXMIN-NEXT:    ret
1838 ; CHECK-ZHINXMIN-LABEL: fnmadd_s_2:
1839 ; CHECK-ZHINXMIN:       # %bb.0:
1840 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1841 ; CHECK-ZHINXMIN-NEXT:    fadd.s a1, a1, zero
1842 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
1843 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1844 ; CHECK-ZHINXMIN-NEXT:    fadd.s a2, a2, zero
1845 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
1846 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1847 ; CHECK-ZHINXMIN-NEXT:    fneg.s a1, a1
1848 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
1849 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1850 ; CHECK-ZHINXMIN-NEXT:    fneg.s a2, a2
1851 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
1852 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1853 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1854 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1855 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
1856 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1857 ; CHECK-ZHINXMIN-NEXT:    ret
1858   %b_ = fadd half 0.0, %b
1859   %c_ = fadd half 0.0, %c
1860   %negb = fsub half -0.0, %b_
1861   %negc = fsub half -0.0, %c_
1862   %1 = call half @llvm.fma.f16(half %a, half %negb, half %negc)
1863   ret half %1
1866 define half @fnmadd_s_3(half %a, half %b, half %c) nounwind {
1867 ; RV32IZFH-LABEL: fnmadd_s_3:
1868 ; RV32IZFH:       # %bb.0:
1869 ; RV32IZFH-NEXT:    fmadd.h ft0, fa0, fa1, fa2
1870 ; RV32IZFH-NEXT:    fneg.h fa0, ft0
1871 ; RV32IZFH-NEXT:    ret
1873 ; RV64IZFH-LABEL: fnmadd_s_3:
1874 ; RV64IZFH:       # %bb.0:
1875 ; RV64IZFH-NEXT:    fmadd.h ft0, fa0, fa1, fa2
1876 ; RV64IZFH-NEXT:    fneg.h fa0, ft0
1877 ; RV64IZFH-NEXT:    ret
1879 ; CHECKIZFH-LABEL: fnmadd_s_3:
1880 ; CHECKIZFH:       # %bb.0:
1881 ; CHECKIZFH-NEXT:    fmadd.h fa5, fa0, fa1, fa2
1882 ; CHECKIZFH-NEXT:    fneg.h fa0, fa5
1883 ; CHECKIZFH-NEXT:    ret
1885 ; CHECK-ZHINX-LABEL: fnmadd_s_3:
1886 ; CHECK-ZHINX:       # %bb.0:
1887 ; CHECK-ZHINX-NEXT:    fmadd.h a0, a0, a1, a2
1888 ; CHECK-ZHINX-NEXT:    lui a1, 1048568
1889 ; CHECK-ZHINX-NEXT:    xor a0, a0, a1
1890 ; CHECK-ZHINX-NEXT:    ret
1892 ; RV32I-LABEL: fnmadd_s_3:
1893 ; RV32I:       # %bb.0:
1894 ; RV32I-NEXT:    addi sp, sp, -32
1895 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1896 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1897 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1898 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1899 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1900 ; RV32I-NEXT:    mv s0, a2
1901 ; RV32I-NEXT:    mv s1, a1
1902 ; RV32I-NEXT:    lui a1, 16
1903 ; RV32I-NEXT:    addi s3, a1, -1
1904 ; RV32I-NEXT:    and a0, a0, s3
1905 ; RV32I-NEXT:    call __extendhfsf2
1906 ; RV32I-NEXT:    mv s2, a0
1907 ; RV32I-NEXT:    and a0, s1, s3
1908 ; RV32I-NEXT:    call __extendhfsf2
1909 ; RV32I-NEXT:    mv s1, a0
1910 ; RV32I-NEXT:    and a0, s0, s3
1911 ; RV32I-NEXT:    call __extendhfsf2
1912 ; RV32I-NEXT:    mv a2, a0
1913 ; RV32I-NEXT:    mv a0, s2
1914 ; RV32I-NEXT:    mv a1, s1
1915 ; RV32I-NEXT:    call fmaf
1916 ; RV32I-NEXT:    call __truncsfhf2
1917 ; RV32I-NEXT:    lui a1, 1048568
1918 ; RV32I-NEXT:    xor a0, a0, a1
1919 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1920 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1921 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1922 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1923 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1924 ; RV32I-NEXT:    addi sp, sp, 32
1925 ; RV32I-NEXT:    ret
1927 ; RV64I-LABEL: fnmadd_s_3:
1928 ; RV64I:       # %bb.0:
1929 ; RV64I-NEXT:    addi sp, sp, -48
1930 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1931 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1932 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1933 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1934 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1935 ; RV64I-NEXT:    mv s0, a2
1936 ; RV64I-NEXT:    mv s1, a1
1937 ; RV64I-NEXT:    lui a1, 16
1938 ; RV64I-NEXT:    addiw s3, a1, -1
1939 ; RV64I-NEXT:    and a0, a0, s3
1940 ; RV64I-NEXT:    call __extendhfsf2
1941 ; RV64I-NEXT:    mv s2, a0
1942 ; RV64I-NEXT:    and a0, s1, s3
1943 ; RV64I-NEXT:    call __extendhfsf2
1944 ; RV64I-NEXT:    mv s1, a0
1945 ; RV64I-NEXT:    and a0, s0, s3
1946 ; RV64I-NEXT:    call __extendhfsf2
1947 ; RV64I-NEXT:    mv a2, a0
1948 ; RV64I-NEXT:    mv a0, s2
1949 ; RV64I-NEXT:    mv a1, s1
1950 ; RV64I-NEXT:    call fmaf
1951 ; RV64I-NEXT:    call __truncsfhf2
1952 ; RV64I-NEXT:    lui a1, 1048568
1953 ; RV64I-NEXT:    xor a0, a0, a1
1954 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1955 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1956 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1957 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1958 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1959 ; RV64I-NEXT:    addi sp, sp, 48
1960 ; RV64I-NEXT:    ret
1962 ; CHECKIZFHMIN-LABEL: fnmadd_s_3:
1963 ; CHECKIZFHMIN:       # %bb.0:
1964 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa2
1965 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa1
1966 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa0
1967 ; CHECKIZFHMIN-NEXT:    fmadd.s fa5, fa3, fa4, fa5
1968 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
1969 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
1970 ; CHECKIZFHMIN-NEXT:    fneg.s fa5, fa5
1971 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
1972 ; CHECKIZFHMIN-NEXT:    ret
1974 ; CHECKZHINXMIN-LABEL: fnmadd_s_3:
1975 ; CHECKZHINXMIN:       # %bb.0:
1976 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
1977 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
1978 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
1979 ; CHECKZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
1980 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
1981 ; CHECKZHINXMIN-NEXT:    lui a1, 1048568
1982 ; CHECKZHINXMIN-NEXT:    xor a0, a0, a1
1983 ; CHECKZHINXMIN-NEXT:    ret
1984 ; CHECK-ZHINXMIN-LABEL: fnmadd_s_3:
1985 ; CHECK-ZHINXMIN:       # %bb.0:
1986 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
1987 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
1988 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
1989 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
1990 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
1991 ; CHECK-ZHINXMIN-NEXT:    lui a1, 1048568
1992 ; CHECK-ZHINXMIN-NEXT:    xor a0, a0, a1
1993 ; CHECK-ZHINXMIN-NEXT:    ret
1994   %1 = call half @llvm.fma.f16(half %a, half %b, half %c)
1995   %neg = fneg half %1
1996   ret half %neg
2000 define half @fnmadd_nsz(half %a, half %b, half %c) nounwind {
2001 ; RV32IZFH-LABEL: fnmadd_nsz:
2002 ; RV32IZFH:       # %bb.0:
2003 ; RV32IZFH-NEXT:    fnmadd.h fa0, fa0, fa1, fa2
2004 ; RV32IZFH-NEXT:    ret
2006 ; RV64IZFH-LABEL: fnmadd_nsz:
2007 ; RV64IZFH:       # %bb.0:
2008 ; RV64IZFH-NEXT:    fnmadd.h fa0, fa0, fa1, fa2
2009 ; RV64IZFH-NEXT:    ret
2011 ; CHECKIZFH-LABEL: fnmadd_nsz:
2012 ; CHECKIZFH:       # %bb.0:
2013 ; CHECKIZFH-NEXT:    fnmadd.h fa0, fa0, fa1, fa2
2014 ; CHECKIZFH-NEXT:    ret
2016 ; CHECK-ZHINX-LABEL: fnmadd_nsz:
2017 ; CHECK-ZHINX:       # %bb.0:
2018 ; CHECK-ZHINX-NEXT:    fmadd.h a0, a0, a1, a2
2019 ; CHECK-ZHINX-NEXT:    lui a1, 1048568
2020 ; CHECK-ZHINX-NEXT:    xor a0, a0, a1
2021 ; CHECK-ZHINX-NEXT:    ret
2023 ; RV32I-LABEL: fnmadd_nsz:
2024 ; RV32I:       # %bb.0:
2025 ; RV32I-NEXT:    addi sp, sp, -32
2026 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
2027 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
2028 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
2029 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
2030 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
2031 ; RV32I-NEXT:    mv s0, a2
2032 ; RV32I-NEXT:    mv s1, a1
2033 ; RV32I-NEXT:    lui a1, 16
2034 ; RV32I-NEXT:    addi s3, a1, -1
2035 ; RV32I-NEXT:    and a0, a0, s3
2036 ; RV32I-NEXT:    call __extendhfsf2
2037 ; RV32I-NEXT:    mv s2, a0
2038 ; RV32I-NEXT:    and a0, s1, s3
2039 ; RV32I-NEXT:    call __extendhfsf2
2040 ; RV32I-NEXT:    mv s1, a0
2041 ; RV32I-NEXT:    and a0, s0, s3
2042 ; RV32I-NEXT:    call __extendhfsf2
2043 ; RV32I-NEXT:    mv a2, a0
2044 ; RV32I-NEXT:    mv a0, s2
2045 ; RV32I-NEXT:    mv a1, s1
2046 ; RV32I-NEXT:    call fmaf
2047 ; RV32I-NEXT:    call __truncsfhf2
2048 ; RV32I-NEXT:    lui a1, 1048568
2049 ; RV32I-NEXT:    xor a0, a0, a1
2050 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
2051 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
2052 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
2053 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
2054 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
2055 ; RV32I-NEXT:    addi sp, sp, 32
2056 ; RV32I-NEXT:    ret
2058 ; RV64I-LABEL: fnmadd_nsz:
2059 ; RV64I:       # %bb.0:
2060 ; RV64I-NEXT:    addi sp, sp, -48
2061 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
2062 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
2063 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
2064 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
2065 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
2066 ; RV64I-NEXT:    mv s0, a2
2067 ; RV64I-NEXT:    mv s1, a1
2068 ; RV64I-NEXT:    lui a1, 16
2069 ; RV64I-NEXT:    addiw s3, a1, -1
2070 ; RV64I-NEXT:    and a0, a0, s3
2071 ; RV64I-NEXT:    call __extendhfsf2
2072 ; RV64I-NEXT:    mv s2, a0
2073 ; RV64I-NEXT:    and a0, s1, s3
2074 ; RV64I-NEXT:    call __extendhfsf2
2075 ; RV64I-NEXT:    mv s1, a0
2076 ; RV64I-NEXT:    and a0, s0, s3
2077 ; RV64I-NEXT:    call __extendhfsf2
2078 ; RV64I-NEXT:    mv a2, a0
2079 ; RV64I-NEXT:    mv a0, s2
2080 ; RV64I-NEXT:    mv a1, s1
2081 ; RV64I-NEXT:    call fmaf
2082 ; RV64I-NEXT:    call __truncsfhf2
2083 ; RV64I-NEXT:    lui a1, 1048568
2084 ; RV64I-NEXT:    xor a0, a0, a1
2085 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
2086 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
2087 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
2088 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
2089 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
2090 ; RV64I-NEXT:    addi sp, sp, 48
2091 ; RV64I-NEXT:    ret
2093 ; CHECKIZFHMIN-LABEL: fnmadd_nsz:
2094 ; CHECKIZFHMIN:       # %bb.0:
2095 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa2
2096 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa1
2097 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa0
2098 ; CHECKIZFHMIN-NEXT:    fmadd.s fa5, fa3, fa4, fa5
2099 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
2100 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
2101 ; CHECKIZFHMIN-NEXT:    fneg.s fa5, fa5
2102 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
2103 ; CHECKIZFHMIN-NEXT:    ret
2105 ; CHECKZHINXMIN-LABEL: fnmadd_nsz:
2106 ; CHECKZHINXMIN:       # %bb.0:
2107 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
2108 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
2109 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2110 ; CHECKZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
2111 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2112 ; CHECKZHINXMIN-NEXT:    lui a1, 1048568
2113 ; CHECKZHINXMIN-NEXT:    xor a0, a0, a1
2114 ; CHECKZHINXMIN-NEXT:    ret
2115 ; CHECK-ZHINXMIN-LABEL: fnmadd_nsz:
2116 ; CHECK-ZHINXMIN:       # %bb.0:
2117 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
2118 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
2119 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2120 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
2121 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2122 ; CHECK-ZHINXMIN-NEXT:    lui a1, 1048568
2123 ; CHECK-ZHINXMIN-NEXT:    xor a0, a0, a1
2124 ; CHECK-ZHINXMIN-NEXT:    ret
2125   %1 = call nsz half @llvm.fma.f16(half %a, half %b, half %c)
2126   %neg = fneg nsz half %1
2127   ret half %neg
2130 define half @fnmsub_s(half %a, half %b, half %c) nounwind {
2131 ; CHECKIZFH-LABEL: fnmsub_s:
2132 ; CHECKIZFH:       # %bb.0:
2133 ; CHECKIZFH-NEXT:    fmv.h.x fa5, zero
2134 ; CHECKIZFH-NEXT:    fadd.h fa5, fa0, fa5
2135 ; CHECKIZFH-NEXT:    fnmsub.h fa0, fa5, fa1, fa2
2136 ; CHECKIZFH-NEXT:    ret
2138 ; CHECK-ZHINX-LABEL: fnmsub_s:
2139 ; CHECK-ZHINX:       # %bb.0:
2140 ; CHECK-ZHINX-NEXT:    fadd.h a0, a0, zero
2141 ; CHECK-ZHINX-NEXT:    fnmsub.h a0, a0, a1, a2
2142 ; CHECK-ZHINX-NEXT:    ret
2144 ; RV32I-LABEL: fnmsub_s:
2145 ; RV32I:       # %bb.0:
2146 ; RV32I-NEXT:    addi sp, sp, -32
2147 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
2148 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
2149 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
2150 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
2151 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
2152 ; RV32I-NEXT:    mv s0, a2
2153 ; RV32I-NEXT:    mv s1, a1
2154 ; RV32I-NEXT:    lui a1, 16
2155 ; RV32I-NEXT:    addi s3, a1, -1
2156 ; RV32I-NEXT:    and a0, a0, s3
2157 ; RV32I-NEXT:    call __extendhfsf2
2158 ; RV32I-NEXT:    li a1, 0
2159 ; RV32I-NEXT:    call __addsf3
2160 ; RV32I-NEXT:    call __truncsfhf2
2161 ; RV32I-NEXT:    and a0, a0, s3
2162 ; RV32I-NEXT:    call __extendhfsf2
2163 ; RV32I-NEXT:    lui a1, 524288
2164 ; RV32I-NEXT:    xor a0, a0, a1
2165 ; RV32I-NEXT:    call __truncsfhf2
2166 ; RV32I-NEXT:    mv s2, a0
2167 ; RV32I-NEXT:    and a0, s1, s3
2168 ; RV32I-NEXT:    call __extendhfsf2
2169 ; RV32I-NEXT:    mv s1, a0
2170 ; RV32I-NEXT:    and a0, s0, s3
2171 ; RV32I-NEXT:    call __extendhfsf2
2172 ; RV32I-NEXT:    mv s0, a0
2173 ; RV32I-NEXT:    and a0, s2, s3
2174 ; RV32I-NEXT:    call __extendhfsf2
2175 ; RV32I-NEXT:    mv a1, s1
2176 ; RV32I-NEXT:    mv a2, s0
2177 ; RV32I-NEXT:    call fmaf
2178 ; RV32I-NEXT:    call __truncsfhf2
2179 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
2180 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
2181 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
2182 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
2183 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
2184 ; RV32I-NEXT:    addi sp, sp, 32
2185 ; RV32I-NEXT:    ret
2187 ; RV64I-LABEL: fnmsub_s:
2188 ; RV64I:       # %bb.0:
2189 ; RV64I-NEXT:    addi sp, sp, -48
2190 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
2191 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
2192 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
2193 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
2194 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
2195 ; RV64I-NEXT:    mv s0, a2
2196 ; RV64I-NEXT:    mv s1, a1
2197 ; RV64I-NEXT:    lui a1, 16
2198 ; RV64I-NEXT:    addiw s3, a1, -1
2199 ; RV64I-NEXT:    and a0, a0, s3
2200 ; RV64I-NEXT:    call __extendhfsf2
2201 ; RV64I-NEXT:    li a1, 0
2202 ; RV64I-NEXT:    call __addsf3
2203 ; RV64I-NEXT:    call __truncsfhf2
2204 ; RV64I-NEXT:    and a0, a0, s3
2205 ; RV64I-NEXT:    call __extendhfsf2
2206 ; RV64I-NEXT:    lui a1, 524288
2207 ; RV64I-NEXT:    xor a0, a0, a1
2208 ; RV64I-NEXT:    call __truncsfhf2
2209 ; RV64I-NEXT:    mv s2, a0
2210 ; RV64I-NEXT:    and a0, s1, s3
2211 ; RV64I-NEXT:    call __extendhfsf2
2212 ; RV64I-NEXT:    mv s1, a0
2213 ; RV64I-NEXT:    and a0, s0, s3
2214 ; RV64I-NEXT:    call __extendhfsf2
2215 ; RV64I-NEXT:    mv s0, a0
2216 ; RV64I-NEXT:    and a0, s2, s3
2217 ; RV64I-NEXT:    call __extendhfsf2
2218 ; RV64I-NEXT:    mv a1, s1
2219 ; RV64I-NEXT:    mv a2, s0
2220 ; RV64I-NEXT:    call fmaf
2221 ; RV64I-NEXT:    call __truncsfhf2
2222 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
2223 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
2224 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
2225 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
2226 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
2227 ; RV64I-NEXT:    addi sp, sp, 48
2228 ; RV64I-NEXT:    ret
2230 ; CHECKIZFHMIN-LABEL: fnmsub_s:
2231 ; CHECKIZFHMIN:       # %bb.0:
2232 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa0
2233 ; CHECKIZFHMIN-NEXT:    fmv.w.x fa4, zero
2234 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
2235 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
2236 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
2237 ; CHECKIZFHMIN-NEXT:    fneg.s fa5, fa5
2238 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
2239 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
2240 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa2
2241 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa1
2242 ; CHECKIZFHMIN-NEXT:    fmadd.s fa5, fa5, fa3, fa4
2243 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
2244 ; CHECKIZFHMIN-NEXT:    ret
2246 ; CHECKZHINXMIN-LABEL: fnmsub_s:
2247 ; CHECKZHINXMIN:       # %bb.0:
2248 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2249 ; CHECKZHINXMIN-NEXT:    fadd.s a0, a0, zero
2250 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2251 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2252 ; CHECKZHINXMIN-NEXT:    fneg.s a0, a0
2253 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2254 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2255 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
2256 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
2257 ; CHECKZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
2258 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2259 ; CHECKZHINXMIN-NEXT:    ret
2260 ; CHECK-ZHINXMIN-LABEL: fnmsub_s:
2261 ; CHECK-ZHINXMIN:       # %bb.0:
2262 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2263 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, zero
2264 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2265 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2266 ; CHECK-ZHINXMIN-NEXT:    fneg.s a0, a0
2267 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2268 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2269 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
2270 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
2271 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
2272 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2273 ; CHECK-ZHINXMIN-NEXT:    ret
2274   %a_ = fadd half 0.0, %a
2275   %nega = fsub half -0.0, %a_
2276   %1 = call half @llvm.fma.f16(half %nega, half %b, half %c)
2277   ret half %1
2280 define half @fnmsub_s_2(half %a, half %b, half %c) nounwind {
2281 ; CHECKIZFH-LABEL: fnmsub_s_2:
2282 ; CHECKIZFH:       # %bb.0:
2283 ; CHECKIZFH-NEXT:    fmv.h.x fa5, zero
2284 ; CHECKIZFH-NEXT:    fadd.h fa5, fa1, fa5
2285 ; CHECKIZFH-NEXT:    fnmsub.h fa0, fa5, fa0, fa2
2286 ; CHECKIZFH-NEXT:    ret
2288 ; CHECK-ZHINX-LABEL: fnmsub_s_2:
2289 ; CHECK-ZHINX:       # %bb.0:
2290 ; CHECK-ZHINX-NEXT:    fadd.h a1, a1, zero
2291 ; CHECK-ZHINX-NEXT:    fnmsub.h a0, a1, a0, a2
2292 ; CHECK-ZHINX-NEXT:    ret
2294 ; RV32I-LABEL: fnmsub_s_2:
2295 ; RV32I:       # %bb.0:
2296 ; RV32I-NEXT:    addi sp, sp, -32
2297 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
2298 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
2299 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
2300 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
2301 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
2302 ; RV32I-NEXT:    mv s0, a2
2303 ; RV32I-NEXT:    mv s1, a0
2304 ; RV32I-NEXT:    lui a0, 16
2305 ; RV32I-NEXT:    addi s3, a0, -1
2306 ; RV32I-NEXT:    and a0, a1, s3
2307 ; RV32I-NEXT:    call __extendhfsf2
2308 ; RV32I-NEXT:    li a1, 0
2309 ; RV32I-NEXT:    call __addsf3
2310 ; RV32I-NEXT:    call __truncsfhf2
2311 ; RV32I-NEXT:    and a0, a0, s3
2312 ; RV32I-NEXT:    call __extendhfsf2
2313 ; RV32I-NEXT:    lui a1, 524288
2314 ; RV32I-NEXT:    xor a0, a0, a1
2315 ; RV32I-NEXT:    call __truncsfhf2
2316 ; RV32I-NEXT:    mv s2, a0
2317 ; RV32I-NEXT:    and a0, s1, s3
2318 ; RV32I-NEXT:    call __extendhfsf2
2319 ; RV32I-NEXT:    mv s1, a0
2320 ; RV32I-NEXT:    and a0, s0, s3
2321 ; RV32I-NEXT:    call __extendhfsf2
2322 ; RV32I-NEXT:    mv s0, a0
2323 ; RV32I-NEXT:    and a0, s2, s3
2324 ; RV32I-NEXT:    call __extendhfsf2
2325 ; RV32I-NEXT:    mv a1, a0
2326 ; RV32I-NEXT:    mv a0, s1
2327 ; RV32I-NEXT:    mv a2, s0
2328 ; RV32I-NEXT:    call fmaf
2329 ; RV32I-NEXT:    call __truncsfhf2
2330 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
2331 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
2332 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
2333 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
2334 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
2335 ; RV32I-NEXT:    addi sp, sp, 32
2336 ; RV32I-NEXT:    ret
2338 ; RV64I-LABEL: fnmsub_s_2:
2339 ; RV64I:       # %bb.0:
2340 ; RV64I-NEXT:    addi sp, sp, -48
2341 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
2342 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
2343 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
2344 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
2345 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
2346 ; RV64I-NEXT:    mv s0, a2
2347 ; RV64I-NEXT:    mv s1, a0
2348 ; RV64I-NEXT:    lui a0, 16
2349 ; RV64I-NEXT:    addiw s3, a0, -1
2350 ; RV64I-NEXT:    and a0, a1, s3
2351 ; RV64I-NEXT:    call __extendhfsf2
2352 ; RV64I-NEXT:    li a1, 0
2353 ; RV64I-NEXT:    call __addsf3
2354 ; RV64I-NEXT:    call __truncsfhf2
2355 ; RV64I-NEXT:    and a0, a0, s3
2356 ; RV64I-NEXT:    call __extendhfsf2
2357 ; RV64I-NEXT:    lui a1, 524288
2358 ; RV64I-NEXT:    xor a0, a0, a1
2359 ; RV64I-NEXT:    call __truncsfhf2
2360 ; RV64I-NEXT:    mv s2, a0
2361 ; RV64I-NEXT:    and a0, s1, s3
2362 ; RV64I-NEXT:    call __extendhfsf2
2363 ; RV64I-NEXT:    mv s1, a0
2364 ; RV64I-NEXT:    and a0, s0, s3
2365 ; RV64I-NEXT:    call __extendhfsf2
2366 ; RV64I-NEXT:    mv s0, a0
2367 ; RV64I-NEXT:    and a0, s2, s3
2368 ; RV64I-NEXT:    call __extendhfsf2
2369 ; RV64I-NEXT:    mv a1, a0
2370 ; RV64I-NEXT:    mv a0, s1
2371 ; RV64I-NEXT:    mv a2, s0
2372 ; RV64I-NEXT:    call fmaf
2373 ; RV64I-NEXT:    call __truncsfhf2
2374 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
2375 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
2376 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
2377 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
2378 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
2379 ; RV64I-NEXT:    addi sp, sp, 48
2380 ; RV64I-NEXT:    ret
2382 ; CHECKIZFHMIN-LABEL: fnmsub_s_2:
2383 ; CHECKIZFHMIN:       # %bb.0:
2384 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
2385 ; CHECKIZFHMIN-NEXT:    fmv.w.x fa4, zero
2386 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
2387 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
2388 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
2389 ; CHECKIZFHMIN-NEXT:    fneg.s fa5, fa5
2390 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
2391 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
2392 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa2
2393 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa0
2394 ; CHECKIZFHMIN-NEXT:    fmadd.s fa5, fa3, fa5, fa4
2395 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
2396 ; CHECKIZFHMIN-NEXT:    ret
2398 ; CHECKZHINXMIN-LABEL: fnmsub_s_2:
2399 ; CHECKZHINXMIN:       # %bb.0:
2400 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
2401 ; CHECKZHINXMIN-NEXT:    fadd.s a1, a1, zero
2402 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a1, a1
2403 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
2404 ; CHECKZHINXMIN-NEXT:    fneg.s a1, a1
2405 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a1, a1
2406 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
2407 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
2408 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2409 ; CHECKZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
2410 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2411 ; CHECKZHINXMIN-NEXT:    ret
2412 ; CHECK-ZHINXMIN-LABEL: fnmsub_s_2:
2413 ; CHECK-ZHINXMIN:       # %bb.0:
2414 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
2415 ; CHECK-ZHINXMIN-NEXT:    fadd.s a1, a1, zero
2416 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
2417 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
2418 ; CHECK-ZHINXMIN-NEXT:    fneg.s a1, a1
2419 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
2420 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
2421 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
2422 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2423 ; CHECK-ZHINXMIN-NEXT:    fmadd.s a0, a0, a1, a2
2424 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2425 ; CHECK-ZHINXMIN-NEXT:    ret
2426   %b_ = fadd half 0.0, %b
2427   %negb = fsub half -0.0, %b_
2428   %1 = call half @llvm.fma.f16(half %a, half %negb, half %c)
2429   ret half %1
2432 define half @fmadd_s_contract(half %a, half %b, half %c) nounwind {
2433 ; CHECKIZFH-LABEL: fmadd_s_contract:
2434 ; CHECKIZFH:       # %bb.0:
2435 ; CHECKIZFH-NEXT:    fmadd.h fa0, fa0, fa1, fa2
2436 ; CHECKIZFH-NEXT:    ret
2438 ; CHECK-ZHINX-LABEL: fmadd_s_contract:
2439 ; CHECK-ZHINX:       # %bb.0:
2440 ; CHECK-ZHINX-NEXT:    fmadd.h a0, a0, a1, a2
2441 ; CHECK-ZHINX-NEXT:    ret
2443 ; RV32I-LABEL: fmadd_s_contract:
2444 ; RV32I:       # %bb.0:
2445 ; RV32I-NEXT:    addi sp, sp, -32
2446 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
2447 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
2448 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
2449 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
2450 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
2451 ; RV32I-NEXT:    mv s0, a2
2452 ; RV32I-NEXT:    mv s1, a1
2453 ; RV32I-NEXT:    lui a1, 16
2454 ; RV32I-NEXT:    addi s3, a1, -1
2455 ; RV32I-NEXT:    and a0, a0, s3
2456 ; RV32I-NEXT:    call __extendhfsf2
2457 ; RV32I-NEXT:    mv s2, a0
2458 ; RV32I-NEXT:    and a0, s1, s3
2459 ; RV32I-NEXT:    call __extendhfsf2
2460 ; RV32I-NEXT:    mv a1, a0
2461 ; RV32I-NEXT:    mv a0, s2
2462 ; RV32I-NEXT:    call __mulsf3
2463 ; RV32I-NEXT:    call __truncsfhf2
2464 ; RV32I-NEXT:    mv s1, a0
2465 ; RV32I-NEXT:    and a0, s0, s3
2466 ; RV32I-NEXT:    call __extendhfsf2
2467 ; RV32I-NEXT:    mv s0, a0
2468 ; RV32I-NEXT:    and a0, s1, s3
2469 ; RV32I-NEXT:    call __extendhfsf2
2470 ; RV32I-NEXT:    mv a1, s0
2471 ; RV32I-NEXT:    call __addsf3
2472 ; RV32I-NEXT:    call __truncsfhf2
2473 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
2474 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
2475 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
2476 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
2477 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
2478 ; RV32I-NEXT:    addi sp, sp, 32
2479 ; RV32I-NEXT:    ret
2481 ; RV64I-LABEL: fmadd_s_contract:
2482 ; RV64I:       # %bb.0:
2483 ; RV64I-NEXT:    addi sp, sp, -48
2484 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
2485 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
2486 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
2487 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
2488 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
2489 ; RV64I-NEXT:    mv s0, a2
2490 ; RV64I-NEXT:    mv s1, a1
2491 ; RV64I-NEXT:    lui a1, 16
2492 ; RV64I-NEXT:    addiw s3, a1, -1
2493 ; RV64I-NEXT:    and a0, a0, s3
2494 ; RV64I-NEXT:    call __extendhfsf2
2495 ; RV64I-NEXT:    mv s2, a0
2496 ; RV64I-NEXT:    and a0, s1, s3
2497 ; RV64I-NEXT:    call __extendhfsf2
2498 ; RV64I-NEXT:    mv a1, a0
2499 ; RV64I-NEXT:    mv a0, s2
2500 ; RV64I-NEXT:    call __mulsf3
2501 ; RV64I-NEXT:    call __truncsfhf2
2502 ; RV64I-NEXT:    mv s1, a0
2503 ; RV64I-NEXT:    and a0, s0, s3
2504 ; RV64I-NEXT:    call __extendhfsf2
2505 ; RV64I-NEXT:    mv s0, a0
2506 ; RV64I-NEXT:    and a0, s1, s3
2507 ; RV64I-NEXT:    call __extendhfsf2
2508 ; RV64I-NEXT:    mv a1, s0
2509 ; RV64I-NEXT:    call __addsf3
2510 ; RV64I-NEXT:    call __truncsfhf2
2511 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
2512 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
2513 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
2514 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
2515 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
2516 ; RV64I-NEXT:    addi sp, sp, 48
2517 ; RV64I-NEXT:    ret
2519 ; CHECKIZFHMIN-LABEL: fmadd_s_contract:
2520 ; CHECKIZFHMIN:       # %bb.0:
2521 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
2522 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa0
2523 ; CHECKIZFHMIN-NEXT:    fmul.s fa5, fa4, fa5
2524 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
2525 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
2526 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa2
2527 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
2528 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
2529 ; CHECKIZFHMIN-NEXT:    ret
2531 ; CHECKZHINXMIN-LABEL: fmadd_s_contract:
2532 ; CHECKZHINXMIN:       # %bb.0:
2533 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
2534 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2535 ; CHECKZHINXMIN-NEXT:    fmul.s a0, a0, a1
2536 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2537 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2538 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a2
2539 ; CHECKZHINXMIN-NEXT:    fadd.s a0, a0, a1
2540 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2541 ; CHECKZHINXMIN-NEXT:    ret
2542 ; CHECK-ZHINXMIN-LABEL: fmadd_s_contract:
2543 ; CHECK-ZHINXMIN:       # %bb.0:
2544 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
2545 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2546 ; CHECK-ZHINXMIN-NEXT:    fmul.s a0, a0, a1
2547 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2548 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2549 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a2
2550 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, a1
2551 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2552 ; CHECK-ZHINXMIN-NEXT:    ret
2553   %1 = fmul contract half %a, %b
2554   %2 = fadd contract half %1, %c
2555   ret half %2
2558 define half @fmsub_s_contract(half %a, half %b, half %c) nounwind {
2559 ; CHECKIZFH-LABEL: fmsub_s_contract:
2560 ; CHECKIZFH:       # %bb.0:
2561 ; CHECKIZFH-NEXT:    fmv.h.x fa5, zero
2562 ; CHECKIZFH-NEXT:    fadd.h fa5, fa2, fa5
2563 ; CHECKIZFH-NEXT:    fmsub.h fa0, fa0, fa1, fa5
2564 ; CHECKIZFH-NEXT:    ret
2566 ; CHECK-ZHINX-LABEL: fmsub_s_contract:
2567 ; CHECK-ZHINX:       # %bb.0:
2568 ; CHECK-ZHINX-NEXT:    fadd.h a2, a2, zero
2569 ; CHECK-ZHINX-NEXT:    fmsub.h a0, a0, a1, a2
2570 ; CHECK-ZHINX-NEXT:    ret
2572 ; RV32I-LABEL: fmsub_s_contract:
2573 ; RV32I:       # %bb.0:
2574 ; RV32I-NEXT:    addi sp, sp, -32
2575 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
2576 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
2577 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
2578 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
2579 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
2580 ; RV32I-NEXT:    mv s0, a1
2581 ; RV32I-NEXT:    mv s1, a0
2582 ; RV32I-NEXT:    lui a0, 16
2583 ; RV32I-NEXT:    addi s3, a0, -1
2584 ; RV32I-NEXT:    and a0, a2, s3
2585 ; RV32I-NEXT:    call __extendhfsf2
2586 ; RV32I-NEXT:    li a1, 0
2587 ; RV32I-NEXT:    call __addsf3
2588 ; RV32I-NEXT:    call __truncsfhf2
2589 ; RV32I-NEXT:    mv s2, a0
2590 ; RV32I-NEXT:    and a0, s1, s3
2591 ; RV32I-NEXT:    call __extendhfsf2
2592 ; RV32I-NEXT:    mv s1, a0
2593 ; RV32I-NEXT:    and a0, s0, s3
2594 ; RV32I-NEXT:    call __extendhfsf2
2595 ; RV32I-NEXT:    mv a1, a0
2596 ; RV32I-NEXT:    mv a0, s1
2597 ; RV32I-NEXT:    call __mulsf3
2598 ; RV32I-NEXT:    call __truncsfhf2
2599 ; RV32I-NEXT:    and a0, a0, s3
2600 ; RV32I-NEXT:    call __extendhfsf2
2601 ; RV32I-NEXT:    mv s0, a0
2602 ; RV32I-NEXT:    and a0, s2, s3
2603 ; RV32I-NEXT:    call __extendhfsf2
2604 ; RV32I-NEXT:    mv a1, a0
2605 ; RV32I-NEXT:    mv a0, s0
2606 ; RV32I-NEXT:    call __subsf3
2607 ; RV32I-NEXT:    call __truncsfhf2
2608 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
2609 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
2610 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
2611 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
2612 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
2613 ; RV32I-NEXT:    addi sp, sp, 32
2614 ; RV32I-NEXT:    ret
2616 ; RV64I-LABEL: fmsub_s_contract:
2617 ; RV64I:       # %bb.0:
2618 ; RV64I-NEXT:    addi sp, sp, -48
2619 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
2620 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
2621 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
2622 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
2623 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
2624 ; RV64I-NEXT:    mv s0, a1
2625 ; RV64I-NEXT:    mv s1, a0
2626 ; RV64I-NEXT:    lui a0, 16
2627 ; RV64I-NEXT:    addiw s3, a0, -1
2628 ; RV64I-NEXT:    and a0, a2, s3
2629 ; RV64I-NEXT:    call __extendhfsf2
2630 ; RV64I-NEXT:    li a1, 0
2631 ; RV64I-NEXT:    call __addsf3
2632 ; RV64I-NEXT:    call __truncsfhf2
2633 ; RV64I-NEXT:    mv s2, a0
2634 ; RV64I-NEXT:    and a0, s1, s3
2635 ; RV64I-NEXT:    call __extendhfsf2
2636 ; RV64I-NEXT:    mv s1, a0
2637 ; RV64I-NEXT:    and a0, s0, s3
2638 ; RV64I-NEXT:    call __extendhfsf2
2639 ; RV64I-NEXT:    mv a1, a0
2640 ; RV64I-NEXT:    mv a0, s1
2641 ; RV64I-NEXT:    call __mulsf3
2642 ; RV64I-NEXT:    call __truncsfhf2
2643 ; RV64I-NEXT:    and a0, a0, s3
2644 ; RV64I-NEXT:    call __extendhfsf2
2645 ; RV64I-NEXT:    mv s0, a0
2646 ; RV64I-NEXT:    and a0, s2, s3
2647 ; RV64I-NEXT:    call __extendhfsf2
2648 ; RV64I-NEXT:    mv a1, a0
2649 ; RV64I-NEXT:    mv a0, s0
2650 ; RV64I-NEXT:    call __subsf3
2651 ; RV64I-NEXT:    call __truncsfhf2
2652 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
2653 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
2654 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
2655 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
2656 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
2657 ; RV64I-NEXT:    addi sp, sp, 48
2658 ; RV64I-NEXT:    ret
2660 ; CHECKIZFHMIN-LABEL: fmsub_s_contract:
2661 ; CHECKIZFHMIN:       # %bb.0:
2662 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa2
2663 ; CHECKIZFHMIN-NEXT:    fmv.w.x fa4, zero
2664 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
2665 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
2666 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa1
2667 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa0
2668 ; CHECKIZFHMIN-NEXT:    fmul.s fa4, fa3, fa4
2669 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa4, fa4
2670 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
2671 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa4
2672 ; CHECKIZFHMIN-NEXT:    fsub.s fa5, fa4, fa5
2673 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
2674 ; CHECKIZFHMIN-NEXT:    ret
2676 ; CHECKZHINXMIN-LABEL: fmsub_s_contract:
2677 ; CHECKZHINXMIN:       # %bb.0:
2678 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
2679 ; CHECKZHINXMIN-NEXT:    fadd.s a2, a2, zero
2680 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a2, a2
2681 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
2682 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2683 ; CHECKZHINXMIN-NEXT:    fmul.s a0, a0, a1
2684 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2685 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a2
2686 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2687 ; CHECKZHINXMIN-NEXT:    fsub.s a0, a0, a1
2688 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2689 ; CHECKZHINXMIN-NEXT:    ret
2690 ; CHECK-ZHINXMIN-LABEL: fmsub_s_contract:
2691 ; CHECK-ZHINXMIN:       # %bb.0:
2692 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
2693 ; CHECK-ZHINXMIN-NEXT:    fadd.s a2, a2, zero
2694 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
2695 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
2696 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2697 ; CHECK-ZHINXMIN-NEXT:    fmul.s a0, a0, a1
2698 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2699 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a2
2700 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2701 ; CHECK-ZHINXMIN-NEXT:    fsub.s a0, a0, a1
2702 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2703 ; CHECK-ZHINXMIN-NEXT:    ret
2704   %c_ = fadd half 0.0, %c ; avoid negation using xor
2705   %1 = fmul contract half %a, %b
2706   %2 = fsub contract half %1, %c_
2707   ret half %2
2710 define half @fnmadd_s_contract(half %a, half %b, half %c) nounwind {
2711 ; CHECKIZFH-LABEL: fnmadd_s_contract:
2712 ; CHECKIZFH:       # %bb.0:
2713 ; CHECKIZFH-NEXT:    fmv.h.x fa5, zero
2714 ; CHECKIZFH-NEXT:    fadd.h fa4, fa0, fa5
2715 ; CHECKIZFH-NEXT:    fadd.h fa3, fa1, fa5
2716 ; CHECKIZFH-NEXT:    fadd.h fa5, fa2, fa5
2717 ; CHECKIZFH-NEXT:    fnmadd.h fa0, fa4, fa3, fa5
2718 ; CHECKIZFH-NEXT:    ret
2720 ; CHECK-ZHINX-LABEL: fnmadd_s_contract:
2721 ; CHECK-ZHINX:       # %bb.0:
2722 ; CHECK-ZHINX-NEXT:    fadd.h a0, a0, zero
2723 ; CHECK-ZHINX-NEXT:    fadd.h a1, a1, zero
2724 ; CHECK-ZHINX-NEXT:    fadd.h a2, a2, zero
2725 ; CHECK-ZHINX-NEXT:    fnmadd.h a0, a0, a1, a2
2726 ; CHECK-ZHINX-NEXT:    ret
2728 ; RV32I-LABEL: fnmadd_s_contract:
2729 ; RV32I:       # %bb.0:
2730 ; RV32I-NEXT:    addi sp, sp, -32
2731 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
2732 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
2733 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
2734 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
2735 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
2736 ; RV32I-NEXT:    mv s0, a2
2737 ; RV32I-NEXT:    mv s1, a1
2738 ; RV32I-NEXT:    lui s3, 16
2739 ; RV32I-NEXT:    addi s3, s3, -1
2740 ; RV32I-NEXT:    and a0, a0, s3
2741 ; RV32I-NEXT:    call __extendhfsf2
2742 ; RV32I-NEXT:    li a1, 0
2743 ; RV32I-NEXT:    call __addsf3
2744 ; RV32I-NEXT:    call __truncsfhf2
2745 ; RV32I-NEXT:    mv s2, a0
2746 ; RV32I-NEXT:    and a0, s1, s3
2747 ; RV32I-NEXT:    call __extendhfsf2
2748 ; RV32I-NEXT:    li a1, 0
2749 ; RV32I-NEXT:    call __addsf3
2750 ; RV32I-NEXT:    call __truncsfhf2
2751 ; RV32I-NEXT:    mv s1, a0
2752 ; RV32I-NEXT:    and a0, s0, s3
2753 ; RV32I-NEXT:    call __extendhfsf2
2754 ; RV32I-NEXT:    li a1, 0
2755 ; RV32I-NEXT:    call __addsf3
2756 ; RV32I-NEXT:    call __truncsfhf2
2757 ; RV32I-NEXT:    mv s0, a0
2758 ; RV32I-NEXT:    and a0, s2, s3
2759 ; RV32I-NEXT:    call __extendhfsf2
2760 ; RV32I-NEXT:    mv s2, a0
2761 ; RV32I-NEXT:    and a0, s1, s3
2762 ; RV32I-NEXT:    call __extendhfsf2
2763 ; RV32I-NEXT:    mv a1, a0
2764 ; RV32I-NEXT:    mv a0, s2
2765 ; RV32I-NEXT:    call __mulsf3
2766 ; RV32I-NEXT:    call __truncsfhf2
2767 ; RV32I-NEXT:    and a0, a0, s3
2768 ; RV32I-NEXT:    call __extendhfsf2
2769 ; RV32I-NEXT:    lui a1, 524288
2770 ; RV32I-NEXT:    xor a0, a0, a1
2771 ; RV32I-NEXT:    call __truncsfhf2
2772 ; RV32I-NEXT:    mv s1, a0
2773 ; RV32I-NEXT:    and a0, s0, s3
2774 ; RV32I-NEXT:    call __extendhfsf2
2775 ; RV32I-NEXT:    mv s0, a0
2776 ; RV32I-NEXT:    and a0, s1, s3
2777 ; RV32I-NEXT:    call __extendhfsf2
2778 ; RV32I-NEXT:    mv a1, s0
2779 ; RV32I-NEXT:    call __subsf3
2780 ; RV32I-NEXT:    call __truncsfhf2
2781 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
2782 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
2783 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
2784 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
2785 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
2786 ; RV32I-NEXT:    addi sp, sp, 32
2787 ; RV32I-NEXT:    ret
2789 ; RV64I-LABEL: fnmadd_s_contract:
2790 ; RV64I:       # %bb.0:
2791 ; RV64I-NEXT:    addi sp, sp, -48
2792 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
2793 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
2794 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
2795 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
2796 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
2797 ; RV64I-NEXT:    mv s0, a2
2798 ; RV64I-NEXT:    mv s1, a1
2799 ; RV64I-NEXT:    lui s3, 16
2800 ; RV64I-NEXT:    addiw s3, s3, -1
2801 ; RV64I-NEXT:    and a0, a0, s3
2802 ; RV64I-NEXT:    call __extendhfsf2
2803 ; RV64I-NEXT:    li a1, 0
2804 ; RV64I-NEXT:    call __addsf3
2805 ; RV64I-NEXT:    call __truncsfhf2
2806 ; RV64I-NEXT:    mv s2, a0
2807 ; RV64I-NEXT:    and a0, s1, s3
2808 ; RV64I-NEXT:    call __extendhfsf2
2809 ; RV64I-NEXT:    li a1, 0
2810 ; RV64I-NEXT:    call __addsf3
2811 ; RV64I-NEXT:    call __truncsfhf2
2812 ; RV64I-NEXT:    mv s1, a0
2813 ; RV64I-NEXT:    and a0, s0, s3
2814 ; RV64I-NEXT:    call __extendhfsf2
2815 ; RV64I-NEXT:    li a1, 0
2816 ; RV64I-NEXT:    call __addsf3
2817 ; RV64I-NEXT:    call __truncsfhf2
2818 ; RV64I-NEXT:    mv s0, a0
2819 ; RV64I-NEXT:    and a0, s2, s3
2820 ; RV64I-NEXT:    call __extendhfsf2
2821 ; RV64I-NEXT:    mv s2, a0
2822 ; RV64I-NEXT:    and a0, s1, s3
2823 ; RV64I-NEXT:    call __extendhfsf2
2824 ; RV64I-NEXT:    mv a1, a0
2825 ; RV64I-NEXT:    mv a0, s2
2826 ; RV64I-NEXT:    call __mulsf3
2827 ; RV64I-NEXT:    call __truncsfhf2
2828 ; RV64I-NEXT:    and a0, a0, s3
2829 ; RV64I-NEXT:    call __extendhfsf2
2830 ; RV64I-NEXT:    lui a1, 524288
2831 ; RV64I-NEXT:    xor a0, a0, a1
2832 ; RV64I-NEXT:    call __truncsfhf2
2833 ; RV64I-NEXT:    mv s1, a0
2834 ; RV64I-NEXT:    and a0, s0, s3
2835 ; RV64I-NEXT:    call __extendhfsf2
2836 ; RV64I-NEXT:    mv s0, a0
2837 ; RV64I-NEXT:    and a0, s1, s3
2838 ; RV64I-NEXT:    call __extendhfsf2
2839 ; RV64I-NEXT:    mv a1, s0
2840 ; RV64I-NEXT:    call __subsf3
2841 ; RV64I-NEXT:    call __truncsfhf2
2842 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
2843 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
2844 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
2845 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
2846 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
2847 ; RV64I-NEXT:    addi sp, sp, 48
2848 ; RV64I-NEXT:    ret
2850 ; CHECKIZFHMIN-LABEL: fnmadd_s_contract:
2851 ; CHECKIZFHMIN:       # %bb.0:
2852 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa0
2853 ; CHECKIZFHMIN-NEXT:    fmv.w.x fa4, zero
2854 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
2855 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
2856 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa1
2857 ; CHECKIZFHMIN-NEXT:    fadd.s fa3, fa3, fa4
2858 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa3, fa3
2859 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa2, fa2
2860 ; CHECKIZFHMIN-NEXT:    fadd.s fa4, fa2, fa4
2861 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa4, fa4
2862 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa3
2863 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
2864 ; CHECKIZFHMIN-NEXT:    fmul.s fa5, fa5, fa3
2865 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
2866 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
2867 ; CHECKIZFHMIN-NEXT:    fneg.s fa5, fa5
2868 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
2869 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
2870 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa4
2871 ; CHECKIZFHMIN-NEXT:    fsub.s fa5, fa5, fa4
2872 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
2873 ; CHECKIZFHMIN-NEXT:    ret
2875 ; CHECKZHINXMIN-LABEL: fnmadd_s_contract:
2876 ; CHECKZHINXMIN:       # %bb.0:
2877 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2878 ; CHECKZHINXMIN-NEXT:    fadd.s a0, a0, zero
2879 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2880 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
2881 ; CHECKZHINXMIN-NEXT:    fadd.s a1, a1, zero
2882 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a1, a1
2883 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a2, a2
2884 ; CHECKZHINXMIN-NEXT:    fadd.s a2, a2, zero
2885 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a2, a2
2886 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
2887 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2888 ; CHECKZHINXMIN-NEXT:    fmul.s a0, a0, a1
2889 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2890 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2891 ; CHECKZHINXMIN-NEXT:    fneg.s a0, a0
2892 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2893 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
2894 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a2
2895 ; CHECKZHINXMIN-NEXT:    fsub.s a0, a0, a1
2896 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
2897 ; CHECKZHINXMIN-NEXT:    ret
2898 ; CHECK-ZHINXMIN-LABEL: fnmadd_s_contract:
2899 ; CHECK-ZHINXMIN:       # %bb.0:
2900 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2901 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, zero
2902 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2903 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
2904 ; CHECK-ZHINXMIN-NEXT:    fadd.s a1, a1, zero
2905 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
2906 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a2, a2
2907 ; CHECK-ZHINXMIN-NEXT:    fadd.s a2, a2, zero
2908 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a2, a2
2909 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
2910 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2911 ; CHECK-ZHINXMIN-NEXT:    fmul.s a0, a0, a1
2912 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2913 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2914 ; CHECK-ZHINXMIN-NEXT:    fneg.s a0, a0
2915 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2916 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
2917 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a2
2918 ; CHECK-ZHINXMIN-NEXT:    fsub.s a0, a0, a1
2919 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
2920 ; CHECK-ZHINXMIN-NEXT:    ret
2921   %a_ = fadd half 0.0, %a ; avoid negation using xor
2922   %b_ = fadd half 0.0, %b ; avoid negation using xor
2923   %c_ = fadd half 0.0, %c ; avoid negation using xor
2924   %1 = fmul contract half %a_, %b_
2925   %2 = fneg half %1
2926   %3 = fsub contract half %2, %c_
2927   ret half %3
2930 define half @fnmsub_s_contract(half %a, half %b, half %c) nounwind {
2931 ; CHECKIZFH-LABEL: fnmsub_s_contract:
2932 ; CHECKIZFH:       # %bb.0:
2933 ; CHECKIZFH-NEXT:    fmv.h.x fa5, zero
2934 ; CHECKIZFH-NEXT:    fadd.h fa4, fa0, fa5
2935 ; CHECKIZFH-NEXT:    fadd.h fa5, fa1, fa5
2936 ; CHECKIZFH-NEXT:    fnmsub.h fa0, fa4, fa5, fa2
2937 ; CHECKIZFH-NEXT:    ret
2939 ; CHECK-ZHINX-LABEL: fnmsub_s_contract:
2940 ; CHECK-ZHINX:       # %bb.0:
2941 ; CHECK-ZHINX-NEXT:    fadd.h a0, a0, zero
2942 ; CHECK-ZHINX-NEXT:    fadd.h a1, a1, zero
2943 ; CHECK-ZHINX-NEXT:    fnmsub.h a0, a0, a1, a2
2944 ; CHECK-ZHINX-NEXT:    ret
2946 ; RV32I-LABEL: fnmsub_s_contract:
2947 ; RV32I:       # %bb.0:
2948 ; RV32I-NEXT:    addi sp, sp, -32
2949 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
2950 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
2951 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
2952 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
2953 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
2954 ; RV32I-NEXT:    mv s0, a2
2955 ; RV32I-NEXT:    mv s1, a1
2956 ; RV32I-NEXT:    lui s3, 16
2957 ; RV32I-NEXT:    addi s3, s3, -1
2958 ; RV32I-NEXT:    and a0, a0, s3
2959 ; RV32I-NEXT:    call __extendhfsf2
2960 ; RV32I-NEXT:    li a1, 0
2961 ; RV32I-NEXT:    call __addsf3
2962 ; RV32I-NEXT:    call __truncsfhf2
2963 ; RV32I-NEXT:    mv s2, a0
2964 ; RV32I-NEXT:    and a0, s1, s3
2965 ; RV32I-NEXT:    call __extendhfsf2
2966 ; RV32I-NEXT:    li a1, 0
2967 ; RV32I-NEXT:    call __addsf3
2968 ; RV32I-NEXT:    call __truncsfhf2
2969 ; RV32I-NEXT:    mv s1, a0
2970 ; RV32I-NEXT:    and a0, s2, s3
2971 ; RV32I-NEXT:    call __extendhfsf2
2972 ; RV32I-NEXT:    mv s2, a0
2973 ; RV32I-NEXT:    and a0, s1, s3
2974 ; RV32I-NEXT:    call __extendhfsf2
2975 ; RV32I-NEXT:    mv a1, a0
2976 ; RV32I-NEXT:    mv a0, s2
2977 ; RV32I-NEXT:    call __mulsf3
2978 ; RV32I-NEXT:    call __truncsfhf2
2979 ; RV32I-NEXT:    mv s1, a0
2980 ; RV32I-NEXT:    and a0, s0, s3
2981 ; RV32I-NEXT:    call __extendhfsf2
2982 ; RV32I-NEXT:    mv s0, a0
2983 ; RV32I-NEXT:    and a0, s1, s3
2984 ; RV32I-NEXT:    call __extendhfsf2
2985 ; RV32I-NEXT:    mv a1, a0
2986 ; RV32I-NEXT:    mv a0, s0
2987 ; RV32I-NEXT:    call __subsf3
2988 ; RV32I-NEXT:    call __truncsfhf2
2989 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
2990 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
2991 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
2992 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
2993 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
2994 ; RV32I-NEXT:    addi sp, sp, 32
2995 ; RV32I-NEXT:    ret
2997 ; RV64I-LABEL: fnmsub_s_contract:
2998 ; RV64I:       # %bb.0:
2999 ; RV64I-NEXT:    addi sp, sp, -48
3000 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
3001 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
3002 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
3003 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
3004 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
3005 ; RV64I-NEXT:    mv s0, a2
3006 ; RV64I-NEXT:    mv s1, a1
3007 ; RV64I-NEXT:    lui s3, 16
3008 ; RV64I-NEXT:    addiw s3, s3, -1
3009 ; RV64I-NEXT:    and a0, a0, s3
3010 ; RV64I-NEXT:    call __extendhfsf2
3011 ; RV64I-NEXT:    li a1, 0
3012 ; RV64I-NEXT:    call __addsf3
3013 ; RV64I-NEXT:    call __truncsfhf2
3014 ; RV64I-NEXT:    mv s2, a0
3015 ; RV64I-NEXT:    and a0, s1, s3
3016 ; RV64I-NEXT:    call __extendhfsf2
3017 ; RV64I-NEXT:    li a1, 0
3018 ; RV64I-NEXT:    call __addsf3
3019 ; RV64I-NEXT:    call __truncsfhf2
3020 ; RV64I-NEXT:    mv s1, a0
3021 ; RV64I-NEXT:    and a0, s2, s3
3022 ; RV64I-NEXT:    call __extendhfsf2
3023 ; RV64I-NEXT:    mv s2, a0
3024 ; RV64I-NEXT:    and a0, s1, s3
3025 ; RV64I-NEXT:    call __extendhfsf2
3026 ; RV64I-NEXT:    mv a1, a0
3027 ; RV64I-NEXT:    mv a0, s2
3028 ; RV64I-NEXT:    call __mulsf3
3029 ; RV64I-NEXT:    call __truncsfhf2
3030 ; RV64I-NEXT:    mv s1, a0
3031 ; RV64I-NEXT:    and a0, s0, s3
3032 ; RV64I-NEXT:    call __extendhfsf2
3033 ; RV64I-NEXT:    mv s0, a0
3034 ; RV64I-NEXT:    and a0, s1, s3
3035 ; RV64I-NEXT:    call __extendhfsf2
3036 ; RV64I-NEXT:    mv a1, a0
3037 ; RV64I-NEXT:    mv a0, s0
3038 ; RV64I-NEXT:    call __subsf3
3039 ; RV64I-NEXT:    call __truncsfhf2
3040 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
3041 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
3042 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
3043 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
3044 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
3045 ; RV64I-NEXT:    addi sp, sp, 48
3046 ; RV64I-NEXT:    ret
3048 ; CHECKIZFHMIN-LABEL: fnmsub_s_contract:
3049 ; CHECKIZFHMIN:       # %bb.0:
3050 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa0
3051 ; CHECKIZFHMIN-NEXT:    fmv.w.x fa4, zero
3052 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
3053 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
3054 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa3, fa1
3055 ; CHECKIZFHMIN-NEXT:    fadd.s fa4, fa3, fa4
3056 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa4, fa4
3057 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa4
3058 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
3059 ; CHECKIZFHMIN-NEXT:    fmul.s fa5, fa5, fa4
3060 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
3061 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
3062 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa2
3063 ; CHECKIZFHMIN-NEXT:    fsub.s fa5, fa4, fa5
3064 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
3065 ; CHECKIZFHMIN-NEXT:    ret
3067 ; CHECKZHINXMIN-LABEL: fnmsub_s_contract:
3068 ; CHECKZHINXMIN:       # %bb.0:
3069 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
3070 ; CHECKZHINXMIN-NEXT:    fadd.s a0, a0, zero
3071 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
3072 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
3073 ; CHECKZHINXMIN-NEXT:    fadd.s a1, a1, zero
3074 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a1, a1
3075 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a1
3076 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
3077 ; CHECKZHINXMIN-NEXT:    fmul.s a0, a0, a1
3078 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
3079 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a0, a0
3080 ; CHECKZHINXMIN-NEXT:    fcvt.s.h a1, a2
3081 ; CHECKZHINXMIN-NEXT:    fsub.s a0, a1, a0
3082 ; CHECKZHINXMIN-NEXT:    fcvt.h.s a0, a0
3083 ; CHECKZHINXMIN-NEXT:    ret
3084 ; CHECK-ZHINXMIN-LABEL: fnmsub_s_contract:
3085 ; CHECK-ZHINXMIN:       # %bb.0:
3086 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
3087 ; CHECK-ZHINXMIN-NEXT:    fadd.s a0, a0, zero
3088 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
3089 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
3090 ; CHECK-ZHINXMIN-NEXT:    fadd.s a1, a1, zero
3091 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a1, a1
3092 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a1
3093 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
3094 ; CHECK-ZHINXMIN-NEXT:    fmul.s a0, a0, a1
3095 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
3096 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a0, a0
3097 ; CHECK-ZHINXMIN-NEXT:    fcvt.s.h a1, a2
3098 ; CHECK-ZHINXMIN-NEXT:    fsub.s a0, a1, a0
3099 ; CHECK-ZHINXMIN-NEXT:    fcvt.h.s a0, a0
3100 ; CHECK-ZHINXMIN-NEXT:    ret
3101   %a_ = fadd half 0.0, %a ; avoid negation using xor
3102   %b_ = fadd half 0.0, %b ; avoid negation using xor
3103   %1 = fmul contract half %a_, %b_
3104   %2 = fsub contract half %c, %1
3105   ret half %2