Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / half-mem.ll
blob5b6a94a83f94bf3ce383586d800f4f162c5024e4
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-prefixes=CHECKIZFH,RV32IZFH %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \
5 ; RUN:   -target-abi lp64f < %s | FileCheck -check-prefixes=CHECKIZFH,RV64IZFH %s
6 ; RUN: llc -mtriple=riscv32 -mattr=+zhinx -verify-machineinstrs \
7 ; RUN:   -target-abi ilp32 < %s | FileCheck -check-prefixes=CHECKIZHINX,RV32IZHINX %s
8 ; RUN: llc -mtriple=riscv64 -mattr=+zhinx -verify-machineinstrs \
9 ; RUN:   -target-abi lp64 < %s | FileCheck -check-prefixes=CHECKIZHINX,RV64IZHINX %s
10 ; RUN: llc -mtriple=riscv32 -mattr=+zfhmin -verify-machineinstrs \
11 ; RUN:   -target-abi ilp32f < %s | FileCheck -check-prefixes=CHECKIZFHMIN,RV32IZFHMIN %s
12 ; RUN: llc -mtriple=riscv64 -mattr=+zfhmin -verify-machineinstrs \
13 ; RUN:   -target-abi lp64f < %s | FileCheck -check-prefixes=CHECKIZFHMIN,RV64IZFHMIN %s
14 ; RUN: llc -mtriple=riscv32 -mattr=+zhinxmin -verify-machineinstrs \
15 ; RUN:   -target-abi ilp32 < %s | FileCheck -check-prefixes=CHECKIZHINXMIN,RV32IZHINXMIN %s
16 ; RUN: llc -mtriple=riscv64 -mattr=+zhinxmin -verify-machineinstrs \
17 ; RUN:   -target-abi lp64 < %s | FileCheck -check-prefixes=CHECKIZHINXMIN,RV64IZHINXMIN %s
19 define half @flh(ptr %a) nounwind {
20 ; CHECKIZFH-LABEL: flh:
21 ; CHECKIZFH:       # %bb.0:
22 ; CHECKIZFH-NEXT:    flh fa5, 0(a0)
23 ; CHECKIZFH-NEXT:    flh fa4, 6(a0)
24 ; CHECKIZFH-NEXT:    fadd.h fa0, fa5, fa4
25 ; CHECKIZFH-NEXT:    ret
27 ; CHECKIZHINX-LABEL: flh:
28 ; CHECKIZHINX:       # %bb.0:
29 ; CHECKIZHINX-NEXT:    lh a1, 0(a0)
30 ; CHECKIZHINX-NEXT:    lh a0, 6(a0)
31 ; CHECKIZHINX-NEXT:    fadd.h a0, a1, a0
32 ; CHECKIZHINX-NEXT:    ret
34 ; CHECKIZFHMIN-LABEL: flh:
35 ; CHECKIZFHMIN:       # %bb.0:
36 ; CHECKIZFHMIN-NEXT:    flh fa5, 6(a0)
37 ; CHECKIZFHMIN-NEXT:    flh fa4, 0(a0)
38 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa5
39 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa4
40 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
41 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
42 ; CHECKIZFHMIN-NEXT:    ret
44 ; CHECKIZHINXMIN-LABEL: flh:
45 ; CHECKIZHINXMIN:       # %bb.0:
46 ; CHECKIZHINXMIN-NEXT:    lh a1, 6(a0)
47 ; CHECKIZHINXMIN-NEXT:    lh a0, 0(a0)
48 ; CHECKIZHINXMIN-NEXT:    fcvt.s.h a1, a1
49 ; CHECKIZHINXMIN-NEXT:    fcvt.s.h a0, a0
50 ; CHECKIZHINXMIN-NEXT:    fadd.s a0, a0, a1
51 ; CHECKIZHINXMIN-NEXT:    fcvt.h.s a0, a0
52 ; CHECKIZHINXMIN-NEXT:    ret
53   %1 = load half, ptr %a
54   %2 = getelementptr half, ptr %a, i32 3
55   %3 = load half, ptr %2
56 ; Use both loaded values in an FP op to ensure an flh is used, even for the
57 ; soft half ABI
58   %4 = fadd half %1, %3
59   ret half %4
62 define dso_local void @fsh(ptr %a, half %b, half %c) nounwind {
63 ; Use %b and %c in an FP op to ensure half precision floating point registers
64 ; are used, even for the soft half ABI
65 ; CHECKIZFH-LABEL: fsh:
66 ; CHECKIZFH:       # %bb.0:
67 ; CHECKIZFH-NEXT:    fadd.h fa5, fa0, fa1
68 ; CHECKIZFH-NEXT:    fsh fa5, 0(a0)
69 ; CHECKIZFH-NEXT:    fsh fa5, 16(a0)
70 ; CHECKIZFH-NEXT:    ret
72 ; CHECKIZHINX-LABEL: fsh:
73 ; CHECKIZHINX:       # %bb.0:
74 ; CHECKIZHINX-NEXT:    fadd.h a1, a1, a2
75 ; CHECKIZHINX-NEXT:    sh a1, 0(a0)
76 ; CHECKIZHINX-NEXT:    sh a1, 16(a0)
77 ; CHECKIZHINX-NEXT:    ret
79 ; CHECKIZFHMIN-LABEL: fsh:
80 ; CHECKIZFHMIN:       # %bb.0:
81 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
82 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa0
83 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
84 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa5, fa5
85 ; CHECKIZFHMIN-NEXT:    fsh fa5, 0(a0)
86 ; CHECKIZFHMIN-NEXT:    fsh fa5, 16(a0)
87 ; CHECKIZFHMIN-NEXT:    ret
89 ; CHECKIZHINXMIN-LABEL: fsh:
90 ; CHECKIZHINXMIN:       # %bb.0:
91 ; CHECKIZHINXMIN-NEXT:    fcvt.s.h a2, a2
92 ; CHECKIZHINXMIN-NEXT:    fcvt.s.h a1, a1
93 ; CHECKIZHINXMIN-NEXT:    fadd.s a1, a1, a2
94 ; CHECKIZHINXMIN-NEXT:    fcvt.h.s a1, a1
95 ; CHECKIZHINXMIN-NEXT:    sh a1, 0(a0)
96 ; CHECKIZHINXMIN-NEXT:    sh a1, 16(a0)
97 ; CHECKIZHINXMIN-NEXT:    ret
98   %1 = fadd half %b, %c
99   store half %1, ptr %a
100   %2 = getelementptr half, ptr %a, i32 8
101   store half %1, ptr %2
102   ret void
105 ; Check load and store to a global
106 @G = dso_local global half 0.0
108 define half @flh_fsh_global(half %a, half %b) nounwind {
109 ; Use %a and %b in an FP op to ensure half precision floating point registers
110 ; are used, even for the soft half ABI
111 ; CHECKIZFH-LABEL: flh_fsh_global:
112 ; CHECKIZFH:       # %bb.0:
113 ; CHECKIZFH-NEXT:    fadd.h fa0, fa0, fa1
114 ; CHECKIZFH-NEXT:    lui a0, %hi(G)
115 ; CHECKIZFH-NEXT:    flh fa5, %lo(G)(a0)
116 ; CHECKIZFH-NEXT:    addi a1, a0, %lo(G)
117 ; CHECKIZFH-NEXT:    fsh fa0, %lo(G)(a0)
118 ; CHECKIZFH-NEXT:    flh fa5, 18(a1)
119 ; CHECKIZFH-NEXT:    fsh fa0, 18(a1)
120 ; CHECKIZFH-NEXT:    ret
122 ; CHECKIZHINX-LABEL: flh_fsh_global:
123 ; CHECKIZHINX:       # %bb.0:
124 ; CHECKIZHINX-NEXT:    fadd.h a0, a0, a1
125 ; CHECKIZHINX-NEXT:    lui a1, %hi(G)
126 ; CHECKIZHINX-NEXT:    lh zero, %lo(G)(a1)
127 ; CHECKIZHINX-NEXT:    addi a2, a1, %lo(G)
128 ; CHECKIZHINX-NEXT:    sh a0, %lo(G)(a1)
129 ; CHECKIZHINX-NEXT:    lh zero, 18(a2)
130 ; CHECKIZHINX-NEXT:    sh a0, 18(a2)
131 ; CHECKIZHINX-NEXT:    ret
133 ; CHECKIZFHMIN-LABEL: flh_fsh_global:
134 ; CHECKIZFHMIN:       # %bb.0:
135 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa5, fa1
136 ; CHECKIZFHMIN-NEXT:    fcvt.s.h fa4, fa0
137 ; CHECKIZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
138 ; CHECKIZFHMIN-NEXT:    fcvt.h.s fa0, fa5
139 ; CHECKIZFHMIN-NEXT:    lui a0, %hi(G)
140 ; CHECKIZFHMIN-NEXT:    flh fa5, %lo(G)(a0)
141 ; CHECKIZFHMIN-NEXT:    addi a1, a0, %lo(G)
142 ; CHECKIZFHMIN-NEXT:    fsh fa0, %lo(G)(a0)
143 ; CHECKIZFHMIN-NEXT:    flh fa5, 18(a1)
144 ; CHECKIZFHMIN-NEXT:    fsh fa0, 18(a1)
145 ; CHECKIZFHMIN-NEXT:    ret
147 ; CHECKIZHINXMIN-LABEL: flh_fsh_global:
148 ; CHECKIZHINXMIN:       # %bb.0:
149 ; CHECKIZHINXMIN-NEXT:    fcvt.s.h a1, a1
150 ; CHECKIZHINXMIN-NEXT:    fcvt.s.h a0, a0
151 ; CHECKIZHINXMIN-NEXT:    fadd.s a0, a0, a1
152 ; CHECKIZHINXMIN-NEXT:    fcvt.h.s a0, a0
153 ; CHECKIZHINXMIN-NEXT:    lui a1, %hi(G)
154 ; CHECKIZHINXMIN-NEXT:    lh zero, %lo(G)(a1)
155 ; CHECKIZHINXMIN-NEXT:    addi a2, a1, %lo(G)
156 ; CHECKIZHINXMIN-NEXT:    sh a0, %lo(G)(a1)
157 ; CHECKIZHINXMIN-NEXT:    lh zero, 18(a2)
158 ; CHECKIZHINXMIN-NEXT:    sh a0, 18(a2)
159 ; CHECKIZHINXMIN-NEXT:    ret
160   %1 = fadd half %a, %b
161   %2 = load volatile half, ptr @G
162   store half %1, ptr @G
163   %3 = getelementptr half, ptr @G, i32 9
164   %4 = load volatile half, ptr %3
165   store half %1, ptr %3
166   ret half %1
169 ; Ensure that 1 is added to the high 20 bits if bit 11 of the low part is 1
170 define half @flh_fsh_constant(half %a) nounwind {
171 ; RV32IZFH-LABEL: flh_fsh_constant:
172 ; RV32IZFH:       # %bb.0:
173 ; RV32IZFH-NEXT:    lui a0, 912092
174 ; RV32IZFH-NEXT:    flh fa5, -273(a0)
175 ; RV32IZFH-NEXT:    fadd.h fa0, fa0, fa5
176 ; RV32IZFH-NEXT:    fsh fa0, -273(a0)
177 ; RV32IZFH-NEXT:    ret
179 ; RV64IZFH-LABEL: flh_fsh_constant:
180 ; RV64IZFH:       # %bb.0:
181 ; RV64IZFH-NEXT:    lui a0, 228023
182 ; RV64IZFH-NEXT:    slli a0, a0, 2
183 ; RV64IZFH-NEXT:    flh fa5, -273(a0)
184 ; RV64IZFH-NEXT:    fadd.h fa0, fa0, fa5
185 ; RV64IZFH-NEXT:    fsh fa0, -273(a0)
186 ; RV64IZFH-NEXT:    ret
188 ; RV32IZHINX-LABEL: flh_fsh_constant:
189 ; RV32IZHINX:       # %bb.0:
190 ; RV32IZHINX-NEXT:    lui a1, 912092
191 ; RV32IZHINX-NEXT:    lh a2, -273(a1)
192 ; RV32IZHINX-NEXT:    fadd.h a0, a0, a2
193 ; RV32IZHINX-NEXT:    sh a0, -273(a1)
194 ; RV32IZHINX-NEXT:    ret
196 ; RV64IZHINX-LABEL: flh_fsh_constant:
197 ; RV64IZHINX:       # %bb.0:
198 ; RV64IZHINX-NEXT:    lui a1, 228023
199 ; RV64IZHINX-NEXT:    slli a1, a1, 2
200 ; RV64IZHINX-NEXT:    lh a2, -273(a1)
201 ; RV64IZHINX-NEXT:    fadd.h a0, a0, a2
202 ; RV64IZHINX-NEXT:    sh a0, -273(a1)
203 ; RV64IZHINX-NEXT:    ret
205 ; RV32IZFHMIN-LABEL: flh_fsh_constant:
206 ; RV32IZFHMIN:       # %bb.0:
207 ; RV32IZFHMIN-NEXT:    lui a0, 912092
208 ; RV32IZFHMIN-NEXT:    flh fa5, -273(a0)
209 ; RV32IZFHMIN-NEXT:    fcvt.s.h fa4, fa0
210 ; RV32IZFHMIN-NEXT:    fcvt.s.h fa5, fa5
211 ; RV32IZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
212 ; RV32IZFHMIN-NEXT:    fcvt.h.s fa0, fa5
213 ; RV32IZFHMIN-NEXT:    fsh fa0, -273(a0)
214 ; RV32IZFHMIN-NEXT:    ret
216 ; RV64IZFHMIN-LABEL: flh_fsh_constant:
217 ; RV64IZFHMIN:       # %bb.0:
218 ; RV64IZFHMIN-NEXT:    lui a0, 228023
219 ; RV64IZFHMIN-NEXT:    slli a0, a0, 2
220 ; RV64IZFHMIN-NEXT:    flh fa5, -273(a0)
221 ; RV64IZFHMIN-NEXT:    fcvt.s.h fa4, fa0
222 ; RV64IZFHMIN-NEXT:    fcvt.s.h fa5, fa5
223 ; RV64IZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
224 ; RV64IZFHMIN-NEXT:    fcvt.h.s fa0, fa5
225 ; RV64IZFHMIN-NEXT:    fsh fa0, -273(a0)
226 ; RV64IZFHMIN-NEXT:    ret
228 ; RV32IZHINXMIN-LABEL: flh_fsh_constant:
229 ; RV32IZHINXMIN:       # %bb.0:
230 ; RV32IZHINXMIN-NEXT:    lui a1, 912092
231 ; RV32IZHINXMIN-NEXT:    lh a2, -273(a1)
232 ; RV32IZHINXMIN-NEXT:    fcvt.s.h a0, a0
233 ; RV32IZHINXMIN-NEXT:    fcvt.s.h a2, a2
234 ; RV32IZHINXMIN-NEXT:    fadd.s a0, a0, a2
235 ; RV32IZHINXMIN-NEXT:    fcvt.h.s a0, a0
236 ; RV32IZHINXMIN-NEXT:    sh a0, -273(a1)
237 ; RV32IZHINXMIN-NEXT:    ret
239 ; RV64IZHINXMIN-LABEL: flh_fsh_constant:
240 ; RV64IZHINXMIN:       # %bb.0:
241 ; RV64IZHINXMIN-NEXT:    lui a1, 228023
242 ; RV64IZHINXMIN-NEXT:    slli a1, a1, 2
243 ; RV64IZHINXMIN-NEXT:    lh a2, -273(a1)
244 ; RV64IZHINXMIN-NEXT:    fcvt.s.h a0, a0
245 ; RV64IZHINXMIN-NEXT:    fcvt.s.h a2, a2
246 ; RV64IZHINXMIN-NEXT:    fadd.s a0, a0, a2
247 ; RV64IZHINXMIN-NEXT:    fcvt.h.s a0, a0
248 ; RV64IZHINXMIN-NEXT:    sh a0, -273(a1)
249 ; RV64IZHINXMIN-NEXT:    ret
250   %1 = inttoptr i32 3735928559 to ptr
251   %2 = load volatile half, ptr %1
252   %3 = fadd half %a, %2
253   store half %3, ptr %1
254   ret half %3
257 declare void @notdead(ptr)
259 define half @flh_stack(half %a) nounwind {
260 ; RV32IZFH-LABEL: flh_stack:
261 ; RV32IZFH:       # %bb.0:
262 ; RV32IZFH-NEXT:    addi sp, sp, -16
263 ; RV32IZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
264 ; RV32IZFH-NEXT:    fsw fs0, 8(sp) # 4-byte Folded Spill
265 ; RV32IZFH-NEXT:    fmv.h fs0, fa0
266 ; RV32IZFH-NEXT:    addi a0, sp, 4
267 ; RV32IZFH-NEXT:    call notdead
268 ; RV32IZFH-NEXT:    flh fa5, 4(sp)
269 ; RV32IZFH-NEXT:    fadd.h fa0, fa5, fs0
270 ; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
271 ; RV32IZFH-NEXT:    flw fs0, 8(sp) # 4-byte Folded Reload
272 ; RV32IZFH-NEXT:    addi sp, sp, 16
273 ; RV32IZFH-NEXT:    ret
275 ; RV64IZFH-LABEL: flh_stack:
276 ; RV64IZFH:       # %bb.0:
277 ; RV64IZFH-NEXT:    addi sp, sp, -16
278 ; RV64IZFH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
279 ; RV64IZFH-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
280 ; RV64IZFH-NEXT:    fmv.h fs0, fa0
281 ; RV64IZFH-NEXT:    mv a0, sp
282 ; RV64IZFH-NEXT:    call notdead
283 ; RV64IZFH-NEXT:    flh fa5, 0(sp)
284 ; RV64IZFH-NEXT:    fadd.h fa0, fa5, fs0
285 ; RV64IZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
286 ; RV64IZFH-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
287 ; RV64IZFH-NEXT:    addi sp, sp, 16
288 ; RV64IZFH-NEXT:    ret
290 ; RV32IZHINX-LABEL: flh_stack:
291 ; RV32IZHINX:       # %bb.0:
292 ; RV32IZHINX-NEXT:    addi sp, sp, -16
293 ; RV32IZHINX-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
294 ; RV32IZHINX-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
295 ; RV32IZHINX-NEXT:    mv s0, a0
296 ; RV32IZHINX-NEXT:    addi a0, sp, 4
297 ; RV32IZHINX-NEXT:    call notdead
298 ; RV32IZHINX-NEXT:    lh a0, 4(sp)
299 ; RV32IZHINX-NEXT:    fadd.h a0, a0, s0
300 ; RV32IZHINX-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
301 ; RV32IZHINX-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
302 ; RV32IZHINX-NEXT:    addi sp, sp, 16
303 ; RV32IZHINX-NEXT:    ret
305 ; RV64IZHINX-LABEL: flh_stack:
306 ; RV64IZHINX:       # %bb.0:
307 ; RV64IZHINX-NEXT:    addi sp, sp, -32
308 ; RV64IZHINX-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
309 ; RV64IZHINX-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
310 ; RV64IZHINX-NEXT:    mv s0, a0
311 ; RV64IZHINX-NEXT:    addi a0, sp, 12
312 ; RV64IZHINX-NEXT:    call notdead
313 ; RV64IZHINX-NEXT:    lh a0, 12(sp)
314 ; RV64IZHINX-NEXT:    fadd.h a0, a0, s0
315 ; RV64IZHINX-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
316 ; RV64IZHINX-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
317 ; RV64IZHINX-NEXT:    addi sp, sp, 32
318 ; RV64IZHINX-NEXT:    ret
320 ; RV32IZFHMIN-LABEL: flh_stack:
321 ; RV32IZFHMIN:       # %bb.0:
322 ; RV32IZFHMIN-NEXT:    addi sp, sp, -16
323 ; RV32IZFHMIN-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
324 ; RV32IZFHMIN-NEXT:    fsw fs0, 8(sp) # 4-byte Folded Spill
325 ; RV32IZFHMIN-NEXT:    fmv.s fs0, fa0
326 ; RV32IZFHMIN-NEXT:    addi a0, sp, 4
327 ; RV32IZFHMIN-NEXT:    call notdead
328 ; RV32IZFHMIN-NEXT:    flh fa5, 4(sp)
329 ; RV32IZFHMIN-NEXT:    fcvt.s.h fa4, fs0
330 ; RV32IZFHMIN-NEXT:    fcvt.s.h fa5, fa5
331 ; RV32IZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
332 ; RV32IZFHMIN-NEXT:    fcvt.h.s fa0, fa5
333 ; RV32IZFHMIN-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
334 ; RV32IZFHMIN-NEXT:    flw fs0, 8(sp) # 4-byte Folded Reload
335 ; RV32IZFHMIN-NEXT:    addi sp, sp, 16
336 ; RV32IZFHMIN-NEXT:    ret
338 ; RV64IZFHMIN-LABEL: flh_stack:
339 ; RV64IZFHMIN:       # %bb.0:
340 ; RV64IZFHMIN-NEXT:    addi sp, sp, -16
341 ; RV64IZFHMIN-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
342 ; RV64IZFHMIN-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
343 ; RV64IZFHMIN-NEXT:    fmv.s fs0, fa0
344 ; RV64IZFHMIN-NEXT:    mv a0, sp
345 ; RV64IZFHMIN-NEXT:    call notdead
346 ; RV64IZFHMIN-NEXT:    flh fa5, 0(sp)
347 ; RV64IZFHMIN-NEXT:    fcvt.s.h fa4, fs0
348 ; RV64IZFHMIN-NEXT:    fcvt.s.h fa5, fa5
349 ; RV64IZFHMIN-NEXT:    fadd.s fa5, fa5, fa4
350 ; RV64IZFHMIN-NEXT:    fcvt.h.s fa0, fa5
351 ; RV64IZFHMIN-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
352 ; RV64IZFHMIN-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
353 ; RV64IZFHMIN-NEXT:    addi sp, sp, 16
354 ; RV64IZFHMIN-NEXT:    ret
356 ; RV32IZHINXMIN-LABEL: flh_stack:
357 ; RV32IZHINXMIN:       # %bb.0:
358 ; RV32IZHINXMIN-NEXT:    addi sp, sp, -16
359 ; RV32IZHINXMIN-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
360 ; RV32IZHINXMIN-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
361 ; RV32IZHINXMIN-NEXT:    mv s0, a0
362 ; RV32IZHINXMIN-NEXT:    addi a0, sp, 4
363 ; RV32IZHINXMIN-NEXT:    call notdead
364 ; RV32IZHINXMIN-NEXT:    lh a0, 4(sp)
365 ; RV32IZHINXMIN-NEXT:    fcvt.s.h a1, s0
366 ; RV32IZHINXMIN-NEXT:    fcvt.s.h a0, a0
367 ; RV32IZHINXMIN-NEXT:    fadd.s a0, a0, a1
368 ; RV32IZHINXMIN-NEXT:    fcvt.h.s a0, a0
369 ; RV32IZHINXMIN-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
370 ; RV32IZHINXMIN-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
371 ; RV32IZHINXMIN-NEXT:    addi sp, sp, 16
372 ; RV32IZHINXMIN-NEXT:    ret
374 ; RV64IZHINXMIN-LABEL: flh_stack:
375 ; RV64IZHINXMIN:       # %bb.0:
376 ; RV64IZHINXMIN-NEXT:    addi sp, sp, -32
377 ; RV64IZHINXMIN-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
378 ; RV64IZHINXMIN-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
379 ; RV64IZHINXMIN-NEXT:    mv s0, a0
380 ; RV64IZHINXMIN-NEXT:    addi a0, sp, 12
381 ; RV64IZHINXMIN-NEXT:    call notdead
382 ; RV64IZHINXMIN-NEXT:    lh a0, 12(sp)
383 ; RV64IZHINXMIN-NEXT:    fcvt.s.h a1, s0
384 ; RV64IZHINXMIN-NEXT:    fcvt.s.h a0, a0
385 ; RV64IZHINXMIN-NEXT:    fadd.s a0, a0, a1
386 ; RV64IZHINXMIN-NEXT:    fcvt.h.s a0, a0
387 ; RV64IZHINXMIN-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
388 ; RV64IZHINXMIN-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
389 ; RV64IZHINXMIN-NEXT:    addi sp, sp, 32
390 ; RV64IZHINXMIN-NEXT:    ret
391   %1 = alloca half, align 4
392   call void @notdead(ptr %1)
393   %2 = load half, ptr %1
394   %3 = fadd half %2, %a ; force load in to FPR16
395   ret half %3
398 define dso_local void @fsh_stack(half %a, half %b) nounwind {
399 ; RV32IZFH-LABEL: fsh_stack:
400 ; RV32IZFH:       # %bb.0:
401 ; RV32IZFH-NEXT:    addi sp, sp, -16
402 ; RV32IZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
403 ; RV32IZFH-NEXT:    fadd.h fa5, fa0, fa1
404 ; RV32IZFH-NEXT:    fsh fa5, 8(sp)
405 ; RV32IZFH-NEXT:    addi a0, sp, 8
406 ; RV32IZFH-NEXT:    call notdead
407 ; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
408 ; RV32IZFH-NEXT:    addi sp, sp, 16
409 ; RV32IZFH-NEXT:    ret
411 ; RV64IZFH-LABEL: fsh_stack:
412 ; RV64IZFH:       # %bb.0:
413 ; RV64IZFH-NEXT:    addi sp, sp, -16
414 ; RV64IZFH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
415 ; RV64IZFH-NEXT:    fadd.h fa5, fa0, fa1
416 ; RV64IZFH-NEXT:    fsh fa5, 4(sp)
417 ; RV64IZFH-NEXT:    addi a0, sp, 4
418 ; RV64IZFH-NEXT:    call notdead
419 ; RV64IZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
420 ; RV64IZFH-NEXT:    addi sp, sp, 16
421 ; RV64IZFH-NEXT:    ret
423 ; RV32IZHINX-LABEL: fsh_stack:
424 ; RV32IZHINX:       # %bb.0:
425 ; RV32IZHINX-NEXT:    addi sp, sp, -16
426 ; RV32IZHINX-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
427 ; RV32IZHINX-NEXT:    fadd.h a0, a0, a1
428 ; RV32IZHINX-NEXT:    sh a0, 8(sp)
429 ; RV32IZHINX-NEXT:    addi a0, sp, 8
430 ; RV32IZHINX-NEXT:    call notdead
431 ; RV32IZHINX-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
432 ; RV32IZHINX-NEXT:    addi sp, sp, 16
433 ; RV32IZHINX-NEXT:    ret
435 ; RV64IZHINX-LABEL: fsh_stack:
436 ; RV64IZHINX:       # %bb.0:
437 ; RV64IZHINX-NEXT:    addi sp, sp, -16
438 ; RV64IZHINX-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
439 ; RV64IZHINX-NEXT:    fadd.h a0, a0, a1
440 ; RV64IZHINX-NEXT:    sh a0, 4(sp)
441 ; RV64IZHINX-NEXT:    addi a0, sp, 4
442 ; RV64IZHINX-NEXT:    call notdead
443 ; RV64IZHINX-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
444 ; RV64IZHINX-NEXT:    addi sp, sp, 16
445 ; RV64IZHINX-NEXT:    ret
447 ; RV32IZFHMIN-LABEL: fsh_stack:
448 ; RV32IZFHMIN:       # %bb.0:
449 ; RV32IZFHMIN-NEXT:    addi sp, sp, -16
450 ; RV32IZFHMIN-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
451 ; RV32IZFHMIN-NEXT:    fcvt.s.h fa5, fa1
452 ; RV32IZFHMIN-NEXT:    fcvt.s.h fa4, fa0
453 ; RV32IZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
454 ; RV32IZFHMIN-NEXT:    fcvt.h.s fa5, fa5
455 ; RV32IZFHMIN-NEXT:    fsh fa5, 8(sp)
456 ; RV32IZFHMIN-NEXT:    addi a0, sp, 8
457 ; RV32IZFHMIN-NEXT:    call notdead
458 ; RV32IZFHMIN-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
459 ; RV32IZFHMIN-NEXT:    addi sp, sp, 16
460 ; RV32IZFHMIN-NEXT:    ret
462 ; RV64IZFHMIN-LABEL: fsh_stack:
463 ; RV64IZFHMIN:       # %bb.0:
464 ; RV64IZFHMIN-NEXT:    addi sp, sp, -16
465 ; RV64IZFHMIN-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
466 ; RV64IZFHMIN-NEXT:    fcvt.s.h fa5, fa1
467 ; RV64IZFHMIN-NEXT:    fcvt.s.h fa4, fa0
468 ; RV64IZFHMIN-NEXT:    fadd.s fa5, fa4, fa5
469 ; RV64IZFHMIN-NEXT:    fcvt.h.s fa5, fa5
470 ; RV64IZFHMIN-NEXT:    fsh fa5, 4(sp)
471 ; RV64IZFHMIN-NEXT:    addi a0, sp, 4
472 ; RV64IZFHMIN-NEXT:    call notdead
473 ; RV64IZFHMIN-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
474 ; RV64IZFHMIN-NEXT:    addi sp, sp, 16
475 ; RV64IZFHMIN-NEXT:    ret
477 ; RV32IZHINXMIN-LABEL: fsh_stack:
478 ; RV32IZHINXMIN:       # %bb.0:
479 ; RV32IZHINXMIN-NEXT:    addi sp, sp, -16
480 ; RV32IZHINXMIN-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
481 ; RV32IZHINXMIN-NEXT:    fcvt.s.h a1, a1
482 ; RV32IZHINXMIN-NEXT:    fcvt.s.h a0, a0
483 ; RV32IZHINXMIN-NEXT:    fadd.s a0, a0, a1
484 ; RV32IZHINXMIN-NEXT:    fcvt.h.s a0, a0
485 ; RV32IZHINXMIN-NEXT:    sh a0, 8(sp)
486 ; RV32IZHINXMIN-NEXT:    addi a0, sp, 8
487 ; RV32IZHINXMIN-NEXT:    call notdead
488 ; RV32IZHINXMIN-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
489 ; RV32IZHINXMIN-NEXT:    addi sp, sp, 16
490 ; RV32IZHINXMIN-NEXT:    ret
492 ; RV64IZHINXMIN-LABEL: fsh_stack:
493 ; RV64IZHINXMIN:       # %bb.0:
494 ; RV64IZHINXMIN-NEXT:    addi sp, sp, -16
495 ; RV64IZHINXMIN-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
496 ; RV64IZHINXMIN-NEXT:    fcvt.s.h a1, a1
497 ; RV64IZHINXMIN-NEXT:    fcvt.s.h a0, a0
498 ; RV64IZHINXMIN-NEXT:    fadd.s a0, a0, a1
499 ; RV64IZHINXMIN-NEXT:    fcvt.h.s a0, a0
500 ; RV64IZHINXMIN-NEXT:    sh a0, 4(sp)
501 ; RV64IZHINXMIN-NEXT:    addi a0, sp, 4
502 ; RV64IZHINXMIN-NEXT:    call notdead
503 ; RV64IZHINXMIN-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
504 ; RV64IZHINXMIN-NEXT:    addi sp, sp, 16
505 ; RV64IZHINXMIN-NEXT:    ret
506   %1 = fadd half %a, %b ; force store from FPR16
507   %2 = alloca half, align 4
508   store half %1, ptr %2
509   call void @notdead(ptr %2)
510   ret void