1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -global-isel -mattr=+f \
3 ; RUN: -verify-machineinstrs -target-abi=ilp32f \
4 ; RUN: | FileCheck -check-prefix=RV32IF %s
5 ; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -global-isel -mattr=+d \
6 ; RUN: -verify-machineinstrs -target-abi=ilp32f \
7 ; RUN: | FileCheck -check-prefix=RV32IF %s
8 ; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -global-isel -mattr=+f \
9 ; RUN: -verify-machineinstrs -target-abi=lp64f \
10 ; RUN: | FileCheck -check-prefix=RV64IF %s
11 ; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -global-isel -mattr=+d \
12 ; RUN: -verify-machineinstrs -target-abi=lp64d \
13 ; RUN: | FileCheck -check-prefix=RV64IF %s
15 define float @sqrt_f32(float %a) nounwind {
16 ; RV32IF-LABEL: sqrt_f32:
18 ; RV32IF-NEXT: fsqrt.s fa0, fa0
21 ; RV64IF-LABEL: sqrt_f32:
23 ; RV64IF-NEXT: fsqrt.s fa0, fa0
25 %1 = call float @llvm.sqrt.f32(float %a)
29 define float @fma_f32(float %a, float %b, float %c) nounwind {
30 ; RV32IF-LABEL: fma_f32:
32 ; RV32IF-NEXT: fmadd.s fa0, fa0, fa1, fa2
35 ; RV64IF-LABEL: fma_f32:
37 ; RV64IF-NEXT: fmadd.s fa0, fa0, fa1, fa2
39 %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
43 define float @fmuladd_f32(float %a, float %b, float %c) nounwind {
44 ; RV32IF-LABEL: fmuladd_f32:
46 ; RV32IF-NEXT: fmadd.s fa0, fa0, fa1, fa2
49 ; RV64IF-LABEL: fmuladd_f32:
51 ; RV64IF-NEXT: fmadd.s fa0, fa0, fa1, fa2
53 %1 = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
57 define float @fabs_f32(float %a) nounwind {
58 ; RV32IF-LABEL: fabs_f32:
60 ; RV32IF-NEXT: fabs.s fa0, fa0
63 ; RV64IF-LABEL: fabs_f32:
65 ; RV64IF-NEXT: fabs.s fa0, fa0
67 %1 = call float @llvm.fabs.f32(float %a)
71 define float @minnum_f32(float %a, float %b) nounwind {
72 ; RV32IF-LABEL: minnum_f32:
74 ; RV32IF-NEXT: fmin.s fa0, fa0, fa1
77 ; RV64IF-LABEL: minnum_f32:
79 ; RV64IF-NEXT: fmin.s fa0, fa0, fa1
81 %1 = call float @llvm.minnum.f32(float %a, float %b)
85 define float @maxnum_f32(float %a, float %b) nounwind {
86 ; RV32IF-LABEL: maxnum_f32:
88 ; RV32IF-NEXT: fmax.s fa0, fa0, fa1
91 ; RV64IF-LABEL: maxnum_f32:
93 ; RV64IF-NEXT: fmax.s fa0, fa0, fa1
95 %1 = call float @llvm.maxnum.f32(float %a, float %b)
99 define float @copysign_f32(float %a, float %b) nounwind {
100 ; RV32IF-LABEL: copysign_f32:
102 ; RV32IF-NEXT: fsgnj.s fa0, fa0, fa1
105 ; RV64IF-LABEL: copysign_f32:
107 ; RV64IF-NEXT: fsgnj.s fa0, fa0, fa1
109 %1 = call float @llvm.copysign.f32(float %a, float %b)
113 define float @ceil_f32(float %a) nounwind {
114 ; RV32IF-LABEL: ceil_f32:
116 ; RV32IF-NEXT: addi sp, sp, -16
117 ; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
118 ; RV32IF-NEXT: call ceilf
119 ; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
120 ; RV32IF-NEXT: addi sp, sp, 16
123 ; RV64IF-LABEL: ceil_f32:
125 ; RV64IF-NEXT: addi sp, sp, -16
126 ; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
127 ; RV64IF-NEXT: call ceilf
128 ; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
129 ; RV64IF-NEXT: addi sp, sp, 16
131 %1 = call float @llvm.ceil.f32(float %a)
135 define float @trunc_f32(float %a) nounwind {
136 ; RV32IF-LABEL: trunc_f32:
138 ; RV32IF-NEXT: addi sp, sp, -16
139 ; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
140 ; RV32IF-NEXT: call truncf
141 ; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
142 ; RV32IF-NEXT: addi sp, sp, 16
145 ; RV64IF-LABEL: trunc_f32:
147 ; RV64IF-NEXT: addi sp, sp, -16
148 ; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
149 ; RV64IF-NEXT: call truncf
150 ; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
151 ; RV64IF-NEXT: addi sp, sp, 16
153 %1 = call float @llvm.trunc.f32(float %a)
157 define float @rint_f32(float %a) nounwind {
158 ; RV32IF-LABEL: rint_f32:
160 ; RV32IF-NEXT: addi sp, sp, -16
161 ; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
162 ; RV32IF-NEXT: call rintf
163 ; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
164 ; RV32IF-NEXT: addi sp, sp, 16
167 ; RV64IF-LABEL: rint_f32:
169 ; RV64IF-NEXT: addi sp, sp, -16
170 ; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
171 ; RV64IF-NEXT: call rintf
172 ; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
173 ; RV64IF-NEXT: addi sp, sp, 16
175 %1 = call float @llvm.rint.f32(float %a)
179 define float @nearbyint_f32(float %a) nounwind {
180 ; RV32IF-LABEL: nearbyint_f32:
182 ; RV32IF-NEXT: addi sp, sp, -16
183 ; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
184 ; RV32IF-NEXT: call nearbyintf
185 ; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
186 ; RV32IF-NEXT: addi sp, sp, 16
189 ; RV64IF-LABEL: nearbyint_f32:
191 ; RV64IF-NEXT: addi sp, sp, -16
192 ; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
193 ; RV64IF-NEXT: call nearbyintf
194 ; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
195 ; RV64IF-NEXT: addi sp, sp, 16
197 %1 = call float @llvm.nearbyint.f32(float %a)
201 define float @round_f32(float %a) nounwind {
202 ; RV32IF-LABEL: round_f32:
204 ; RV32IF-NEXT: addi sp, sp, -16
205 ; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
206 ; RV32IF-NEXT: call roundf
207 ; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
208 ; RV32IF-NEXT: addi sp, sp, 16
211 ; RV64IF-LABEL: round_f32:
213 ; RV64IF-NEXT: addi sp, sp, -16
214 ; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
215 ; RV64IF-NEXT: call roundf
216 ; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
217 ; RV64IF-NEXT: addi sp, sp, 16
219 %1 = call float @llvm.round.f32(float %a)
223 define float @roundeven_f32(float %a) nounwind {
224 ; RV32IF-LABEL: roundeven_f32:
226 ; RV32IF-NEXT: addi sp, sp, -16
227 ; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
228 ; RV32IF-NEXT: call roundevenf
229 ; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
230 ; RV32IF-NEXT: addi sp, sp, 16
233 ; RV64IF-LABEL: roundeven_f32:
235 ; RV64IF-NEXT: addi sp, sp, -16
236 ; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
237 ; RV64IF-NEXT: call roundevenf
238 ; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
239 ; RV64IF-NEXT: addi sp, sp, 16
241 %1 = call float @llvm.roundeven.f32(float %a)
245 define i1 @fpclass(float %x) {
246 ; RV32IF-LABEL: fpclass:
248 ; RV32IF-NEXT: fclass.s a0, fa0
249 ; RV32IF-NEXT: andi a0, a0, 927
250 ; RV32IF-NEXT: snez a0, a0
253 ; RV64IF-LABEL: fpclass:
255 ; RV64IF-NEXT: fclass.s a0, fa0
256 ; RV64IF-NEXT: andi a0, a0, 927
257 ; RV64IF-NEXT: snez a0, a0
259 %cmp = call i1 @llvm.is.fpclass.f32(float %x, i32 639)
263 define i1 @isnan_fpclass(float %x) {
264 ; RV32IF-LABEL: isnan_fpclass:
266 ; RV32IF-NEXT: fclass.s a0, fa0
267 ; RV32IF-NEXT: andi a0, a0, 768
268 ; RV32IF-NEXT: snez a0, a0
271 ; RV64IF-LABEL: isnan_fpclass:
273 ; RV64IF-NEXT: fclass.s a0, fa0
274 ; RV64IF-NEXT: andi a0, a0, 768
275 ; RV64IF-NEXT: snez a0, a0
277 %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 3) ; nan
281 define i1 @isqnan_fpclass(float %x) {
282 ; RV32IF-LABEL: isqnan_fpclass:
284 ; RV32IF-NEXT: fclass.s a0, fa0
285 ; RV32IF-NEXT: andi a0, a0, 512
286 ; RV32IF-NEXT: snez a0, a0
289 ; RV64IF-LABEL: isqnan_fpclass:
291 ; RV64IF-NEXT: fclass.s a0, fa0
292 ; RV64IF-NEXT: andi a0, a0, 512
293 ; RV64IF-NEXT: snez a0, a0
295 %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 2) ; qnan
299 define i1 @issnan_fpclass(float %x) {
300 ; RV32IF-LABEL: issnan_fpclass:
302 ; RV32IF-NEXT: fclass.s a0, fa0
303 ; RV32IF-NEXT: andi a0, a0, 256
304 ; RV32IF-NEXT: snez a0, a0
307 ; RV64IF-LABEL: issnan_fpclass:
309 ; RV64IF-NEXT: fclass.s a0, fa0
310 ; RV64IF-NEXT: andi a0, a0, 256
311 ; RV64IF-NEXT: snez a0, a0
313 %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 1) ; snan
317 define i1 @isinf_fpclass(float %x) {
318 ; RV32IF-LABEL: isinf_fpclass:
320 ; RV32IF-NEXT: fclass.s a0, fa0
321 ; RV32IF-NEXT: andi a0, a0, 129
322 ; RV32IF-NEXT: snez a0, a0
325 ; RV64IF-LABEL: isinf_fpclass:
327 ; RV64IF-NEXT: fclass.s a0, fa0
328 ; RV64IF-NEXT: andi a0, a0, 129
329 ; RV64IF-NEXT: snez a0, a0
331 %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 516) ; 0x204 = "inf"
335 define i1 @isposinf_fpclass(float %x) {
336 ; RV32IF-LABEL: isposinf_fpclass:
338 ; RV32IF-NEXT: fclass.s a0, fa0
339 ; RV32IF-NEXT: andi a0, a0, 128
340 ; RV32IF-NEXT: snez a0, a0
343 ; RV64IF-LABEL: isposinf_fpclass:
345 ; RV64IF-NEXT: fclass.s a0, fa0
346 ; RV64IF-NEXT: andi a0, a0, 128
347 ; RV64IF-NEXT: snez a0, a0
349 %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 512) ; 0x200 = "+inf"
353 define i1 @isneginf_fpclass(float %x) {
354 ; RV32IF-LABEL: isneginf_fpclass:
356 ; RV32IF-NEXT: fclass.s a0, fa0
357 ; RV32IF-NEXT: andi a0, a0, 1
358 ; RV32IF-NEXT: snez a0, a0
361 ; RV64IF-LABEL: isneginf_fpclass:
363 ; RV64IF-NEXT: fclass.s a0, fa0
364 ; RV64IF-NEXT: andi a0, a0, 1
365 ; RV64IF-NEXT: snez a0, a0
367 %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 4) ; "-inf"
371 define i1 @isfinite_fpclass(float %x) {
372 ; RV32IF-LABEL: isfinite_fpclass:
374 ; RV32IF-NEXT: fclass.s a0, fa0
375 ; RV32IF-NEXT: andi a0, a0, 126
376 ; RV32IF-NEXT: snez a0, a0
379 ; RV64IF-LABEL: isfinite_fpclass:
381 ; RV64IF-NEXT: fclass.s a0, fa0
382 ; RV64IF-NEXT: andi a0, a0, 126
383 ; RV64IF-NEXT: snez a0, a0
385 %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 504) ; 0x1f8 = "finite"
389 define i1 @isposfinite_fpclass(float %x) {
390 ; RV32IF-LABEL: isposfinite_fpclass:
392 ; RV32IF-NEXT: fclass.s a0, fa0
393 ; RV32IF-NEXT: andi a0, a0, 112
394 ; RV32IF-NEXT: snez a0, a0
397 ; RV64IF-LABEL: isposfinite_fpclass:
399 ; RV64IF-NEXT: fclass.s a0, fa0
400 ; RV64IF-NEXT: andi a0, a0, 112
401 ; RV64IF-NEXT: snez a0, a0
403 %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 448) ; 0x1c0 = "+finite"
407 define i1 @isnegfinite_fpclass(float %x) {
408 ; RV32IF-LABEL: isnegfinite_fpclass:
410 ; RV32IF-NEXT: fclass.s a0, fa0
411 ; RV32IF-NEXT: andi a0, a0, 14
412 ; RV32IF-NEXT: snez a0, a0
415 ; RV64IF-LABEL: isnegfinite_fpclass:
417 ; RV64IF-NEXT: fclass.s a0, fa0
418 ; RV64IF-NEXT: andi a0, a0, 14
419 ; RV64IF-NEXT: snez a0, a0
421 %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 56) ; 0x38 = "-finite"
425 define i1 @isnotfinite_fpclass(float %x) {
426 ; RV32IF-LABEL: isnotfinite_fpclass:
428 ; RV32IF-NEXT: fclass.s a0, fa0
429 ; RV32IF-NEXT: andi a0, a0, 897
430 ; RV32IF-NEXT: snez a0, a0
433 ; RV64IF-LABEL: isnotfinite_fpclass:
435 ; RV64IF-NEXT: fclass.s a0, fa0
436 ; RV64IF-NEXT: andi a0, a0, 897
437 ; RV64IF-NEXT: snez a0, a0
439 %1 = call i1 @llvm.is.fpclass.f32(float %x, i32 519) ; ox207 = "inf|nan"