1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -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 -mattr=+zfinx \
6 ; RUN: -verify-machineinstrs -target-abi=ilp32 \
7 ; RUN: | FileCheck -check-prefix=RV32IZFINX %s
8 ; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+d \
9 ; RUN: -verify-machineinstrs -target-abi=ilp32f \
10 ; RUN: | FileCheck -check-prefix=RV32IF %s
11 ; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+f \
12 ; RUN: -verify-machineinstrs -target-abi=lp64f \
13 ; RUN: | FileCheck -check-prefix=RV64IF %s
14 ; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+zfinx \
15 ; RUN: -verify-machineinstrs -target-abi=lp64 \
16 ; RUN: | FileCheck -check-prefix=RV64IZFINX %s
17 ; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+d \
18 ; RUN: -verify-machineinstrs -target-abi=lp64d \
19 ; RUN: | FileCheck -check-prefix=RV64IF %s
21 declare float @llvm.minimum.f32(float, float)
23 define float @fminimum_f32(float %a, float %b) nounwind {
24 ; RV32IF-LABEL: fminimum_f32:
26 ; RV32IF-NEXT: feq.s a0, fa0, fa0
27 ; RV32IF-NEXT: fmv.s fa5, fa1
28 ; RV32IF-NEXT: beqz a0, .LBB0_3
29 ; RV32IF-NEXT: # %bb.1:
30 ; RV32IF-NEXT: feq.s a0, fa1, fa1
31 ; RV32IF-NEXT: beqz a0, .LBB0_4
32 ; RV32IF-NEXT: .LBB0_2:
33 ; RV32IF-NEXT: fmin.s fa0, fa0, fa5
35 ; RV32IF-NEXT: .LBB0_3:
36 ; RV32IF-NEXT: fmv.s fa5, fa0
37 ; RV32IF-NEXT: feq.s a0, fa1, fa1
38 ; RV32IF-NEXT: bnez a0, .LBB0_2
39 ; RV32IF-NEXT: .LBB0_4:
40 ; RV32IF-NEXT: fmin.s fa0, fa1, fa5
43 ; RV32IZFINX-LABEL: fminimum_f32:
44 ; RV32IZFINX: # %bb.0:
45 ; RV32IZFINX-NEXT: feq.s a3, a0, a0
46 ; RV32IZFINX-NEXT: mv a2, a1
47 ; RV32IZFINX-NEXT: beqz a3, .LBB0_3
48 ; RV32IZFINX-NEXT: # %bb.1:
49 ; RV32IZFINX-NEXT: feq.s a3, a1, a1
50 ; RV32IZFINX-NEXT: beqz a3, .LBB0_4
51 ; RV32IZFINX-NEXT: .LBB0_2:
52 ; RV32IZFINX-NEXT: fmin.s a0, a0, a2
53 ; RV32IZFINX-NEXT: ret
54 ; RV32IZFINX-NEXT: .LBB0_3:
55 ; RV32IZFINX-NEXT: mv a2, a0
56 ; RV32IZFINX-NEXT: feq.s a3, a1, a1
57 ; RV32IZFINX-NEXT: bnez a3, .LBB0_2
58 ; RV32IZFINX-NEXT: .LBB0_4:
59 ; RV32IZFINX-NEXT: fmin.s a0, a1, a2
60 ; RV32IZFINX-NEXT: ret
62 ; RV64IF-LABEL: fminimum_f32:
64 ; RV64IF-NEXT: feq.s a0, fa0, fa0
65 ; RV64IF-NEXT: fmv.s fa5, fa1
66 ; RV64IF-NEXT: beqz a0, .LBB0_3
67 ; RV64IF-NEXT: # %bb.1:
68 ; RV64IF-NEXT: feq.s a0, fa1, fa1
69 ; RV64IF-NEXT: beqz a0, .LBB0_4
70 ; RV64IF-NEXT: .LBB0_2:
71 ; RV64IF-NEXT: fmin.s fa0, fa0, fa5
73 ; RV64IF-NEXT: .LBB0_3:
74 ; RV64IF-NEXT: fmv.s fa5, fa0
75 ; RV64IF-NEXT: feq.s a0, fa1, fa1
76 ; RV64IF-NEXT: bnez a0, .LBB0_2
77 ; RV64IF-NEXT: .LBB0_4:
78 ; RV64IF-NEXT: fmin.s fa0, fa1, fa5
81 ; RV64IZFINX-LABEL: fminimum_f32:
82 ; RV64IZFINX: # %bb.0:
83 ; RV64IZFINX-NEXT: feq.s a3, a0, a0
84 ; RV64IZFINX-NEXT: mv a2, a1
85 ; RV64IZFINX-NEXT: beqz a3, .LBB0_3
86 ; RV64IZFINX-NEXT: # %bb.1:
87 ; RV64IZFINX-NEXT: feq.s a3, a1, a1
88 ; RV64IZFINX-NEXT: beqz a3, .LBB0_4
89 ; RV64IZFINX-NEXT: .LBB0_2:
90 ; RV64IZFINX-NEXT: fmin.s a0, a0, a2
91 ; RV64IZFINX-NEXT: ret
92 ; RV64IZFINX-NEXT: .LBB0_3:
93 ; RV64IZFINX-NEXT: mv a2, a0
94 ; RV64IZFINX-NEXT: feq.s a3, a1, a1
95 ; RV64IZFINX-NEXT: bnez a3, .LBB0_2
96 ; RV64IZFINX-NEXT: .LBB0_4:
97 ; RV64IZFINX-NEXT: fmin.s a0, a1, a2
98 ; RV64IZFINX-NEXT: ret
99 %1 = call float @llvm.minimum.f32(float %a, float %b)
103 declare float @llvm.maximum.f32(float, float)
105 define float @fmaximum_f32(float %a, float %b) nounwind {
106 ; RV32IF-LABEL: fmaximum_f32:
108 ; RV32IF-NEXT: feq.s a0, fa0, fa0
109 ; RV32IF-NEXT: fmv.s fa5, fa1
110 ; RV32IF-NEXT: beqz a0, .LBB1_3
111 ; RV32IF-NEXT: # %bb.1:
112 ; RV32IF-NEXT: feq.s a0, fa1, fa1
113 ; RV32IF-NEXT: beqz a0, .LBB1_4
114 ; RV32IF-NEXT: .LBB1_2:
115 ; RV32IF-NEXT: fmax.s fa0, fa0, fa5
117 ; RV32IF-NEXT: .LBB1_3:
118 ; RV32IF-NEXT: fmv.s fa5, fa0
119 ; RV32IF-NEXT: feq.s a0, fa1, fa1
120 ; RV32IF-NEXT: bnez a0, .LBB1_2
121 ; RV32IF-NEXT: .LBB1_4:
122 ; RV32IF-NEXT: fmax.s fa0, fa1, fa5
125 ; RV32IZFINX-LABEL: fmaximum_f32:
126 ; RV32IZFINX: # %bb.0:
127 ; RV32IZFINX-NEXT: feq.s a3, a0, a0
128 ; RV32IZFINX-NEXT: mv a2, a1
129 ; RV32IZFINX-NEXT: beqz a3, .LBB1_3
130 ; RV32IZFINX-NEXT: # %bb.1:
131 ; RV32IZFINX-NEXT: feq.s a3, a1, a1
132 ; RV32IZFINX-NEXT: beqz a3, .LBB1_4
133 ; RV32IZFINX-NEXT: .LBB1_2:
134 ; RV32IZFINX-NEXT: fmax.s a0, a0, a2
135 ; RV32IZFINX-NEXT: ret
136 ; RV32IZFINX-NEXT: .LBB1_3:
137 ; RV32IZFINX-NEXT: mv a2, a0
138 ; RV32IZFINX-NEXT: feq.s a3, a1, a1
139 ; RV32IZFINX-NEXT: bnez a3, .LBB1_2
140 ; RV32IZFINX-NEXT: .LBB1_4:
141 ; RV32IZFINX-NEXT: fmax.s a0, a1, a2
142 ; RV32IZFINX-NEXT: ret
144 ; RV64IF-LABEL: fmaximum_f32:
146 ; RV64IF-NEXT: feq.s a0, fa0, fa0
147 ; RV64IF-NEXT: fmv.s fa5, fa1
148 ; RV64IF-NEXT: beqz a0, .LBB1_3
149 ; RV64IF-NEXT: # %bb.1:
150 ; RV64IF-NEXT: feq.s a0, fa1, fa1
151 ; RV64IF-NEXT: beqz a0, .LBB1_4
152 ; RV64IF-NEXT: .LBB1_2:
153 ; RV64IF-NEXT: fmax.s fa0, fa0, fa5
155 ; RV64IF-NEXT: .LBB1_3:
156 ; RV64IF-NEXT: fmv.s fa5, fa0
157 ; RV64IF-NEXT: feq.s a0, fa1, fa1
158 ; RV64IF-NEXT: bnez a0, .LBB1_2
159 ; RV64IF-NEXT: .LBB1_4:
160 ; RV64IF-NEXT: fmax.s fa0, fa1, fa5
163 ; RV64IZFINX-LABEL: fmaximum_f32:
164 ; RV64IZFINX: # %bb.0:
165 ; RV64IZFINX-NEXT: feq.s a3, a0, a0
166 ; RV64IZFINX-NEXT: mv a2, a1
167 ; RV64IZFINX-NEXT: beqz a3, .LBB1_3
168 ; RV64IZFINX-NEXT: # %bb.1:
169 ; RV64IZFINX-NEXT: feq.s a3, a1, a1
170 ; RV64IZFINX-NEXT: beqz a3, .LBB1_4
171 ; RV64IZFINX-NEXT: .LBB1_2:
172 ; RV64IZFINX-NEXT: fmax.s a0, a0, a2
173 ; RV64IZFINX-NEXT: ret
174 ; RV64IZFINX-NEXT: .LBB1_3:
175 ; RV64IZFINX-NEXT: mv a2, a0
176 ; RV64IZFINX-NEXT: feq.s a3, a1, a1
177 ; RV64IZFINX-NEXT: bnez a3, .LBB1_2
178 ; RV64IZFINX-NEXT: .LBB1_4:
179 ; RV64IZFINX-NEXT: fmax.s a0, a1, a2
180 ; RV64IZFINX-NEXT: ret
181 %1 = call float @llvm.maximum.f32(float %a, float %b)
185 define float @fminimum_nnan_f32(float %a, float %b) nounwind {
186 ; RV32IF-LABEL: fminimum_nnan_f32:
188 ; RV32IF-NEXT: fmin.s fa0, fa0, fa1
191 ; RV32IZFINX-LABEL: fminimum_nnan_f32:
192 ; RV32IZFINX: # %bb.0:
193 ; RV32IZFINX-NEXT: fmin.s a0, a0, a1
194 ; RV32IZFINX-NEXT: ret
196 ; RV64IF-LABEL: fminimum_nnan_f32:
198 ; RV64IF-NEXT: fmin.s fa0, fa0, fa1
201 ; RV64IZFINX-LABEL: fminimum_nnan_f32:
202 ; RV64IZFINX: # %bb.0:
203 ; RV64IZFINX-NEXT: fmin.s a0, a0, a1
204 ; RV64IZFINX-NEXT: ret
205 %1 = call nnan float @llvm.minimum.f32(float %a, float %b)
209 define float @fmaximum_nnan_f32(float %a, float %b) nounwind {
210 ; RV32IF-LABEL: fmaximum_nnan_f32:
212 ; RV32IF-NEXT: fmax.s fa0, fa0, fa1
215 ; RV32IZFINX-LABEL: fmaximum_nnan_f32:
216 ; RV32IZFINX: # %bb.0:
217 ; RV32IZFINX-NEXT: fmax.s a0, a0, a1
218 ; RV32IZFINX-NEXT: ret
220 ; RV64IF-LABEL: fmaximum_nnan_f32:
222 ; RV64IF-NEXT: fmax.s fa0, fa0, fa1
225 ; RV64IZFINX-LABEL: fmaximum_nnan_f32:
226 ; RV64IZFINX: # %bb.0:
227 ; RV64IZFINX-NEXT: fmax.s a0, a0, a1
228 ; RV64IZFINX-NEXT: ret
229 %1 = call nnan float @llvm.maximum.f32(float %a, float %b)
233 define float @fminimum_nnan_attr_f32(float %a, float %b) nounwind "no-nans-fp-math"="true" {
234 ; RV32IF-LABEL: fminimum_nnan_attr_f32:
236 ; RV32IF-NEXT: fmin.s fa0, fa0, fa1
239 ; RV32IZFINX-LABEL: fminimum_nnan_attr_f32:
240 ; RV32IZFINX: # %bb.0:
241 ; RV32IZFINX-NEXT: fmin.s a0, a0, a1
242 ; RV32IZFINX-NEXT: ret
244 ; RV64IF-LABEL: fminimum_nnan_attr_f32:
246 ; RV64IF-NEXT: fmin.s fa0, fa0, fa1
249 ; RV64IZFINX-LABEL: fminimum_nnan_attr_f32:
250 ; RV64IZFINX: # %bb.0:
251 ; RV64IZFINX-NEXT: fmin.s a0, a0, a1
252 ; RV64IZFINX-NEXT: ret
253 %1 = call float @llvm.minimum.f32(float %a, float %b)
257 define float @fminimum_nnan_op_f32(float %a, float %b) nounwind {
258 ; RV32IF-LABEL: fminimum_nnan_op_f32:
260 ; RV32IF-NEXT: feq.s a0, fa0, fa0
261 ; RV32IF-NEXT: bnez a0, .LBB5_2
262 ; RV32IF-NEXT: # %bb.1:
263 ; RV32IF-NEXT: fmin.s fa0, fa0, fa0
265 ; RV32IF-NEXT: .LBB5_2:
266 ; RV32IF-NEXT: fadd.s fa5, fa0, fa0
267 ; RV32IF-NEXT: fmin.s fa0, fa0, fa5
270 ; RV32IZFINX-LABEL: fminimum_nnan_op_f32:
271 ; RV32IZFINX: # %bb.0:
272 ; RV32IZFINX-NEXT: feq.s a1, a0, a0
273 ; RV32IZFINX-NEXT: bnez a1, .LBB5_2
274 ; RV32IZFINX-NEXT: # %bb.1:
275 ; RV32IZFINX-NEXT: fmin.s a0, a0, a0
276 ; RV32IZFINX-NEXT: ret
277 ; RV32IZFINX-NEXT: .LBB5_2:
278 ; RV32IZFINX-NEXT: fadd.s a1, a0, a0
279 ; RV32IZFINX-NEXT: fmin.s a0, a0, a1
280 ; RV32IZFINX-NEXT: ret
282 ; RV64IF-LABEL: fminimum_nnan_op_f32:
284 ; RV64IF-NEXT: feq.s a0, fa0, fa0
285 ; RV64IF-NEXT: bnez a0, .LBB5_2
286 ; RV64IF-NEXT: # %bb.1:
287 ; RV64IF-NEXT: fmin.s fa0, fa0, fa0
289 ; RV64IF-NEXT: .LBB5_2:
290 ; RV64IF-NEXT: fadd.s fa5, fa0, fa0
291 ; RV64IF-NEXT: fmin.s fa0, fa0, fa5
294 ; RV64IZFINX-LABEL: fminimum_nnan_op_f32:
295 ; RV64IZFINX: # %bb.0:
296 ; RV64IZFINX-NEXT: feq.s a1, a0, a0
297 ; RV64IZFINX-NEXT: bnez a1, .LBB5_2
298 ; RV64IZFINX-NEXT: # %bb.1:
299 ; RV64IZFINX-NEXT: fmin.s a0, a0, a0
300 ; RV64IZFINX-NEXT: ret
301 ; RV64IZFINX-NEXT: .LBB5_2:
302 ; RV64IZFINX-NEXT: fadd.s a1, a0, a0
303 ; RV64IZFINX-NEXT: fmin.s a0, a0, a1
304 ; RV64IZFINX-NEXT: ret
305 %c = fadd nnan float %a, %a
306 %1 = call float @llvm.minimum.f32(float %a, float %c)
310 define float @fmaximum_nnan_op_f32(float %a, float %b) nounwind {
311 ; RV32IF-LABEL: fmaximum_nnan_op_f32:
313 ; RV32IF-NEXT: fadd.s fa5, fa0, fa1
314 ; RV32IF-NEXT: fsub.s fa4, fa0, fa1
315 ; RV32IF-NEXT: fmax.s fa0, fa5, fa4
318 ; RV32IZFINX-LABEL: fmaximum_nnan_op_f32:
319 ; RV32IZFINX: # %bb.0:
320 ; RV32IZFINX-NEXT: fadd.s a2, a0, a1
321 ; RV32IZFINX-NEXT: fsub.s a0, a0, a1
322 ; RV32IZFINX-NEXT: fmax.s a0, a2, a0
323 ; RV32IZFINX-NEXT: ret
325 ; RV64IF-LABEL: fmaximum_nnan_op_f32:
327 ; RV64IF-NEXT: fadd.s fa5, fa0, fa1
328 ; RV64IF-NEXT: fsub.s fa4, fa0, fa1
329 ; RV64IF-NEXT: fmax.s fa0, fa5, fa4
332 ; RV64IZFINX-LABEL: fmaximum_nnan_op_f32:
333 ; RV64IZFINX: # %bb.0:
334 ; RV64IZFINX-NEXT: fadd.s a2, a0, a1
335 ; RV64IZFINX-NEXT: fsub.s a0, a0, a1
336 ; RV64IZFINX-NEXT: fmax.s a0, a2, a0
337 ; RV64IZFINX-NEXT: ret
338 %c = fadd nnan float %a, %b
339 %d = fsub nnan float %a, %b
340 %1 = call float @llvm.maximum.f32(float %c, float %d)