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 ; TODO: feq.s+sltiu+bne sequence could be optimised
169 ; RV32IF-LABEL: select_fcmp_one:
171 ; RV32IF-NEXT: fmv.w.x ft0, a0
172 ; RV32IF-NEXT: fmv.w.x ft1, a1
173 ; RV32IF-NEXT: feq.s a0, ft1, ft1
174 ; RV32IF-NEXT: feq.s a1, ft0, ft0
175 ; RV32IF-NEXT: and a0, a1, a0
176 ; RV32IF-NEXT: feq.s a1, ft0, ft1
177 ; RV32IF-NEXT: not a1, a1
178 ; RV32IF-NEXT: and a0, a1, a0
179 ; RV32IF-NEXT: bnez a0, .LBB6_2
180 ; RV32IF-NEXT: # %bb.1:
181 ; RV32IF-NEXT: fmv.s ft0, ft1
182 ; RV32IF-NEXT: .LBB6_2:
183 ; RV32IF-NEXT: fmv.x.w a0, ft0
186 ; RV64IF-LABEL: select_fcmp_one:
188 ; RV64IF-NEXT: fmv.w.x ft0, a0
189 ; RV64IF-NEXT: fmv.w.x ft1, a1
190 ; RV64IF-NEXT: feq.s a0, ft1, ft1
191 ; RV64IF-NEXT: feq.s a1, ft0, ft0
192 ; RV64IF-NEXT: and a0, a1, a0
193 ; RV64IF-NEXT: feq.s a1, ft0, ft1
194 ; RV64IF-NEXT: not a1, a1
195 ; RV64IF-NEXT: and a0, a1, a0
196 ; RV64IF-NEXT: bnez a0, .LBB6_2
197 ; RV64IF-NEXT: # %bb.1:
198 ; RV64IF-NEXT: fmv.s ft0, ft1
199 ; RV64IF-NEXT: .LBB6_2:
200 ; RV64IF-NEXT: fmv.x.w a0, ft0
202 %1 = fcmp one float %a, %b
203 %2 = select i1 %1, float %a, float %b
207 define float @select_fcmp_ord(float %a, float %b) nounwind {
208 ; RV32IF-LABEL: select_fcmp_ord:
210 ; RV32IF-NEXT: fmv.w.x ft0, a0
211 ; RV32IF-NEXT: fmv.w.x ft1, a1
212 ; RV32IF-NEXT: feq.s a0, ft1, ft1
213 ; RV32IF-NEXT: feq.s a1, ft0, ft0
214 ; RV32IF-NEXT: and a0, a1, a0
215 ; RV32IF-NEXT: bnez a0, .LBB7_2
216 ; RV32IF-NEXT: # %bb.1:
217 ; RV32IF-NEXT: fmv.s ft0, ft1
218 ; RV32IF-NEXT: .LBB7_2:
219 ; RV32IF-NEXT: fmv.x.w a0, ft0
222 ; RV64IF-LABEL: select_fcmp_ord:
224 ; RV64IF-NEXT: fmv.w.x ft0, a0
225 ; RV64IF-NEXT: fmv.w.x ft1, a1
226 ; RV64IF-NEXT: feq.s a0, ft1, ft1
227 ; RV64IF-NEXT: feq.s a1, ft0, ft0
228 ; RV64IF-NEXT: and a0, a1, a0
229 ; RV64IF-NEXT: bnez a0, .LBB7_2
230 ; RV64IF-NEXT: # %bb.1:
231 ; RV64IF-NEXT: fmv.s ft0, ft1
232 ; RV64IF-NEXT: .LBB7_2:
233 ; RV64IF-NEXT: fmv.x.w a0, ft0
235 %1 = fcmp ord float %a, %b
236 %2 = select i1 %1, float %a, float %b
240 define float @select_fcmp_ueq(float %a, float %b) nounwind {
241 ; RV32IF-LABEL: select_fcmp_ueq:
243 ; RV32IF-NEXT: fmv.w.x ft1, a1
244 ; RV32IF-NEXT: fmv.w.x ft0, a0
245 ; RV32IF-NEXT: feq.s a0, ft0, ft1
246 ; RV32IF-NEXT: feq.s a1, ft1, ft1
247 ; RV32IF-NEXT: feq.s a2, ft0, ft0
248 ; RV32IF-NEXT: and a1, a2, a1
249 ; RV32IF-NEXT: seqz a1, a1
250 ; RV32IF-NEXT: or a0, a0, a1
251 ; RV32IF-NEXT: bnez a0, .LBB8_2
252 ; RV32IF-NEXT: # %bb.1:
253 ; RV32IF-NEXT: fmv.s ft0, ft1
254 ; RV32IF-NEXT: .LBB8_2:
255 ; RV32IF-NEXT: fmv.x.w a0, ft0
258 ; RV64IF-LABEL: select_fcmp_ueq:
260 ; RV64IF-NEXT: fmv.w.x ft1, a1
261 ; RV64IF-NEXT: fmv.w.x ft0, a0
262 ; RV64IF-NEXT: feq.s a0, ft0, ft1
263 ; RV64IF-NEXT: feq.s a1, ft1, ft1
264 ; RV64IF-NEXT: feq.s a2, ft0, ft0
265 ; RV64IF-NEXT: and a1, a2, a1
266 ; RV64IF-NEXT: seqz a1, a1
267 ; RV64IF-NEXT: or a0, a0, a1
268 ; RV64IF-NEXT: bnez a0, .LBB8_2
269 ; RV64IF-NEXT: # %bb.1:
270 ; RV64IF-NEXT: fmv.s ft0, ft1
271 ; RV64IF-NEXT: .LBB8_2:
272 ; RV64IF-NEXT: fmv.x.w a0, ft0
274 %1 = fcmp ueq float %a, %b
275 %2 = select i1 %1, float %a, float %b
279 define float @select_fcmp_ugt(float %a, float %b) nounwind {
280 ; RV32IF-LABEL: select_fcmp_ugt:
282 ; RV32IF-NEXT: fmv.w.x ft1, a1
283 ; RV32IF-NEXT: fmv.w.x ft0, a0
284 ; RV32IF-NEXT: fle.s a0, ft0, ft1
285 ; RV32IF-NEXT: xori a0, a0, 1
286 ; RV32IF-NEXT: bnez a0, .LBB9_2
287 ; RV32IF-NEXT: # %bb.1:
288 ; RV32IF-NEXT: fmv.s ft0, ft1
289 ; RV32IF-NEXT: .LBB9_2:
290 ; RV32IF-NEXT: fmv.x.w a0, ft0
293 ; RV64IF-LABEL: select_fcmp_ugt:
295 ; RV64IF-NEXT: fmv.w.x ft1, a1
296 ; RV64IF-NEXT: fmv.w.x ft0, a0
297 ; RV64IF-NEXT: fle.s a0, ft0, ft1
298 ; RV64IF-NEXT: xori a0, a0, 1
299 ; RV64IF-NEXT: bnez a0, .LBB9_2
300 ; RV64IF-NEXT: # %bb.1:
301 ; RV64IF-NEXT: fmv.s ft0, ft1
302 ; RV64IF-NEXT: .LBB9_2:
303 ; RV64IF-NEXT: fmv.x.w a0, ft0
305 %1 = fcmp ugt float %a, %b
306 %2 = select i1 %1, float %a, float %b
310 define float @select_fcmp_uge(float %a, float %b) nounwind {
311 ; RV32IF-LABEL: select_fcmp_uge:
313 ; RV32IF-NEXT: fmv.w.x ft1, a1
314 ; RV32IF-NEXT: fmv.w.x ft0, a0
315 ; RV32IF-NEXT: flt.s a0, ft0, ft1
316 ; RV32IF-NEXT: xori a0, a0, 1
317 ; RV32IF-NEXT: bnez a0, .LBB10_2
318 ; RV32IF-NEXT: # %bb.1:
319 ; RV32IF-NEXT: fmv.s ft0, ft1
320 ; RV32IF-NEXT: .LBB10_2:
321 ; RV32IF-NEXT: fmv.x.w a0, ft0
324 ; RV64IF-LABEL: select_fcmp_uge:
326 ; RV64IF-NEXT: fmv.w.x ft1, a1
327 ; RV64IF-NEXT: fmv.w.x ft0, a0
328 ; RV64IF-NEXT: flt.s a0, ft0, ft1
329 ; RV64IF-NEXT: xori a0, a0, 1
330 ; RV64IF-NEXT: bnez a0, .LBB10_2
331 ; RV64IF-NEXT: # %bb.1:
332 ; RV64IF-NEXT: fmv.s ft0, ft1
333 ; RV64IF-NEXT: .LBB10_2:
334 ; RV64IF-NEXT: fmv.x.w a0, ft0
336 %1 = fcmp uge float %a, %b
337 %2 = select i1 %1, float %a, float %b
341 define float @select_fcmp_ult(float %a, float %b) nounwind {
342 ; RV32IF-LABEL: select_fcmp_ult:
344 ; RV32IF-NEXT: fmv.w.x ft0, a0
345 ; RV32IF-NEXT: fmv.w.x ft1, a1
346 ; RV32IF-NEXT: fle.s a0, ft1, ft0
347 ; RV32IF-NEXT: xori a0, a0, 1
348 ; RV32IF-NEXT: bnez a0, .LBB11_2
349 ; RV32IF-NEXT: # %bb.1:
350 ; RV32IF-NEXT: fmv.s ft0, ft1
351 ; RV32IF-NEXT: .LBB11_2:
352 ; RV32IF-NEXT: fmv.x.w a0, ft0
355 ; RV64IF-LABEL: select_fcmp_ult:
357 ; RV64IF-NEXT: fmv.w.x ft0, a0
358 ; RV64IF-NEXT: fmv.w.x ft1, a1
359 ; RV64IF-NEXT: fle.s a0, ft1, ft0
360 ; RV64IF-NEXT: xori a0, a0, 1
361 ; RV64IF-NEXT: bnez a0, .LBB11_2
362 ; RV64IF-NEXT: # %bb.1:
363 ; RV64IF-NEXT: fmv.s ft0, ft1
364 ; RV64IF-NEXT: .LBB11_2:
365 ; RV64IF-NEXT: fmv.x.w a0, ft0
367 %1 = fcmp ult float %a, %b
368 %2 = select i1 %1, float %a, float %b
372 define float @select_fcmp_ule(float %a, float %b) nounwind {
373 ; RV32IF-LABEL: select_fcmp_ule:
375 ; RV32IF-NEXT: fmv.w.x ft0, a0
376 ; RV32IF-NEXT: fmv.w.x ft1, a1
377 ; RV32IF-NEXT: flt.s a0, ft1, ft0
378 ; RV32IF-NEXT: xori a0, a0, 1
379 ; RV32IF-NEXT: bnez a0, .LBB12_2
380 ; RV32IF-NEXT: # %bb.1:
381 ; RV32IF-NEXT: fmv.s ft0, ft1
382 ; RV32IF-NEXT: .LBB12_2:
383 ; RV32IF-NEXT: fmv.x.w a0, ft0
386 ; RV64IF-LABEL: select_fcmp_ule:
388 ; RV64IF-NEXT: fmv.w.x ft0, a0
389 ; RV64IF-NEXT: fmv.w.x ft1, a1
390 ; RV64IF-NEXT: flt.s a0, ft1, ft0
391 ; RV64IF-NEXT: xori a0, a0, 1
392 ; RV64IF-NEXT: bnez a0, .LBB12_2
393 ; RV64IF-NEXT: # %bb.1:
394 ; RV64IF-NEXT: fmv.s ft0, ft1
395 ; RV64IF-NEXT: .LBB12_2:
396 ; RV64IF-NEXT: fmv.x.w a0, ft0
398 %1 = fcmp ule float %a, %b
399 %2 = select i1 %1, float %a, float %b
403 define float @select_fcmp_une(float %a, float %b) nounwind {
404 ; RV32IF-LABEL: select_fcmp_une:
406 ; RV32IF-NEXT: fmv.w.x ft1, a1
407 ; RV32IF-NEXT: fmv.w.x ft0, a0
408 ; RV32IF-NEXT: feq.s a0, ft0, ft1
409 ; RV32IF-NEXT: xori a0, a0, 1
410 ; RV32IF-NEXT: bnez a0, .LBB13_2
411 ; RV32IF-NEXT: # %bb.1:
412 ; RV32IF-NEXT: fmv.s ft0, ft1
413 ; RV32IF-NEXT: .LBB13_2:
414 ; RV32IF-NEXT: fmv.x.w a0, ft0
417 ; RV64IF-LABEL: select_fcmp_une:
419 ; RV64IF-NEXT: fmv.w.x ft1, a1
420 ; RV64IF-NEXT: fmv.w.x ft0, a0
421 ; RV64IF-NEXT: feq.s a0, ft0, ft1
422 ; RV64IF-NEXT: xori a0, a0, 1
423 ; RV64IF-NEXT: bnez a0, .LBB13_2
424 ; RV64IF-NEXT: # %bb.1:
425 ; RV64IF-NEXT: fmv.s ft0, ft1
426 ; RV64IF-NEXT: .LBB13_2:
427 ; RV64IF-NEXT: fmv.x.w a0, ft0
429 %1 = fcmp une float %a, %b
430 %2 = select i1 %1, float %a, float %b
434 define float @select_fcmp_uno(float %a, float %b) nounwind {
435 ; TODO: sltiu+bne could be optimized
436 ; RV32IF-LABEL: select_fcmp_uno:
438 ; RV32IF-NEXT: fmv.w.x ft0, a0
439 ; RV32IF-NEXT: fmv.w.x ft1, a1
440 ; RV32IF-NEXT: feq.s a0, ft1, ft1
441 ; RV32IF-NEXT: feq.s a1, ft0, ft0
442 ; RV32IF-NEXT: and a0, a1, a0
443 ; RV32IF-NEXT: seqz a0, a0
444 ; RV32IF-NEXT: bnez a0, .LBB14_2
445 ; RV32IF-NEXT: # %bb.1:
446 ; RV32IF-NEXT: fmv.s ft0, ft1
447 ; RV32IF-NEXT: .LBB14_2:
448 ; RV32IF-NEXT: fmv.x.w a0, ft0
451 ; RV64IF-LABEL: select_fcmp_uno:
453 ; RV64IF-NEXT: fmv.w.x ft0, a0
454 ; RV64IF-NEXT: fmv.w.x ft1, a1
455 ; RV64IF-NEXT: feq.s a0, ft1, ft1
456 ; RV64IF-NEXT: feq.s a1, ft0, ft0
457 ; RV64IF-NEXT: and a0, a1, a0
458 ; RV64IF-NEXT: seqz a0, a0
459 ; RV64IF-NEXT: bnez a0, .LBB14_2
460 ; RV64IF-NEXT: # %bb.1:
461 ; RV64IF-NEXT: fmv.s ft0, ft1
462 ; RV64IF-NEXT: .LBB14_2:
463 ; RV64IF-NEXT: fmv.x.w a0, ft0
465 %1 = fcmp uno float %a, %b
466 %2 = select i1 %1, float %a, float %b
470 define float @select_fcmp_true(float %a, float %b) nounwind {
471 ; RV32IF-LABEL: select_fcmp_true:
475 ; RV64IF-LABEL: select_fcmp_true:
478 %1 = fcmp true float %a, %b
479 %2 = select i1 %1, float %a, float %b
483 ; Ensure that ISel succeeds for a select+fcmp that has an i32 result type.
484 define i32 @i32_select_fcmp_oeq(float %a, float %b, i32 %c, i32 %d) nounwind {
485 ; RV32IF-LABEL: i32_select_fcmp_oeq:
487 ; RV32IF-NEXT: fmv.w.x ft0, a1
488 ; RV32IF-NEXT: fmv.w.x ft1, a0
489 ; RV32IF-NEXT: feq.s a1, ft1, ft0
490 ; RV32IF-NEXT: mv a0, a2
491 ; RV32IF-NEXT: bnez a1, .LBB16_2
492 ; RV32IF-NEXT: # %bb.1:
493 ; RV32IF-NEXT: mv a0, a3
494 ; RV32IF-NEXT: .LBB16_2:
497 ; RV64IF-LABEL: i32_select_fcmp_oeq:
499 ; RV64IF-NEXT: fmv.w.x ft0, a1
500 ; RV64IF-NEXT: fmv.w.x ft1, a0
501 ; RV64IF-NEXT: feq.s a1, ft1, ft0
502 ; RV64IF-NEXT: mv a0, a2
503 ; RV64IF-NEXT: bnez a1, .LBB16_2
504 ; RV64IF-NEXT: # %bb.1:
505 ; RV64IF-NEXT: mv a0, a3
506 ; RV64IF-NEXT: .LBB16_2:
508 %1 = fcmp oeq float %a, %b
509 %2 = select i1 %1, i32 %c, i32 %d