Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / X86 / fcmp-logic.ll
blob4953d004e65c578245a0ae4b4844ad047ffdba7a
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-- -mattr=sse2    | FileCheck %s --check-prefixes=SSE2
3 ; RUN: llc < %s -mtriple=x86_64-- -mattr=avx     | FileCheck %s --check-prefixes=AVX,AVX1
4 ; RUN: llc < %s -mtriple=x86_64-- -mattr=avx512f | FileCheck %s --check-prefixes=AVX,AVX512
6 define i1 @olt_ole_and_f32(float %w, float %x, float %y, float %z) {
7 ; SSE2-LABEL: olt_ole_and_f32:
8 ; SSE2:       # %bb.0:
9 ; SSE2-NEXT:    cmpleps %xmm3, %xmm2
10 ; SSE2-NEXT:    cmpltps %xmm1, %xmm0
11 ; SSE2-NEXT:    andps %xmm2, %xmm0
12 ; SSE2-NEXT:    movd %xmm0, %eax
13 ; SSE2-NEXT:    # kill: def $al killed $al killed $eax
14 ; SSE2-NEXT:    retq
16 ; AVX1-LABEL: olt_ole_and_f32:
17 ; AVX1:       # %bb.0:
18 ; AVX1-NEXT:    vcmpleps %xmm3, %xmm2, %xmm2
19 ; AVX1-NEXT:    vcmpltps %xmm1, %xmm0, %xmm0
20 ; AVX1-NEXT:    vandps %xmm2, %xmm0, %xmm0
21 ; AVX1-NEXT:    vmovd %xmm0, %eax
22 ; AVX1-NEXT:    # kill: def $al killed $al killed $eax
23 ; AVX1-NEXT:    retq
25 ; AVX512-LABEL: olt_ole_and_f32:
26 ; AVX512:       # %bb.0:
27 ; AVX512-NEXT:    # kill: def $xmm3 killed $xmm3 def $zmm3
28 ; AVX512-NEXT:    # kill: def $xmm2 killed $xmm2 def $zmm2
29 ; AVX512-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
30 ; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
31 ; AVX512-NEXT:    vcmpltps %zmm1, %zmm0, %k1
32 ; AVX512-NEXT:    vcmpleps %zmm3, %zmm2, %k0 {%k1}
33 ; AVX512-NEXT:    kmovw %k0, %eax
34 ; AVX512-NEXT:    # kill: def $al killed $al killed $eax
35 ; AVX512-NEXT:    vzeroupper
36 ; AVX512-NEXT:    retq
37   %f1 = fcmp olt float %w, %x
38   %f2 = fcmp ole float %y, %z
39   %r = and i1 %f1, %f2
40   ret i1 %r
43 define i1 @oge_oeq_or_f32(float %w, float %x, float %y, float %z) {
44 ; SSE2-LABEL: oge_oeq_or_f32:
45 ; SSE2:       # %bb.0:
46 ; SSE2-NEXT:    cmpeqps %xmm3, %xmm2
47 ; SSE2-NEXT:    cmpleps %xmm0, %xmm1
48 ; SSE2-NEXT:    orps %xmm2, %xmm1
49 ; SSE2-NEXT:    movd %xmm1, %eax
50 ; SSE2-NEXT:    # kill: def $al killed $al killed $eax
51 ; SSE2-NEXT:    retq
53 ; AVX1-LABEL: oge_oeq_or_f32:
54 ; AVX1:       # %bb.0:
55 ; AVX1-NEXT:    vcmpeqps %xmm3, %xmm2, %xmm2
56 ; AVX1-NEXT:    vcmpleps %xmm0, %xmm1, %xmm0
57 ; AVX1-NEXT:    vorps %xmm2, %xmm0, %xmm0
58 ; AVX1-NEXT:    vmovd %xmm0, %eax
59 ; AVX1-NEXT:    # kill: def $al killed $al killed $eax
60 ; AVX1-NEXT:    retq
62 ; AVX512-LABEL: oge_oeq_or_f32:
63 ; AVX512:       # %bb.0:
64 ; AVX512-NEXT:    # kill: def $xmm3 killed $xmm3 def $zmm3
65 ; AVX512-NEXT:    # kill: def $xmm2 killed $xmm2 def $zmm2
66 ; AVX512-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
67 ; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
68 ; AVX512-NEXT:    vcmpeqps %zmm3, %zmm2, %k0
69 ; AVX512-NEXT:    vcmpleps %zmm0, %zmm1, %k1
70 ; AVX512-NEXT:    korw %k0, %k1, %k0
71 ; AVX512-NEXT:    kmovw %k0, %eax
72 ; AVX512-NEXT:    # kill: def $al killed $al killed $eax
73 ; AVX512-NEXT:    vzeroupper
74 ; AVX512-NEXT:    retq
75   %f1 = fcmp oge float %w, %x
76   %f2 = fcmp oeq float %y, %z
77   %r = or i1 %f1, %f2
78   ret i1 %r
81 define i1 @ord_one_xor_f32(float %w, float %x, float %y, float %z) {
82 ; SSE2-LABEL: ord_one_xor_f32:
83 ; SSE2:       # %bb.0:
84 ; SSE2-NEXT:    ucomiss %xmm1, %xmm0
85 ; SSE2-NEXT:    setnp %cl
86 ; SSE2-NEXT:    ucomiss %xmm3, %xmm2
87 ; SSE2-NEXT:    setne %al
88 ; SSE2-NEXT:    xorb %cl, %al
89 ; SSE2-NEXT:    retq
91 ; AVX1-LABEL: ord_one_xor_f32:
92 ; AVX1:       # %bb.0:
93 ; AVX1-NEXT:    vcmpneq_oqps %xmm3, %xmm2, %xmm2
94 ; AVX1-NEXT:    vcmpordps %xmm1, %xmm0, %xmm0
95 ; AVX1-NEXT:    vxorps %xmm2, %xmm0, %xmm0
96 ; AVX1-NEXT:    vmovd %xmm0, %eax
97 ; AVX1-NEXT:    # kill: def $al killed $al killed $eax
98 ; AVX1-NEXT:    retq
100 ; AVX512-LABEL: ord_one_xor_f32:
101 ; AVX512:       # %bb.0:
102 ; AVX512-NEXT:    # kill: def $xmm3 killed $xmm3 def $zmm3
103 ; AVX512-NEXT:    # kill: def $xmm2 killed $xmm2 def $zmm2
104 ; AVX512-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
105 ; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
106 ; AVX512-NEXT:    vcmpneq_oqps %zmm3, %zmm2, %k0
107 ; AVX512-NEXT:    vcmpordps %zmm1, %zmm0, %k1
108 ; AVX512-NEXT:    kxorw %k0, %k1, %k0
109 ; AVX512-NEXT:    kmovw %k0, %eax
110 ; AVX512-NEXT:    # kill: def $al killed $al killed $eax
111 ; AVX512-NEXT:    vzeroupper
112 ; AVX512-NEXT:    retq
113   %f1 = fcmp ord float %w, %x
114   %f2 = fcmp one float %y, %z
115   %r = xor i1 %f1, %f2
116   ret i1 %r
119 ; PR51068
120 define i1 @une_oeq_xor_f32(float %w, float %x, float %y, float %z) {
121 ; SSE2-LABEL: une_oeq_xor_f32:
122 ; SSE2:       # %bb.0:
123 ; SSE2-NEXT:    cmpeqps %xmm3, %xmm2
124 ; SSE2-NEXT:    cmpneqps %xmm1, %xmm0
125 ; SSE2-NEXT:    xorps %xmm2, %xmm0
126 ; SSE2-NEXT:    movd %xmm0, %eax
127 ; SSE2-NEXT:    # kill: def $al killed $al killed $eax
128 ; SSE2-NEXT:    retq
130 ; AVX1-LABEL: une_oeq_xor_f32:
131 ; AVX1:       # %bb.0:
132 ; AVX1-NEXT:    vcmpeqps %xmm3, %xmm2, %xmm2
133 ; AVX1-NEXT:    vcmpneqps %xmm1, %xmm0, %xmm0
134 ; AVX1-NEXT:    vxorps %xmm2, %xmm0, %xmm0
135 ; AVX1-NEXT:    vmovd %xmm0, %eax
136 ; AVX1-NEXT:    # kill: def $al killed $al killed $eax
137 ; AVX1-NEXT:    retq
139 ; AVX512-LABEL: une_oeq_xor_f32:
140 ; AVX512:       # %bb.0:
141 ; AVX512-NEXT:    # kill: def $xmm3 killed $xmm3 def $zmm3
142 ; AVX512-NEXT:    # kill: def $xmm2 killed $xmm2 def $zmm2
143 ; AVX512-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
144 ; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
145 ; AVX512-NEXT:    vcmpeqps %zmm3, %zmm2, %k0
146 ; AVX512-NEXT:    vcmpneqps %zmm1, %zmm0, %k1
147 ; AVX512-NEXT:    kxorw %k0, %k1, %k0
148 ; AVX512-NEXT:    kmovw %k0, %eax
149 ; AVX512-NEXT:    # kill: def $al killed $al killed $eax
150 ; AVX512-NEXT:    vzeroupper
151 ; AVX512-NEXT:    retq
152   %f1 = fcmp une float %w, %x
153   %f2 = fcmp oeq float %y, %z
154   %r = xor i1 %f1, %f2
155   ret i1 %r
158 define i1 @une_ugt_and_f64(double %w, double %x, double %y, double %z) {
159 ; SSE2-LABEL: une_ugt_and_f64:
160 ; SSE2:       # %bb.0:
161 ; SSE2-NEXT:    cmpnlepd %xmm3, %xmm2
162 ; SSE2-NEXT:    cmpneqpd %xmm1, %xmm0
163 ; SSE2-NEXT:    andpd %xmm2, %xmm0
164 ; SSE2-NEXT:    movd %xmm0, %eax
165 ; SSE2-NEXT:    # kill: def $al killed $al killed $eax
166 ; SSE2-NEXT:    retq
168 ; AVX1-LABEL: une_ugt_and_f64:
169 ; AVX1:       # %bb.0:
170 ; AVX1-NEXT:    vcmpnlepd %xmm3, %xmm2, %xmm2
171 ; AVX1-NEXT:    vcmpneqpd %xmm1, %xmm0, %xmm0
172 ; AVX1-NEXT:    vandpd %xmm2, %xmm0, %xmm0
173 ; AVX1-NEXT:    vmovd %xmm0, %eax
174 ; AVX1-NEXT:    # kill: def $al killed $al killed $eax
175 ; AVX1-NEXT:    retq
177 ; AVX512-LABEL: une_ugt_and_f64:
178 ; AVX512:       # %bb.0:
179 ; AVX512-NEXT:    # kill: def $xmm3 killed $xmm3 def $zmm3
180 ; AVX512-NEXT:    # kill: def $xmm2 killed $xmm2 def $zmm2
181 ; AVX512-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
182 ; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
183 ; AVX512-NEXT:    vcmpneqpd %zmm1, %zmm0, %k1
184 ; AVX512-NEXT:    vcmpnlepd %zmm3, %zmm2, %k0 {%k1}
185 ; AVX512-NEXT:    kmovw %k0, %eax
186 ; AVX512-NEXT:    # kill: def $al killed $al killed $eax
187 ; AVX512-NEXT:    vzeroupper
188 ; AVX512-NEXT:    retq
189   %f1 = fcmp une double %w, %x
190   %f2 = fcmp ugt double %y, %z
191   %r = and i1 %f1, %f2
192   ret i1 %r
195 define i1 @ult_uge_or_f64(double %w, double %x, double %y, double %z) {
196 ; SSE2-LABEL: ult_uge_or_f64:
197 ; SSE2:       # %bb.0:
198 ; SSE2-NEXT:    cmpnltpd %xmm3, %xmm2
199 ; SSE2-NEXT:    cmpnlepd %xmm0, %xmm1
200 ; SSE2-NEXT:    orpd %xmm2, %xmm1
201 ; SSE2-NEXT:    movd %xmm1, %eax
202 ; SSE2-NEXT:    # kill: def $al killed $al killed $eax
203 ; SSE2-NEXT:    retq
205 ; AVX1-LABEL: ult_uge_or_f64:
206 ; AVX1:       # %bb.0:
207 ; AVX1-NEXT:    vcmpnltpd %xmm3, %xmm2, %xmm2
208 ; AVX1-NEXT:    vcmpnlepd %xmm0, %xmm1, %xmm0
209 ; AVX1-NEXT:    vorpd %xmm2, %xmm0, %xmm0
210 ; AVX1-NEXT:    vmovd %xmm0, %eax
211 ; AVX1-NEXT:    # kill: def $al killed $al killed $eax
212 ; AVX1-NEXT:    retq
214 ; AVX512-LABEL: ult_uge_or_f64:
215 ; AVX512:       # %bb.0:
216 ; AVX512-NEXT:    # kill: def $xmm3 killed $xmm3 def $zmm3
217 ; AVX512-NEXT:    # kill: def $xmm2 killed $xmm2 def $zmm2
218 ; AVX512-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
219 ; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
220 ; AVX512-NEXT:    vcmpnltpd %zmm3, %zmm2, %k0
221 ; AVX512-NEXT:    vcmpnlepd %zmm0, %zmm1, %k1
222 ; AVX512-NEXT:    korw %k0, %k1, %k0
223 ; AVX512-NEXT:    kmovw %k0, %eax
224 ; AVX512-NEXT:    # kill: def $al killed $al killed $eax
225 ; AVX512-NEXT:    vzeroupper
226 ; AVX512-NEXT:    retq
227   %f1 = fcmp ult double %w, %x
228   %f2 = fcmp uge double %y, %z
229   %r = or i1 %f1, %f2
230   ret i1 %r
233 define i1 @une_uno_xor_f64(double %w, double %x, double %y, double %z) {
234 ; SSE2-LABEL: une_uno_xor_f64:
235 ; SSE2:       # %bb.0:
236 ; SSE2-NEXT:    cmpunordpd %xmm3, %xmm2
237 ; SSE2-NEXT:    cmpneqpd %xmm1, %xmm0
238 ; SSE2-NEXT:    xorpd %xmm2, %xmm0
239 ; SSE2-NEXT:    movd %xmm0, %eax
240 ; SSE2-NEXT:    # kill: def $al killed $al killed $eax
241 ; SSE2-NEXT:    retq
243 ; AVX1-LABEL: une_uno_xor_f64:
244 ; AVX1:       # %bb.0:
245 ; AVX1-NEXT:    vcmpunordpd %xmm3, %xmm2, %xmm2
246 ; AVX1-NEXT:    vcmpneqpd %xmm1, %xmm0, %xmm0
247 ; AVX1-NEXT:    vxorpd %xmm2, %xmm0, %xmm0
248 ; AVX1-NEXT:    vmovd %xmm0, %eax
249 ; AVX1-NEXT:    # kill: def $al killed $al killed $eax
250 ; AVX1-NEXT:    retq
252 ; AVX512-LABEL: une_uno_xor_f64:
253 ; AVX512:       # %bb.0:
254 ; AVX512-NEXT:    # kill: def $xmm3 killed $xmm3 def $zmm3
255 ; AVX512-NEXT:    # kill: def $xmm2 killed $xmm2 def $zmm2
256 ; AVX512-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
257 ; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
258 ; AVX512-NEXT:    vcmpunordpd %zmm3, %zmm2, %k0
259 ; AVX512-NEXT:    vcmpneqpd %zmm1, %zmm0, %k1
260 ; AVX512-NEXT:    kxorw %k0, %k1, %k0
261 ; AVX512-NEXT:    kmovw %k0, %eax
262 ; AVX512-NEXT:    # kill: def $al killed $al killed $eax
263 ; AVX512-NEXT:    vzeroupper
264 ; AVX512-NEXT:    retq
265   %f1 = fcmp une double %w, %x
266   %f2 = fcmp uno double %y, %z
267   %r = xor i1 %f1, %f2
268   ret i1 %r
271 ; This uses ucomis because the types do not match.
272 ; TODO: Merge down to narrow type?
274 define i1 @olt_olt_and_f32_f64(float %w, float %x, double %y, double %z) {
275 ; SSE2-LABEL: olt_olt_and_f32_f64:
276 ; SSE2:       # %bb.0:
277 ; SSE2-NEXT:    ucomiss %xmm0, %xmm1
278 ; SSE2-NEXT:    seta %cl
279 ; SSE2-NEXT:    ucomisd %xmm2, %xmm3
280 ; SSE2-NEXT:    seta %al
281 ; SSE2-NEXT:    andb %cl, %al
282 ; SSE2-NEXT:    retq
284 ; AVX-LABEL: olt_olt_and_f32_f64:
285 ; AVX:       # %bb.0:
286 ; AVX-NEXT:    vucomiss %xmm0, %xmm1
287 ; AVX-NEXT:    seta %cl
288 ; AVX-NEXT:    vucomisd %xmm2, %xmm3
289 ; AVX-NEXT:    seta %al
290 ; AVX-NEXT:    andb %cl, %al
291 ; AVX-NEXT:    retq
292   %f1 = fcmp olt float %w, %x
293   %f2 = fcmp olt double %y, %z
294   %r = and i1 %f1, %f2
295   ret i1 %r
298 ; This uses ucomis because of extra uses.
300 define i1 @une_uno_xor_f64_use1(double %w, double %x, double %y, double %z, ptr %p) {
301 ; SSE2-LABEL: une_uno_xor_f64_use1:
302 ; SSE2:       # %bb.0:
303 ; SSE2-NEXT:    ucomisd %xmm1, %xmm0
304 ; SSE2-NEXT:    setp %al
305 ; SSE2-NEXT:    setne %cl
306 ; SSE2-NEXT:    orb %al, %cl
307 ; SSE2-NEXT:    movb %cl, (%rdi)
308 ; SSE2-NEXT:    ucomisd %xmm3, %xmm2
309 ; SSE2-NEXT:    setp %al
310 ; SSE2-NEXT:    xorb %cl, %al
311 ; SSE2-NEXT:    retq
313 ; AVX-LABEL: une_uno_xor_f64_use1:
314 ; AVX:       # %bb.0:
315 ; AVX-NEXT:    vucomisd %xmm1, %xmm0
316 ; AVX-NEXT:    setp %al
317 ; AVX-NEXT:    setne %cl
318 ; AVX-NEXT:    orb %al, %cl
319 ; AVX-NEXT:    movb %cl, (%rdi)
320 ; AVX-NEXT:    vucomisd %xmm3, %xmm2
321 ; AVX-NEXT:    setp %al
322 ; AVX-NEXT:    xorb %cl, %al
323 ; AVX-NEXT:    retq
324   %f1 = fcmp une double %w, %x
325   store i1 %f1, ptr %p
326   %f2 = fcmp uno double %y, %z
327   %r = xor i1 %f1, %f2
328   ret i1 %r
331 ; This uses ucomis because of extra uses.
333 define i1 @une_uno_xor_f64_use2(double %w, double %x, double %y, double %z, ptr %p) {
334 ; SSE2-LABEL: une_uno_xor_f64_use2:
335 ; SSE2:       # %bb.0:
336 ; SSE2-NEXT:    ucomisd %xmm1, %xmm0
337 ; SSE2-NEXT:    setp %al
338 ; SSE2-NEXT:    setne %cl
339 ; SSE2-NEXT:    orb %al, %cl
340 ; SSE2-NEXT:    ucomisd %xmm3, %xmm2
341 ; SSE2-NEXT:    setp %al
342 ; SSE2-NEXT:    setp (%rdi)
343 ; SSE2-NEXT:    xorb %cl, %al
344 ; SSE2-NEXT:    retq
346 ; AVX-LABEL: une_uno_xor_f64_use2:
347 ; AVX:       # %bb.0:
348 ; AVX-NEXT:    vucomisd %xmm1, %xmm0
349 ; AVX-NEXT:    setp %al
350 ; AVX-NEXT:    setne %cl
351 ; AVX-NEXT:    orb %al, %cl
352 ; AVX-NEXT:    vucomisd %xmm3, %xmm2
353 ; AVX-NEXT:    setp %al
354 ; AVX-NEXT:    setp (%rdi)
355 ; AVX-NEXT:    xorb %cl, %al
356 ; AVX-NEXT:    retq
357   %f1 = fcmp une double %w, %x
358   %f2 = fcmp uno double %y, %z
359   store i1 %f2, ptr %p
360   %r = xor i1 %f1, %f2
361   ret i1 %r
365 ; bool f32cmp3(float x, float y, float z, float w) {
366 ;     return ((x > 0) || (y > 0)) != (z < w);
367 ; }
369 define i1 @f32cmp3(float %x, float %y, float %z, float %w) {
370 ; SSE2-LABEL: f32cmp3:
371 ; SSE2:       # %bb.0:
372 ; SSE2-NEXT:    xorps %xmm4, %xmm4
373 ; SSE2-NEXT:    xorps %xmm5, %xmm5
374 ; SSE2-NEXT:    cmpltps %xmm1, %xmm5
375 ; SSE2-NEXT:    cmpltps %xmm0, %xmm4
376 ; SSE2-NEXT:    orps %xmm5, %xmm4
377 ; SSE2-NEXT:    movd %xmm4, %ecx
378 ; SSE2-NEXT:    ucomiss %xmm2, %xmm3
379 ; SSE2-NEXT:    seta %al
380 ; SSE2-NEXT:    xorb %cl, %al
381 ; SSE2-NEXT:    retq
383 ; AVX1-LABEL: f32cmp3:
384 ; AVX1:       # %bb.0:
385 ; AVX1-NEXT:    vxorps %xmm4, %xmm4, %xmm4
386 ; AVX1-NEXT:    vcmpltps %xmm1, %xmm4, %xmm1
387 ; AVX1-NEXT:    vcmpltps %xmm0, %xmm4, %xmm0
388 ; AVX1-NEXT:    vorps %xmm1, %xmm0, %xmm0
389 ; AVX1-NEXT:    vmovd %xmm0, %ecx
390 ; AVX1-NEXT:    vucomiss %xmm2, %xmm3
391 ; AVX1-NEXT:    seta %al
392 ; AVX1-NEXT:    xorb %cl, %al
393 ; AVX1-NEXT:    retq
395 ; AVX512-LABEL: f32cmp3:
396 ; AVX512:       # %bb.0:
397 ; AVX512-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
398 ; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
399 ; AVX512-NEXT:    vxorps %xmm4, %xmm4, %xmm4
400 ; AVX512-NEXT:    vcmpltps %zmm1, %zmm4, %k0
401 ; AVX512-NEXT:    vcmpltps %zmm0, %zmm4, %k1
402 ; AVX512-NEXT:    korw %k0, %k1, %k0
403 ; AVX512-NEXT:    kmovw %k0, %ecx
404 ; AVX512-NEXT:    vucomiss %xmm2, %xmm3
405 ; AVX512-NEXT:    seta %al
406 ; AVX512-NEXT:    xorb %cl, %al
407 ; AVX512-NEXT:    vzeroupper
408 ; AVX512-NEXT:    retq
409   %cmpx = fcmp ogt float %x, 0.0
410   %cmpy = fcmp ogt float %y, 0.0
411   %or = select i1 %cmpx, i1 true, i1 %cmpy
412   %cmpzw = fcmp olt float %z, %w
413   %r = xor i1 %or, %cmpzw
414   ret i1 %r