1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
3 ; RUN: | FileCheck -check-prefix=RV32IF %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
5 ; RUN: | FileCheck -check-prefix=RV64IF %s
7 define float @select_fcmp_false(float %a, float %b) nounwind {
8 ; RV32IF-LABEL: select_fcmp_false:
10 ; RV32IF-NEXT: mv a0, a1
13 ; RV64IF-LABEL: select_fcmp_false:
15 ; RV64IF-NEXT: mv a0, a1
17 %1 = fcmp false float %a, %b
18 %2 = select i1 %1, float %a, float %b
22 define float @select_fcmp_oeq(float %a, float %b) nounwind {
23 ; RV32IF-LABEL: select_fcmp_oeq:
25 ; RV32IF-NEXT: fmv.w.x ft1, a1
26 ; RV32IF-NEXT: fmv.w.x ft0, a0
27 ; RV32IF-NEXT: feq.s a0, ft0, ft1
28 ; RV32IF-NEXT: bnez a0, .LBB1_2
29 ; RV32IF-NEXT: # %bb.1:
30 ; RV32IF-NEXT: fmv.s ft0, ft1
31 ; RV32IF-NEXT: .LBB1_2:
32 ; RV32IF-NEXT: fmv.x.w a0, ft0
35 ; RV64IF-LABEL: select_fcmp_oeq:
37 ; RV64IF-NEXT: fmv.w.x ft1, a1
38 ; RV64IF-NEXT: fmv.w.x ft0, a0
39 ; RV64IF-NEXT: feq.s a0, ft0, ft1
40 ; RV64IF-NEXT: bnez a0, .LBB1_2
41 ; RV64IF-NEXT: # %bb.1:
42 ; RV64IF-NEXT: fmv.s ft0, ft1
43 ; RV64IF-NEXT: .LBB1_2:
44 ; RV64IF-NEXT: fmv.x.w a0, ft0
46 %1 = fcmp oeq float %a, %b
47 %2 = select i1 %1, float %a, float %b
51 define float @select_fcmp_ogt(float %a, float %b) nounwind {
52 ; RV32IF-LABEL: select_fcmp_ogt:
54 ; RV32IF-NEXT: fmv.w.x ft0, a0
55 ; RV32IF-NEXT: fmv.w.x ft1, a1
56 ; RV32IF-NEXT: flt.s a0, ft1, ft0
57 ; RV32IF-NEXT: bnez a0, .LBB2_2
58 ; RV32IF-NEXT: # %bb.1:
59 ; RV32IF-NEXT: fmv.s ft0, ft1
60 ; RV32IF-NEXT: .LBB2_2:
61 ; RV32IF-NEXT: fmv.x.w a0, ft0
64 ; RV64IF-LABEL: select_fcmp_ogt:
66 ; RV64IF-NEXT: fmv.w.x ft0, a0
67 ; RV64IF-NEXT: fmv.w.x ft1, a1
68 ; RV64IF-NEXT: flt.s a0, ft1, ft0
69 ; RV64IF-NEXT: bnez a0, .LBB2_2
70 ; RV64IF-NEXT: # %bb.1:
71 ; RV64IF-NEXT: fmv.s ft0, ft1
72 ; RV64IF-NEXT: .LBB2_2:
73 ; RV64IF-NEXT: fmv.x.w a0, ft0
75 %1 = fcmp ogt float %a, %b
76 %2 = select i1 %1, float %a, float %b
80 define float @select_fcmp_oge(float %a, float %b) nounwind {
81 ; RV32IF-LABEL: select_fcmp_oge:
83 ; RV32IF-NEXT: fmv.w.x ft0, a0
84 ; RV32IF-NEXT: fmv.w.x ft1, a1
85 ; RV32IF-NEXT: fle.s a0, ft1, ft0
86 ; RV32IF-NEXT: bnez a0, .LBB3_2
87 ; RV32IF-NEXT: # %bb.1:
88 ; RV32IF-NEXT: fmv.s ft0, ft1
89 ; RV32IF-NEXT: .LBB3_2:
90 ; RV32IF-NEXT: fmv.x.w a0, ft0
93 ; RV64IF-LABEL: select_fcmp_oge:
95 ; RV64IF-NEXT: fmv.w.x ft0, a0
96 ; RV64IF-NEXT: fmv.w.x ft1, a1
97 ; RV64IF-NEXT: fle.s a0, ft1, ft0
98 ; RV64IF-NEXT: bnez a0, .LBB3_2
99 ; RV64IF-NEXT: # %bb.1:
100 ; RV64IF-NEXT: fmv.s ft0, ft1
101 ; RV64IF-NEXT: .LBB3_2:
102 ; RV64IF-NEXT: fmv.x.w a0, ft0
104 %1 = fcmp oge float %a, %b
105 %2 = select i1 %1, float %a, float %b
109 define float @select_fcmp_olt(float %a, float %b) nounwind {
110 ; RV32IF-LABEL: select_fcmp_olt:
112 ; RV32IF-NEXT: fmv.w.x ft1, a1
113 ; RV32IF-NEXT: fmv.w.x ft0, a0
114 ; RV32IF-NEXT: flt.s a0, ft0, ft1
115 ; RV32IF-NEXT: bnez a0, .LBB4_2
116 ; RV32IF-NEXT: # %bb.1:
117 ; RV32IF-NEXT: fmv.s ft0, ft1
118 ; RV32IF-NEXT: .LBB4_2:
119 ; RV32IF-NEXT: fmv.x.w a0, ft0
122 ; RV64IF-LABEL: select_fcmp_olt:
124 ; RV64IF-NEXT: fmv.w.x ft1, a1
125 ; RV64IF-NEXT: fmv.w.x ft0, a0
126 ; RV64IF-NEXT: flt.s a0, ft0, ft1
127 ; RV64IF-NEXT: bnez a0, .LBB4_2
128 ; RV64IF-NEXT: # %bb.1:
129 ; RV64IF-NEXT: fmv.s ft0, ft1
130 ; RV64IF-NEXT: .LBB4_2:
131 ; RV64IF-NEXT: fmv.x.w a0, ft0
133 %1 = fcmp olt float %a, %b
134 %2 = select i1 %1, float %a, float %b
138 define float @select_fcmp_ole(float %a, float %b) nounwind {
139 ; RV32IF-LABEL: select_fcmp_ole:
141 ; RV32IF-NEXT: fmv.w.x ft1, a1
142 ; RV32IF-NEXT: fmv.w.x ft0, a0
143 ; RV32IF-NEXT: fle.s a0, ft0, ft1
144 ; RV32IF-NEXT: bnez a0, .LBB5_2
145 ; RV32IF-NEXT: # %bb.1:
146 ; RV32IF-NEXT: fmv.s ft0, ft1
147 ; RV32IF-NEXT: .LBB5_2:
148 ; RV32IF-NEXT: fmv.x.w a0, ft0
151 ; RV64IF-LABEL: select_fcmp_ole:
153 ; RV64IF-NEXT: fmv.w.x ft1, a1
154 ; RV64IF-NEXT: fmv.w.x ft0, a0
155 ; RV64IF-NEXT: fle.s a0, ft0, ft1
156 ; RV64IF-NEXT: bnez a0, .LBB5_2
157 ; RV64IF-NEXT: # %bb.1:
158 ; RV64IF-NEXT: fmv.s ft0, ft1
159 ; RV64IF-NEXT: .LBB5_2:
160 ; RV64IF-NEXT: fmv.x.w a0, ft0
162 %1 = fcmp ole float %a, %b
163 %2 = select i1 %1, float %a, float %b
167 define float @select_fcmp_one(float %a, float %b) nounwind {
168 ; RV32IF-LABEL: select_fcmp_one:
170 ; RV32IF-NEXT: fmv.w.x ft1, a1
171 ; RV32IF-NEXT: fmv.w.x ft0, a0
172 ; RV32IF-NEXT: flt.s a0, ft0, ft1
173 ; RV32IF-NEXT: flt.s a1, ft1, ft0
174 ; RV32IF-NEXT: or a0, a1, a0
175 ; RV32IF-NEXT: bnez a0, .LBB6_2
176 ; RV32IF-NEXT: # %bb.1:
177 ; RV32IF-NEXT: fmv.s ft0, ft1
178 ; RV32IF-NEXT: .LBB6_2:
179 ; RV32IF-NEXT: fmv.x.w a0, ft0
182 ; RV64IF-LABEL: select_fcmp_one:
184 ; RV64IF-NEXT: fmv.w.x ft1, a1
185 ; RV64IF-NEXT: fmv.w.x ft0, a0
186 ; RV64IF-NEXT: flt.s a0, ft0, ft1
187 ; RV64IF-NEXT: flt.s a1, ft1, ft0
188 ; RV64IF-NEXT: or a0, a1, a0
189 ; RV64IF-NEXT: bnez a0, .LBB6_2
190 ; RV64IF-NEXT: # %bb.1:
191 ; RV64IF-NEXT: fmv.s ft0, ft1
192 ; RV64IF-NEXT: .LBB6_2:
193 ; RV64IF-NEXT: fmv.x.w a0, ft0
195 %1 = fcmp one float %a, %b
196 %2 = select i1 %1, float %a, float %b
200 define float @select_fcmp_ord(float %a, float %b) nounwind {
201 ; RV32IF-LABEL: select_fcmp_ord:
203 ; RV32IF-NEXT: fmv.w.x ft0, a0
204 ; RV32IF-NEXT: fmv.w.x ft1, a1
205 ; RV32IF-NEXT: feq.s a0, ft1, ft1
206 ; RV32IF-NEXT: feq.s a1, ft0, ft0
207 ; RV32IF-NEXT: and a0, a1, a0
208 ; RV32IF-NEXT: bnez a0, .LBB7_2
209 ; RV32IF-NEXT: # %bb.1:
210 ; RV32IF-NEXT: fmv.s ft0, ft1
211 ; RV32IF-NEXT: .LBB7_2:
212 ; RV32IF-NEXT: fmv.x.w a0, ft0
215 ; RV64IF-LABEL: select_fcmp_ord:
217 ; RV64IF-NEXT: fmv.w.x ft0, a0
218 ; RV64IF-NEXT: fmv.w.x ft1, a1
219 ; RV64IF-NEXT: feq.s a0, ft1, ft1
220 ; RV64IF-NEXT: feq.s a1, ft0, ft0
221 ; RV64IF-NEXT: and a0, a1, a0
222 ; RV64IF-NEXT: bnez a0, .LBB7_2
223 ; RV64IF-NEXT: # %bb.1:
224 ; RV64IF-NEXT: fmv.s ft0, ft1
225 ; RV64IF-NEXT: .LBB7_2:
226 ; RV64IF-NEXT: fmv.x.w a0, ft0
228 %1 = fcmp ord float %a, %b
229 %2 = select i1 %1, float %a, float %b
233 define float @select_fcmp_ueq(float %a, float %b) nounwind {
234 ; RV32IF-LABEL: select_fcmp_ueq:
236 ; RV32IF-NEXT: fmv.w.x ft1, a1
237 ; RV32IF-NEXT: fmv.w.x ft0, a0
238 ; RV32IF-NEXT: flt.s a0, ft0, ft1
239 ; RV32IF-NEXT: flt.s a1, ft1, ft0
240 ; RV32IF-NEXT: or a0, a1, a0
241 ; RV32IF-NEXT: beqz a0, .LBB8_2
242 ; RV32IF-NEXT: # %bb.1:
243 ; RV32IF-NEXT: fmv.s ft0, ft1
244 ; RV32IF-NEXT: .LBB8_2:
245 ; RV32IF-NEXT: fmv.x.w a0, ft0
248 ; RV64IF-LABEL: select_fcmp_ueq:
250 ; RV64IF-NEXT: fmv.w.x ft1, a1
251 ; RV64IF-NEXT: fmv.w.x ft0, a0
252 ; RV64IF-NEXT: flt.s a0, ft0, ft1
253 ; RV64IF-NEXT: flt.s a1, ft1, ft0
254 ; RV64IF-NEXT: or a0, a1, a0
255 ; RV64IF-NEXT: beqz a0, .LBB8_2
256 ; RV64IF-NEXT: # %bb.1:
257 ; RV64IF-NEXT: fmv.s ft0, ft1
258 ; RV64IF-NEXT: .LBB8_2:
259 ; RV64IF-NEXT: fmv.x.w a0, ft0
261 %1 = fcmp ueq float %a, %b
262 %2 = select i1 %1, float %a, float %b
266 define float @select_fcmp_ugt(float %a, float %b) nounwind {
267 ; RV32IF-LABEL: select_fcmp_ugt:
269 ; RV32IF-NEXT: fmv.w.x ft1, a1
270 ; RV32IF-NEXT: fmv.w.x ft0, a0
271 ; RV32IF-NEXT: fle.s a0, ft0, ft1
272 ; RV32IF-NEXT: beqz a0, .LBB9_2
273 ; RV32IF-NEXT: # %bb.1:
274 ; RV32IF-NEXT: fmv.s ft0, ft1
275 ; RV32IF-NEXT: .LBB9_2:
276 ; RV32IF-NEXT: fmv.x.w a0, ft0
279 ; RV64IF-LABEL: select_fcmp_ugt:
281 ; RV64IF-NEXT: fmv.w.x ft1, a1
282 ; RV64IF-NEXT: fmv.w.x ft0, a0
283 ; RV64IF-NEXT: fle.s a0, ft0, ft1
284 ; RV64IF-NEXT: beqz a0, .LBB9_2
285 ; RV64IF-NEXT: # %bb.1:
286 ; RV64IF-NEXT: fmv.s ft0, ft1
287 ; RV64IF-NEXT: .LBB9_2:
288 ; RV64IF-NEXT: fmv.x.w a0, ft0
290 %1 = fcmp ugt float %a, %b
291 %2 = select i1 %1, float %a, float %b
295 define float @select_fcmp_uge(float %a, float %b) nounwind {
296 ; RV32IF-LABEL: select_fcmp_uge:
298 ; RV32IF-NEXT: fmv.w.x ft1, a1
299 ; RV32IF-NEXT: fmv.w.x ft0, a0
300 ; RV32IF-NEXT: flt.s a0, ft0, ft1
301 ; RV32IF-NEXT: beqz a0, .LBB10_2
302 ; RV32IF-NEXT: # %bb.1:
303 ; RV32IF-NEXT: fmv.s ft0, ft1
304 ; RV32IF-NEXT: .LBB10_2:
305 ; RV32IF-NEXT: fmv.x.w a0, ft0
308 ; RV64IF-LABEL: select_fcmp_uge:
310 ; RV64IF-NEXT: fmv.w.x ft1, a1
311 ; RV64IF-NEXT: fmv.w.x ft0, a0
312 ; RV64IF-NEXT: flt.s a0, ft0, ft1
313 ; RV64IF-NEXT: beqz a0, .LBB10_2
314 ; RV64IF-NEXT: # %bb.1:
315 ; RV64IF-NEXT: fmv.s ft0, ft1
316 ; RV64IF-NEXT: .LBB10_2:
317 ; RV64IF-NEXT: fmv.x.w a0, ft0
319 %1 = fcmp uge float %a, %b
320 %2 = select i1 %1, float %a, float %b
324 define float @select_fcmp_ult(float %a, float %b) nounwind {
325 ; RV32IF-LABEL: select_fcmp_ult:
327 ; RV32IF-NEXT: fmv.w.x ft0, a0
328 ; RV32IF-NEXT: fmv.w.x ft1, a1
329 ; RV32IF-NEXT: fle.s a0, ft1, ft0
330 ; RV32IF-NEXT: beqz a0, .LBB11_2
331 ; RV32IF-NEXT: # %bb.1:
332 ; RV32IF-NEXT: fmv.s ft0, ft1
333 ; RV32IF-NEXT: .LBB11_2:
334 ; RV32IF-NEXT: fmv.x.w a0, ft0
337 ; RV64IF-LABEL: select_fcmp_ult:
339 ; RV64IF-NEXT: fmv.w.x ft0, a0
340 ; RV64IF-NEXT: fmv.w.x ft1, a1
341 ; RV64IF-NEXT: fle.s a0, ft1, ft0
342 ; RV64IF-NEXT: beqz a0, .LBB11_2
343 ; RV64IF-NEXT: # %bb.1:
344 ; RV64IF-NEXT: fmv.s ft0, ft1
345 ; RV64IF-NEXT: .LBB11_2:
346 ; RV64IF-NEXT: fmv.x.w a0, ft0
348 %1 = fcmp ult float %a, %b
349 %2 = select i1 %1, float %a, float %b
353 define float @select_fcmp_ule(float %a, float %b) nounwind {
354 ; RV32IF-LABEL: select_fcmp_ule:
356 ; RV32IF-NEXT: fmv.w.x ft0, a0
357 ; RV32IF-NEXT: fmv.w.x ft1, a1
358 ; RV32IF-NEXT: flt.s a0, ft1, ft0
359 ; RV32IF-NEXT: beqz a0, .LBB12_2
360 ; RV32IF-NEXT: # %bb.1:
361 ; RV32IF-NEXT: fmv.s ft0, ft1
362 ; RV32IF-NEXT: .LBB12_2:
363 ; RV32IF-NEXT: fmv.x.w a0, ft0
366 ; RV64IF-LABEL: select_fcmp_ule:
368 ; RV64IF-NEXT: fmv.w.x ft0, a0
369 ; RV64IF-NEXT: fmv.w.x ft1, a1
370 ; RV64IF-NEXT: flt.s a0, ft1, ft0
371 ; RV64IF-NEXT: beqz a0, .LBB12_2
372 ; RV64IF-NEXT: # %bb.1:
373 ; RV64IF-NEXT: fmv.s ft0, ft1
374 ; RV64IF-NEXT: .LBB12_2:
375 ; RV64IF-NEXT: fmv.x.w a0, ft0
377 %1 = fcmp ule float %a, %b
378 %2 = select i1 %1, float %a, float %b
382 define float @select_fcmp_une(float %a, float %b) nounwind {
383 ; RV32IF-LABEL: select_fcmp_une:
385 ; RV32IF-NEXT: fmv.w.x ft1, a1
386 ; RV32IF-NEXT: fmv.w.x ft0, a0
387 ; RV32IF-NEXT: feq.s a0, ft0, ft1
388 ; RV32IF-NEXT: beqz a0, .LBB13_2
389 ; RV32IF-NEXT: # %bb.1:
390 ; RV32IF-NEXT: fmv.s ft0, ft1
391 ; RV32IF-NEXT: .LBB13_2:
392 ; RV32IF-NEXT: fmv.x.w a0, ft0
395 ; RV64IF-LABEL: select_fcmp_une:
397 ; RV64IF-NEXT: fmv.w.x ft1, a1
398 ; RV64IF-NEXT: fmv.w.x ft0, a0
399 ; RV64IF-NEXT: feq.s a0, ft0, ft1
400 ; RV64IF-NEXT: beqz a0, .LBB13_2
401 ; RV64IF-NEXT: # %bb.1:
402 ; RV64IF-NEXT: fmv.s ft0, ft1
403 ; RV64IF-NEXT: .LBB13_2:
404 ; RV64IF-NEXT: fmv.x.w a0, ft0
406 %1 = fcmp une float %a, %b
407 %2 = select i1 %1, float %a, float %b
411 define float @select_fcmp_uno(float %a, float %b) nounwind {
412 ; RV32IF-LABEL: select_fcmp_uno:
414 ; RV32IF-NEXT: fmv.w.x ft0, a0
415 ; RV32IF-NEXT: fmv.w.x ft1, a1
416 ; RV32IF-NEXT: feq.s a0, ft1, ft1
417 ; RV32IF-NEXT: feq.s a1, ft0, ft0
418 ; RV32IF-NEXT: and a0, a1, a0
419 ; RV32IF-NEXT: beqz a0, .LBB14_2
420 ; RV32IF-NEXT: # %bb.1:
421 ; RV32IF-NEXT: fmv.s ft0, ft1
422 ; RV32IF-NEXT: .LBB14_2:
423 ; RV32IF-NEXT: fmv.x.w a0, ft0
426 ; RV64IF-LABEL: select_fcmp_uno:
428 ; RV64IF-NEXT: fmv.w.x ft0, a0
429 ; RV64IF-NEXT: fmv.w.x ft1, a1
430 ; RV64IF-NEXT: feq.s a0, ft1, ft1
431 ; RV64IF-NEXT: feq.s a1, ft0, ft0
432 ; RV64IF-NEXT: and a0, a1, a0
433 ; RV64IF-NEXT: beqz a0, .LBB14_2
434 ; RV64IF-NEXT: # %bb.1:
435 ; RV64IF-NEXT: fmv.s ft0, ft1
436 ; RV64IF-NEXT: .LBB14_2:
437 ; RV64IF-NEXT: fmv.x.w a0, ft0
439 %1 = fcmp uno float %a, %b
440 %2 = select i1 %1, float %a, float %b
444 define float @select_fcmp_true(float %a, float %b) nounwind {
445 ; RV32IF-LABEL: select_fcmp_true:
449 ; RV64IF-LABEL: select_fcmp_true:
452 %1 = fcmp true float %a, %b
453 %2 = select i1 %1, float %a, float %b
457 ; Ensure that ISel succeeds for a select+fcmp that has an i32 result type.
458 define i32 @i32_select_fcmp_oeq(float %a, float %b, i32 %c, i32 %d) nounwind {
459 ; RV32IF-LABEL: i32_select_fcmp_oeq:
461 ; RV32IF-NEXT: fmv.w.x ft0, a1
462 ; RV32IF-NEXT: fmv.w.x ft1, a0
463 ; RV32IF-NEXT: feq.s a1, ft1, ft0
464 ; RV32IF-NEXT: mv a0, a2
465 ; RV32IF-NEXT: bnez a1, .LBB16_2
466 ; RV32IF-NEXT: # %bb.1:
467 ; RV32IF-NEXT: mv a0, a3
468 ; RV32IF-NEXT: .LBB16_2:
471 ; RV64IF-LABEL: i32_select_fcmp_oeq:
473 ; RV64IF-NEXT: fmv.w.x ft0, a1
474 ; RV64IF-NEXT: fmv.w.x ft1, a0
475 ; RV64IF-NEXT: feq.s a1, ft1, ft0
476 ; RV64IF-NEXT: mv a0, a2
477 ; RV64IF-NEXT: bnez a1, .LBB16_2
478 ; RV64IF-NEXT: # %bb.1:
479 ; RV64IF-NEXT: mv a0, a3
480 ; RV64IF-NEXT: .LBB16_2:
482 %1 = fcmp oeq float %a, %b
483 %2 = select i1 %1, i32 %c, i32 %d