[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / RISCV / double-fcmp.ll
blob28875226abb4b0ac94484c2626e29c7bcd2a7680
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
3 ; RUN:   | FileCheck -check-prefix=RV32IFD %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck -check-prefix=RV64IFD %s
7 define i32 @fcmp_false(double %a, double %b) nounwind {
8 ; RV32IFD-LABEL: fcmp_false:
9 ; RV32IFD:       # %bb.0:
10 ; RV32IFD-NEXT:    mv a0, zero
11 ; RV32IFD-NEXT:    ret
13 ; RV64IFD-LABEL: fcmp_false:
14 ; RV64IFD:       # %bb.0:
15 ; RV64IFD-NEXT:    mv a0, zero
16 ; RV64IFD-NEXT:    ret
17   %1 = fcmp false double %a, %b
18   %2 = zext i1 %1 to i32
19   ret i32 %2
22 define i32 @fcmp_oeq(double %a, double %b) nounwind {
23 ; RV32IFD-LABEL: fcmp_oeq:
24 ; RV32IFD:       # %bb.0:
25 ; RV32IFD-NEXT:    addi sp, sp, -16
26 ; RV32IFD-NEXT:    sw a2, 8(sp)
27 ; RV32IFD-NEXT:    sw a3, 12(sp)
28 ; RV32IFD-NEXT:    fld ft0, 8(sp)
29 ; RV32IFD-NEXT:    sw a0, 8(sp)
30 ; RV32IFD-NEXT:    sw a1, 12(sp)
31 ; RV32IFD-NEXT:    fld ft1, 8(sp)
32 ; RV32IFD-NEXT:    feq.d a0, ft1, ft0
33 ; RV32IFD-NEXT:    addi sp, sp, 16
34 ; RV32IFD-NEXT:    ret
36 ; RV64IFD-LABEL: fcmp_oeq:
37 ; RV64IFD:       # %bb.0:
38 ; RV64IFD-NEXT:    fmv.d.x ft0, a1
39 ; RV64IFD-NEXT:    fmv.d.x ft1, a0
40 ; RV64IFD-NEXT:    feq.d a0, ft1, ft0
41 ; RV64IFD-NEXT:    ret
42   %1 = fcmp oeq double %a, %b
43   %2 = zext i1 %1 to i32
44   ret i32 %2
47 define i32 @fcmp_ogt(double %a, double %b) nounwind {
48 ; RV32IFD-LABEL: fcmp_ogt:
49 ; RV32IFD:       # %bb.0:
50 ; RV32IFD-NEXT:    addi sp, sp, -16
51 ; RV32IFD-NEXT:    sw a0, 8(sp)
52 ; RV32IFD-NEXT:    sw a1, 12(sp)
53 ; RV32IFD-NEXT:    fld ft0, 8(sp)
54 ; RV32IFD-NEXT:    sw a2, 8(sp)
55 ; RV32IFD-NEXT:    sw a3, 12(sp)
56 ; RV32IFD-NEXT:    fld ft1, 8(sp)
57 ; RV32IFD-NEXT:    flt.d a0, ft1, ft0
58 ; RV32IFD-NEXT:    addi sp, sp, 16
59 ; RV32IFD-NEXT:    ret
61 ; RV64IFD-LABEL: fcmp_ogt:
62 ; RV64IFD:       # %bb.0:
63 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
64 ; RV64IFD-NEXT:    fmv.d.x ft1, a1
65 ; RV64IFD-NEXT:    flt.d a0, ft1, ft0
66 ; RV64IFD-NEXT:    ret
67   %1 = fcmp ogt double %a, %b
68   %2 = zext i1 %1 to i32
69   ret i32 %2
72 define i32 @fcmp_oge(double %a, double %b) nounwind {
73 ; RV32IFD-LABEL: fcmp_oge:
74 ; RV32IFD:       # %bb.0:
75 ; RV32IFD-NEXT:    addi sp, sp, -16
76 ; RV32IFD-NEXT:    sw a0, 8(sp)
77 ; RV32IFD-NEXT:    sw a1, 12(sp)
78 ; RV32IFD-NEXT:    fld ft0, 8(sp)
79 ; RV32IFD-NEXT:    sw a2, 8(sp)
80 ; RV32IFD-NEXT:    sw a3, 12(sp)
81 ; RV32IFD-NEXT:    fld ft1, 8(sp)
82 ; RV32IFD-NEXT:    fle.d a0, ft1, ft0
83 ; RV32IFD-NEXT:    addi sp, sp, 16
84 ; RV32IFD-NEXT:    ret
86 ; RV64IFD-LABEL: fcmp_oge:
87 ; RV64IFD:       # %bb.0:
88 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
89 ; RV64IFD-NEXT:    fmv.d.x ft1, a1
90 ; RV64IFD-NEXT:    fle.d a0, ft1, ft0
91 ; RV64IFD-NEXT:    ret
92   %1 = fcmp oge double %a, %b
93   %2 = zext i1 %1 to i32
94   ret i32 %2
97 define i32 @fcmp_olt(double %a, double %b) nounwind {
98 ; RV32IFD-LABEL: fcmp_olt:
99 ; RV32IFD:       # %bb.0:
100 ; RV32IFD-NEXT:    addi sp, sp, -16
101 ; RV32IFD-NEXT:    sw a2, 8(sp)
102 ; RV32IFD-NEXT:    sw a3, 12(sp)
103 ; RV32IFD-NEXT:    fld ft0, 8(sp)
104 ; RV32IFD-NEXT:    sw a0, 8(sp)
105 ; RV32IFD-NEXT:    sw a1, 12(sp)
106 ; RV32IFD-NEXT:    fld ft1, 8(sp)
107 ; RV32IFD-NEXT:    flt.d a0, ft1, ft0
108 ; RV32IFD-NEXT:    addi sp, sp, 16
109 ; RV32IFD-NEXT:    ret
111 ; RV64IFD-LABEL: fcmp_olt:
112 ; RV64IFD:       # %bb.0:
113 ; RV64IFD-NEXT:    fmv.d.x ft0, a1
114 ; RV64IFD-NEXT:    fmv.d.x ft1, a0
115 ; RV64IFD-NEXT:    flt.d a0, ft1, ft0
116 ; RV64IFD-NEXT:    ret
117   %1 = fcmp olt double %a, %b
118   %2 = zext i1 %1 to i32
119   ret i32 %2
122 define i32 @fcmp_ole(double %a, double %b) nounwind {
123 ; RV32IFD-LABEL: fcmp_ole:
124 ; RV32IFD:       # %bb.0:
125 ; RV32IFD-NEXT:    addi sp, sp, -16
126 ; RV32IFD-NEXT:    sw a2, 8(sp)
127 ; RV32IFD-NEXT:    sw a3, 12(sp)
128 ; RV32IFD-NEXT:    fld ft0, 8(sp)
129 ; RV32IFD-NEXT:    sw a0, 8(sp)
130 ; RV32IFD-NEXT:    sw a1, 12(sp)
131 ; RV32IFD-NEXT:    fld ft1, 8(sp)
132 ; RV32IFD-NEXT:    fle.d a0, ft1, ft0
133 ; RV32IFD-NEXT:    addi sp, sp, 16
134 ; RV32IFD-NEXT:    ret
136 ; RV64IFD-LABEL: fcmp_ole:
137 ; RV64IFD:       # %bb.0:
138 ; RV64IFD-NEXT:    fmv.d.x ft0, a1
139 ; RV64IFD-NEXT:    fmv.d.x ft1, a0
140 ; RV64IFD-NEXT:    fle.d a0, ft1, ft0
141 ; RV64IFD-NEXT:    ret
142   %1 = fcmp ole double %a, %b
143   %2 = zext i1 %1 to i32
144   ret i32 %2
147 define i32 @fcmp_one(double %a, double %b) nounwind {
148 ; RV32IFD-LABEL: fcmp_one:
149 ; RV32IFD:       # %bb.0:
150 ; RV32IFD-NEXT:    addi sp, sp, -16
151 ; RV32IFD-NEXT:    sw a0, 8(sp)
152 ; RV32IFD-NEXT:    sw a1, 12(sp)
153 ; RV32IFD-NEXT:    fld ft0, 8(sp)
154 ; RV32IFD-NEXT:    sw a2, 8(sp)
155 ; RV32IFD-NEXT:    sw a3, 12(sp)
156 ; RV32IFD-NEXT:    fld ft1, 8(sp)
157 ; RV32IFD-NEXT:    feq.d a0, ft1, ft1
158 ; RV32IFD-NEXT:    feq.d a1, ft0, ft0
159 ; RV32IFD-NEXT:    and a0, a1, a0
160 ; RV32IFD-NEXT:    feq.d a1, ft0, ft1
161 ; RV32IFD-NEXT:    not a1, a1
162 ; RV32IFD-NEXT:    and a0, a1, a0
163 ; RV32IFD-NEXT:    addi sp, sp, 16
164 ; RV32IFD-NEXT:    ret
166 ; RV64IFD-LABEL: fcmp_one:
167 ; RV64IFD:       # %bb.0:
168 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
169 ; RV64IFD-NEXT:    fmv.d.x ft1, a1
170 ; RV64IFD-NEXT:    feq.d a0, ft1, ft1
171 ; RV64IFD-NEXT:    feq.d a1, ft0, ft0
172 ; RV64IFD-NEXT:    and a0, a1, a0
173 ; RV64IFD-NEXT:    feq.d a1, ft0, ft1
174 ; RV64IFD-NEXT:    not a1, a1
175 ; RV64IFD-NEXT:    and a0, a1, a0
176 ; RV64IFD-NEXT:    ret
177   %1 = fcmp one double %a, %b
178   %2 = zext i1 %1 to i32
179   ret i32 %2
182 define i32 @fcmp_ord(double %a, double %b) nounwind {
183 ; RV32IFD-LABEL: fcmp_ord:
184 ; RV32IFD:       # %bb.0:
185 ; RV32IFD-NEXT:    addi sp, sp, -16
186 ; RV32IFD-NEXT:    sw a0, 8(sp)
187 ; RV32IFD-NEXT:    sw a1, 12(sp)
188 ; RV32IFD-NEXT:    fld ft0, 8(sp)
189 ; RV32IFD-NEXT:    sw a2, 8(sp)
190 ; RV32IFD-NEXT:    sw a3, 12(sp)
191 ; RV32IFD-NEXT:    fld ft1, 8(sp)
192 ; RV32IFD-NEXT:    feq.d a0, ft1, ft1
193 ; RV32IFD-NEXT:    feq.d a1, ft0, ft0
194 ; RV32IFD-NEXT:    and a0, a1, a0
195 ; RV32IFD-NEXT:    addi sp, sp, 16
196 ; RV32IFD-NEXT:    ret
198 ; RV64IFD-LABEL: fcmp_ord:
199 ; RV64IFD:       # %bb.0:
200 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
201 ; RV64IFD-NEXT:    fmv.d.x ft1, a1
202 ; RV64IFD-NEXT:    feq.d a0, ft1, ft1
203 ; RV64IFD-NEXT:    feq.d a1, ft0, ft0
204 ; RV64IFD-NEXT:    and a0, a1, a0
205 ; RV64IFD-NEXT:    ret
206   %1 = fcmp ord double %a, %b
207   %2 = zext i1 %1 to i32
208   ret i32 %2
211 define i32 @fcmp_ueq(double %a, double %b) nounwind {
212 ; RV32IFD-LABEL: fcmp_ueq:
213 ; RV32IFD:       # %bb.0:
214 ; RV32IFD-NEXT:    addi sp, sp, -16
215 ; RV32IFD-NEXT:    sw a2, 8(sp)
216 ; RV32IFD-NEXT:    sw a3, 12(sp)
217 ; RV32IFD-NEXT:    fld ft0, 8(sp)
218 ; RV32IFD-NEXT:    sw a0, 8(sp)
219 ; RV32IFD-NEXT:    sw a1, 12(sp)
220 ; RV32IFD-NEXT:    fld ft1, 8(sp)
221 ; RV32IFD-NEXT:    feq.d a0, ft1, ft0
222 ; RV32IFD-NEXT:    feq.d a1, ft0, ft0
223 ; RV32IFD-NEXT:    feq.d a2, ft1, ft1
224 ; RV32IFD-NEXT:    and a1, a2, a1
225 ; RV32IFD-NEXT:    seqz a1, a1
226 ; RV32IFD-NEXT:    or a0, a0, a1
227 ; RV32IFD-NEXT:    addi sp, sp, 16
228 ; RV32IFD-NEXT:    ret
230 ; RV64IFD-LABEL: fcmp_ueq:
231 ; RV64IFD:       # %bb.0:
232 ; RV64IFD-NEXT:    fmv.d.x ft0, a1
233 ; RV64IFD-NEXT:    fmv.d.x ft1, a0
234 ; RV64IFD-NEXT:    feq.d a0, ft1, ft0
235 ; RV64IFD-NEXT:    feq.d a1, ft0, ft0
236 ; RV64IFD-NEXT:    feq.d a2, ft1, ft1
237 ; RV64IFD-NEXT:    and a1, a2, a1
238 ; RV64IFD-NEXT:    seqz a1, a1
239 ; RV64IFD-NEXT:    or a0, a0, a1
240 ; RV64IFD-NEXT:    ret
241   %1 = fcmp ueq double %a, %b
242   %2 = zext i1 %1 to i32
243   ret i32 %2
246 define i32 @fcmp_ugt(double %a, double %b) nounwind {
247 ; RV32IFD-LABEL: fcmp_ugt:
248 ; RV32IFD:       # %bb.0:
249 ; RV32IFD-NEXT:    addi sp, sp, -16
250 ; RV32IFD-NEXT:    sw a2, 8(sp)
251 ; RV32IFD-NEXT:    sw a3, 12(sp)
252 ; RV32IFD-NEXT:    fld ft0, 8(sp)
253 ; RV32IFD-NEXT:    sw a0, 8(sp)
254 ; RV32IFD-NEXT:    sw a1, 12(sp)
255 ; RV32IFD-NEXT:    fld ft1, 8(sp)
256 ; RV32IFD-NEXT:    fle.d a0, ft1, ft0
257 ; RV32IFD-NEXT:    xori a0, a0, 1
258 ; RV32IFD-NEXT:    addi sp, sp, 16
259 ; RV32IFD-NEXT:    ret
261 ; RV64IFD-LABEL: fcmp_ugt:
262 ; RV64IFD:       # %bb.0:
263 ; RV64IFD-NEXT:    fmv.d.x ft0, a1
264 ; RV64IFD-NEXT:    fmv.d.x ft1, a0
265 ; RV64IFD-NEXT:    fle.d a0, ft1, ft0
266 ; RV64IFD-NEXT:    xori a0, a0, 1
267 ; RV64IFD-NEXT:    ret
268   %1 = fcmp ugt double %a, %b
269   %2 = zext i1 %1 to i32
270   ret i32 %2
273 define i32 @fcmp_uge(double %a, double %b) nounwind {
274 ; RV32IFD-LABEL: fcmp_uge:
275 ; RV32IFD:       # %bb.0:
276 ; RV32IFD-NEXT:    addi sp, sp, -16
277 ; RV32IFD-NEXT:    sw a2, 8(sp)
278 ; RV32IFD-NEXT:    sw a3, 12(sp)
279 ; RV32IFD-NEXT:    fld ft0, 8(sp)
280 ; RV32IFD-NEXT:    sw a0, 8(sp)
281 ; RV32IFD-NEXT:    sw a1, 12(sp)
282 ; RV32IFD-NEXT:    fld ft1, 8(sp)
283 ; RV32IFD-NEXT:    flt.d a0, ft1, ft0
284 ; RV32IFD-NEXT:    xori a0, a0, 1
285 ; RV32IFD-NEXT:    addi sp, sp, 16
286 ; RV32IFD-NEXT:    ret
288 ; RV64IFD-LABEL: fcmp_uge:
289 ; RV64IFD:       # %bb.0:
290 ; RV64IFD-NEXT:    fmv.d.x ft0, a1
291 ; RV64IFD-NEXT:    fmv.d.x ft1, a0
292 ; RV64IFD-NEXT:    flt.d a0, ft1, ft0
293 ; RV64IFD-NEXT:    xori a0, a0, 1
294 ; RV64IFD-NEXT:    ret
295   %1 = fcmp uge double %a, %b
296   %2 = zext i1 %1 to i32
297   ret i32 %2
300 define i32 @fcmp_ult(double %a, double %b) nounwind {
301 ; RV32IFD-LABEL: fcmp_ult:
302 ; RV32IFD:       # %bb.0:
303 ; RV32IFD-NEXT:    addi sp, sp, -16
304 ; RV32IFD-NEXT:    sw a0, 8(sp)
305 ; RV32IFD-NEXT:    sw a1, 12(sp)
306 ; RV32IFD-NEXT:    fld ft0, 8(sp)
307 ; RV32IFD-NEXT:    sw a2, 8(sp)
308 ; RV32IFD-NEXT:    sw a3, 12(sp)
309 ; RV32IFD-NEXT:    fld ft1, 8(sp)
310 ; RV32IFD-NEXT:    fle.d a0, ft1, ft0
311 ; RV32IFD-NEXT:    xori a0, a0, 1
312 ; RV32IFD-NEXT:    addi sp, sp, 16
313 ; RV32IFD-NEXT:    ret
315 ; RV64IFD-LABEL: fcmp_ult:
316 ; RV64IFD:       # %bb.0:
317 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
318 ; RV64IFD-NEXT:    fmv.d.x ft1, a1
319 ; RV64IFD-NEXT:    fle.d a0, ft1, ft0
320 ; RV64IFD-NEXT:    xori a0, a0, 1
321 ; RV64IFD-NEXT:    ret
322   %1 = fcmp ult double %a, %b
323   %2 = zext i1 %1 to i32
324   ret i32 %2
327 define i32 @fcmp_ule(double %a, double %b) nounwind {
328 ; RV32IFD-LABEL: fcmp_ule:
329 ; RV32IFD:       # %bb.0:
330 ; RV32IFD-NEXT:    addi sp, sp, -16
331 ; RV32IFD-NEXT:    sw a0, 8(sp)
332 ; RV32IFD-NEXT:    sw a1, 12(sp)
333 ; RV32IFD-NEXT:    fld ft0, 8(sp)
334 ; RV32IFD-NEXT:    sw a2, 8(sp)
335 ; RV32IFD-NEXT:    sw a3, 12(sp)
336 ; RV32IFD-NEXT:    fld ft1, 8(sp)
337 ; RV32IFD-NEXT:    flt.d a0, ft1, ft0
338 ; RV32IFD-NEXT:    xori a0, a0, 1
339 ; RV32IFD-NEXT:    addi sp, sp, 16
340 ; RV32IFD-NEXT:    ret
342 ; RV64IFD-LABEL: fcmp_ule:
343 ; RV64IFD:       # %bb.0:
344 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
345 ; RV64IFD-NEXT:    fmv.d.x ft1, a1
346 ; RV64IFD-NEXT:    flt.d a0, ft1, ft0
347 ; RV64IFD-NEXT:    xori a0, a0, 1
348 ; RV64IFD-NEXT:    ret
349   %1 = fcmp ule double %a, %b
350   %2 = zext i1 %1 to i32
351   ret i32 %2
354 define i32 @fcmp_une(double %a, double %b) nounwind {
355 ; RV32IFD-LABEL: fcmp_une:
356 ; RV32IFD:       # %bb.0:
357 ; RV32IFD-NEXT:    addi sp, sp, -16
358 ; RV32IFD-NEXT:    sw a2, 8(sp)
359 ; RV32IFD-NEXT:    sw a3, 12(sp)
360 ; RV32IFD-NEXT:    fld ft0, 8(sp)
361 ; RV32IFD-NEXT:    sw a0, 8(sp)
362 ; RV32IFD-NEXT:    sw a1, 12(sp)
363 ; RV32IFD-NEXT:    fld ft1, 8(sp)
364 ; RV32IFD-NEXT:    feq.d a0, ft1, ft0
365 ; RV32IFD-NEXT:    xori a0, a0, 1
366 ; RV32IFD-NEXT:    addi sp, sp, 16
367 ; RV32IFD-NEXT:    ret
369 ; RV64IFD-LABEL: fcmp_une:
370 ; RV64IFD:       # %bb.0:
371 ; RV64IFD-NEXT:    fmv.d.x ft0, a1
372 ; RV64IFD-NEXT:    fmv.d.x ft1, a0
373 ; RV64IFD-NEXT:    feq.d a0, ft1, ft0
374 ; RV64IFD-NEXT:    xori a0, a0, 1
375 ; RV64IFD-NEXT:    ret
376   %1 = fcmp une double %a, %b
377   %2 = zext i1 %1 to i32
378   ret i32 %2
381 define i32 @fcmp_uno(double %a, double %b) nounwind {
382 ; RV32IFD-LABEL: fcmp_uno:
383 ; RV32IFD:       # %bb.0:
384 ; RV32IFD-NEXT:    addi sp, sp, -16
385 ; RV32IFD-NEXT:    sw a0, 8(sp)
386 ; RV32IFD-NEXT:    sw a1, 12(sp)
387 ; RV32IFD-NEXT:    fld ft0, 8(sp)
388 ; RV32IFD-NEXT:    sw a2, 8(sp)
389 ; RV32IFD-NEXT:    sw a3, 12(sp)
390 ; RV32IFD-NEXT:    fld ft1, 8(sp)
391 ; RV32IFD-NEXT:    feq.d a0, ft1, ft1
392 ; RV32IFD-NEXT:    feq.d a1, ft0, ft0
393 ; RV32IFD-NEXT:    and a0, a1, a0
394 ; RV32IFD-NEXT:    seqz a0, a0
395 ; RV32IFD-NEXT:    addi sp, sp, 16
396 ; RV32IFD-NEXT:    ret
398 ; RV64IFD-LABEL: fcmp_uno:
399 ; RV64IFD:       # %bb.0:
400 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
401 ; RV64IFD-NEXT:    fmv.d.x ft1, a1
402 ; RV64IFD-NEXT:    feq.d a0, ft1, ft1
403 ; RV64IFD-NEXT:    feq.d a1, ft0, ft0
404 ; RV64IFD-NEXT:    and a0, a1, a0
405 ; RV64IFD-NEXT:    seqz a0, a0
406 ; RV64IFD-NEXT:    ret
407   %1 = fcmp uno double %a, %b
408   %2 = zext i1 %1 to i32
409   ret i32 %2
412 define i32 @fcmp_true(double %a, double %b) nounwind {
413 ; RV32IFD-LABEL: fcmp_true:
414 ; RV32IFD:       # %bb.0:
415 ; RV32IFD-NEXT:    addi a0, zero, 1
416 ; RV32IFD-NEXT:    ret
418 ; RV64IFD-LABEL: fcmp_true:
419 ; RV64IFD:       # %bb.0:
420 ; RV64IFD-NEXT:    addi a0, zero, 1
421 ; RV64IFD-NEXT:    ret
422   %1 = fcmp true double %a, %b
423   %2 = zext i1 %1 to i32
424   ret i32 %2