[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / X86 / setcc-logic.ll
blob3e7d7d32e0e768c0b832f0923872240fd839e2fa
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=CHECK,NOBMI
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefixes=CHECK,BMI
5 define zeroext i1 @all_bits_clear(i32 %P, i32 %Q) nounwind {
6 ; CHECK-LABEL: all_bits_clear:
7 ; CHECK:       # %bb.0:
8 ; CHECK-NEXT:    orl %esi, %edi
9 ; CHECK-NEXT:    sete %al
10 ; CHECK-NEXT:    retq
11   %a = icmp eq i32 %P, 0
12   %b = icmp eq i32 %Q, 0
13   %c = and i1 %a, %b
14   ret i1 %c
17 define zeroext i1 @all_sign_bits_clear(i32 %P, i32 %Q) nounwind {
18 ; CHECK-LABEL: all_sign_bits_clear:
19 ; CHECK:       # %bb.0:
20 ; CHECK-NEXT:    orl %esi, %edi
21 ; CHECK-NEXT:    setns %al
22 ; CHECK-NEXT:    retq
23   %a = icmp sgt i32 %P, -1
24   %b = icmp sgt i32 %Q, -1
25   %c = and i1 %a, %b
26   ret i1 %c
29 define zeroext i1 @all_bits_set(i32 %P, i32 %Q) nounwind {
30 ; CHECK-LABEL: all_bits_set:
31 ; CHECK:       # %bb.0:
32 ; CHECK-NEXT:    andl %esi, %edi
33 ; CHECK-NEXT:    cmpl $-1, %edi
34 ; CHECK-NEXT:    sete %al
35 ; CHECK-NEXT:    retq
36   %a = icmp eq i32 %P, -1
37   %b = icmp eq i32 %Q, -1
38   %c = and i1 %a, %b
39   ret i1 %c
42 define zeroext i1 @all_sign_bits_set(i32 %P, i32 %Q) nounwind {
43 ; CHECK-LABEL: all_sign_bits_set:
44 ; CHECK:       # %bb.0:
45 ; CHECK-NEXT:    movl %edi, %eax
46 ; CHECK-NEXT:    andl %esi, %eax
47 ; CHECK-NEXT:    shrl $31, %eax
48 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
49 ; CHECK-NEXT:    retq
50   %a = icmp slt i32 %P, 0
51   %b = icmp slt i32 %Q, 0
52   %c = and i1 %a, %b
53   ret i1 %c
56 define zeroext i1 @any_bits_set(i32 %P, i32 %Q) nounwind {
57 ; CHECK-LABEL: any_bits_set:
58 ; CHECK:       # %bb.0:
59 ; CHECK-NEXT:    orl %esi, %edi
60 ; CHECK-NEXT:    setne %al
61 ; CHECK-NEXT:    retq
62   %a = icmp ne i32 %P, 0
63   %b = icmp ne i32 %Q, 0
64   %c = or i1 %a, %b
65   ret i1 %c
68 define zeroext i1 @any_sign_bits_set(i32 %P, i32 %Q) nounwind {
69 ; CHECK-LABEL: any_sign_bits_set:
70 ; CHECK:       # %bb.0:
71 ; CHECK-NEXT:    movl %edi, %eax
72 ; CHECK-NEXT:    orl %esi, %eax
73 ; CHECK-NEXT:    shrl $31, %eax
74 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
75 ; CHECK-NEXT:    retq
76   %a = icmp slt i32 %P, 0
77   %b = icmp slt i32 %Q, 0
78   %c = or i1 %a, %b
79   ret i1 %c
82 define zeroext i1 @any_bits_clear(i32 %P, i32 %Q) nounwind {
83 ; CHECK-LABEL: any_bits_clear:
84 ; CHECK:       # %bb.0:
85 ; CHECK-NEXT:    andl %esi, %edi
86 ; CHECK-NEXT:    cmpl $-1, %edi
87 ; CHECK-NEXT:    setne %al
88 ; CHECK-NEXT:    retq
89   %a = icmp ne i32 %P, -1
90   %b = icmp ne i32 %Q, -1
91   %c = or i1 %a, %b
92   ret i1 %c
95 define zeroext i1 @any_sign_bits_clear(i32 %P, i32 %Q) nounwind {
96 ; CHECK-LABEL: any_sign_bits_clear:
97 ; CHECK:       # %bb.0:
98 ; CHECK-NEXT:    testl %esi, %edi
99 ; CHECK-NEXT:    setns %al
100 ; CHECK-NEXT:    retq
101   %a = icmp sgt i32 %P, -1
102   %b = icmp sgt i32 %Q, -1
103   %c = or i1 %a, %b
104   ret i1 %c
107 ; PR3351 - (P == 0) & (Q == 0) -> (P|Q) == 0
108 define i32 @all_bits_clear_branch(i32* %P, i32* %Q) nounwind {
109 ; CHECK-LABEL: all_bits_clear_branch:
110 ; CHECK:       # %bb.0: # %entry
111 ; CHECK-NEXT:    orq %rsi, %rdi
112 ; CHECK-NEXT:    jne .LBB8_2
113 ; CHECK-NEXT:  # %bb.1: # %bb1
114 ; CHECK-NEXT:    movl $4, %eax
115 ; CHECK-NEXT:    retq
116 ; CHECK-NEXT:  .LBB8_2: # %return
117 ; CHECK-NEXT:    movl $192, %eax
118 ; CHECK-NEXT:    retq
119 entry:
120   %a = icmp eq i32* %P, null
121   %b = icmp eq i32* %Q, null
122   %c = and i1 %a, %b
123   br i1 %c, label %bb1, label %return
125 bb1:
126   ret i32 4
128 return:
129   ret i32 192
132 define i32 @all_sign_bits_clear_branch(i32 %P, i32 %Q) nounwind {
133 ; CHECK-LABEL: all_sign_bits_clear_branch:
134 ; CHECK:       # %bb.0: # %entry
135 ; CHECK-NEXT:    testl %edi, %edi
136 ; CHECK-NEXT:    js .LBB9_3
137 ; CHECK-NEXT:  # %bb.1: # %entry
138 ; CHECK-NEXT:    testl %esi, %esi
139 ; CHECK-NEXT:    js .LBB9_3
140 ; CHECK-NEXT:  # %bb.2: # %bb1
141 ; CHECK-NEXT:    movl $4, %eax
142 ; CHECK-NEXT:    retq
143 ; CHECK-NEXT:  .LBB9_3: # %return
144 ; CHECK-NEXT:    movl $192, %eax
145 ; CHECK-NEXT:    retq
146 entry:
147   %a = icmp sgt i32 %P, -1
148   %b = icmp sgt i32 %Q, -1
149   %c = and i1 %a, %b
150   br i1 %c, label %bb1, label %return
152 bb1:
153   ret i32 4
155 return:
156   ret i32 192
159 define i32 @all_bits_set_branch(i32 %P, i32 %Q) nounwind {
160 ; CHECK-LABEL: all_bits_set_branch:
161 ; CHECK:       # %bb.0: # %entry
162 ; CHECK-NEXT:    cmpl $-1, %edi
163 ; CHECK-NEXT:    jne .LBB10_3
164 ; CHECK-NEXT:  # %bb.1: # %entry
165 ; CHECK-NEXT:    cmpl $-1, %esi
166 ; CHECK-NEXT:    jne .LBB10_3
167 ; CHECK-NEXT:  # %bb.2: # %bb1
168 ; CHECK-NEXT:    movl $4, %eax
169 ; CHECK-NEXT:    retq
170 ; CHECK-NEXT:  .LBB10_3: # %return
171 ; CHECK-NEXT:    movl $192, %eax
172 ; CHECK-NEXT:    retq
173 entry:
174   %a = icmp eq i32 %P, -1
175   %b = icmp eq i32 %Q, -1
176   %c = and i1 %a, %b
177   br i1 %c, label %bb1, label %return
179 bb1:
180   ret i32 4
182 return:
183   ret i32 192
186 define i32 @all_sign_bits_set_branch(i32 %P, i32 %Q) nounwind {
187 ; CHECK-LABEL: all_sign_bits_set_branch:
188 ; CHECK:       # %bb.0: # %entry
189 ; CHECK-NEXT:    testl %edi, %edi
190 ; CHECK-NEXT:    jns .LBB11_3
191 ; CHECK-NEXT:  # %bb.1: # %entry
192 ; CHECK-NEXT:    testl %esi, %esi
193 ; CHECK-NEXT:    jns .LBB11_3
194 ; CHECK-NEXT:  # %bb.2: # %bb1
195 ; CHECK-NEXT:    movl $4, %eax
196 ; CHECK-NEXT:    retq
197 ; CHECK-NEXT:  .LBB11_3: # %return
198 ; CHECK-NEXT:    movl $192, %eax
199 ; CHECK-NEXT:    retq
200 entry:
201   %a = icmp slt i32 %P, 0
202   %b = icmp slt i32 %Q, 0
203   %c = and i1 %a, %b
204   br i1 %c, label %bb1, label %return
206 bb1:
207   ret i32 4
209 return:
210   ret i32 192
213 ; PR3351 - (P != 0) | (Q != 0) -> (P|Q) != 0
214 define i32 @any_bits_set_branch(i32* %P, i32* %Q) nounwind {
215 ; CHECK-LABEL: any_bits_set_branch:
216 ; CHECK:       # %bb.0: # %entry
217 ; CHECK-NEXT:    orq %rsi, %rdi
218 ; CHECK-NEXT:    je .LBB12_2
219 ; CHECK-NEXT:  # %bb.1: # %bb1
220 ; CHECK-NEXT:    movl $4, %eax
221 ; CHECK-NEXT:    retq
222 ; CHECK-NEXT:  .LBB12_2: # %return
223 ; CHECK-NEXT:    movl $192, %eax
224 ; CHECK-NEXT:    retq
225 entry:
226   %a = icmp ne i32* %P, null
227   %b = icmp ne i32* %Q, null
228   %c = or i1 %a, %b
229   br i1 %c, label %bb1, label %return
231 bb1:
232   ret i32 4
234 return:
235   ret i32 192
238 define i32 @any_sign_bits_set_branch(i32 %P, i32 %Q) nounwind {
239 ; CHECK-LABEL: any_sign_bits_set_branch:
240 ; CHECK:       # %bb.0: # %entry
241 ; CHECK-NEXT:    testl %edi, %edi
242 ; CHECK-NEXT:    js .LBB13_2
243 ; CHECK-NEXT:  # %bb.1: # %entry
244 ; CHECK-NEXT:    testl %esi, %esi
245 ; CHECK-NEXT:    js .LBB13_2
246 ; CHECK-NEXT:  # %bb.3: # %return
247 ; CHECK-NEXT:    movl $192, %eax
248 ; CHECK-NEXT:    retq
249 ; CHECK-NEXT:  .LBB13_2: # %bb1
250 ; CHECK-NEXT:    movl $4, %eax
251 ; CHECK-NEXT:    retq
252 entry:
253   %a = icmp slt i32 %P, 0
254   %b = icmp slt i32 %Q, 0
255   %c = or i1 %a, %b
256   br i1 %c, label %bb1, label %return
258 bb1:
259   ret i32 4
261 return:
262   ret i32 192
265 define i32 @any_bits_clear_branch(i32 %P, i32 %Q) nounwind {
266 ; CHECK-LABEL: any_bits_clear_branch:
267 ; CHECK:       # %bb.0: # %entry
268 ; CHECK-NEXT:    cmpl $-1, %edi
269 ; CHECK-NEXT:    jne .LBB14_2
270 ; CHECK-NEXT:  # %bb.1: # %entry
271 ; CHECK-NEXT:    cmpl $-1, %esi
272 ; CHECK-NEXT:    jne .LBB14_2
273 ; CHECK-NEXT:  # %bb.3: # %return
274 ; CHECK-NEXT:    movl $192, %eax
275 ; CHECK-NEXT:    retq
276 ; CHECK-NEXT:  .LBB14_2: # %bb1
277 ; CHECK-NEXT:    movl $4, %eax
278 ; CHECK-NEXT:    retq
279 entry:
280   %a = icmp ne i32 %P, -1
281   %b = icmp ne i32 %Q, -1
282   %c = or i1 %a, %b
283   br i1 %c, label %bb1, label %return
285 bb1:
286   ret i32 4
288 return:
289   ret i32 192
292 define i32 @any_sign_bits_clear_branch(i32 %P, i32 %Q) nounwind {
293 ; CHECK-LABEL: any_sign_bits_clear_branch:
294 ; CHECK:       # %bb.0: # %entry
295 ; CHECK-NEXT:    testl %edi, %edi
296 ; CHECK-NEXT:    jns .LBB15_2
297 ; CHECK-NEXT:  # %bb.1: # %entry
298 ; CHECK-NEXT:    testl %esi, %esi
299 ; CHECK-NEXT:    jns .LBB15_2
300 ; CHECK-NEXT:  # %bb.3: # %return
301 ; CHECK-NEXT:    movl $192, %eax
302 ; CHECK-NEXT:    retq
303 ; CHECK-NEXT:  .LBB15_2: # %bb1
304 ; CHECK-NEXT:    movl $4, %eax
305 ; CHECK-NEXT:    retq
306 entry:
307   %a = icmp sgt i32 %P, -1
308   %b = icmp sgt i32 %Q, -1
309   %c = or i1 %a, %b
310   br i1 %c, label %bb1, label %return
312 bb1:
313   ret i32 4
315 return:
316   ret i32 192
319 ; PR44565 - https://bugs.llvm.org/show_bug.cgi?id=44565
321 define i32 @vec_extract_branch(<2 x double> %x)  {
322 ; CHECK-LABEL: vec_extract_branch:
323 ; CHECK:       # %bb.0:
324 ; CHECK-NEXT:    xorpd %xmm1, %xmm1
325 ; CHECK-NEXT:    cmpltpd %xmm0, %xmm1
326 ; CHECK-NEXT:    movmskpd %xmm1, %eax
327 ; CHECK-NEXT:    cmpb $3, %al
328 ; CHECK-NEXT:    jne .LBB16_2
329 ; CHECK-NEXT:  # %bb.1: # %true
330 ; CHECK-NEXT:    movl $42, %eax
331 ; CHECK-NEXT:    retq
332 ; CHECK-NEXT:  .LBB16_2: # %false
333 ; CHECK-NEXT:    movl $88, %eax
334 ; CHECK-NEXT:    retq
335   %t1 = fcmp ogt <2 x double> %x, zeroinitializer
336   %t2 = extractelement <2 x i1> %t1, i32 0
337   %t3 = extractelement <2 x i1> %t1, i32 1
338   %t4 = and i1 %t2, %t3
339   br i1 %t4, label %true, label %false
340 true:
341   ret i32 42
342 false:
343   ret i32 88
346 define <4 x i1> @all_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
347 ; CHECK-LABEL: all_bits_clear_vec:
348 ; CHECK:       # %bb.0:
349 ; CHECK-NEXT:    por %xmm1, %xmm0
350 ; CHECK-NEXT:    pxor %xmm1, %xmm1
351 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
352 ; CHECK-NEXT:    retq
353   %a = icmp eq <4 x i32> %P, zeroinitializer
354   %b = icmp eq <4 x i32> %Q, zeroinitializer
355   %c = and <4 x i1> %a, %b
356   ret <4 x i1> %c
359 define <4 x i1> @all_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
360 ; CHECK-LABEL: all_sign_bits_clear_vec:
361 ; CHECK:       # %bb.0:
362 ; CHECK-NEXT:    por %xmm1, %xmm0
363 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
364 ; CHECK-NEXT:    pcmpgtd %xmm1, %xmm0
365 ; CHECK-NEXT:    retq
366   %a = icmp sgt <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1>
367   %b = icmp sgt <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1>
368   %c = and <4 x i1> %a, %b
369   ret <4 x i1> %c
372 define <4 x i1> @all_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
373 ; CHECK-LABEL: all_bits_set_vec:
374 ; CHECK:       # %bb.0:
375 ; CHECK-NEXT:    pand %xmm1, %xmm0
376 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
377 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
378 ; CHECK-NEXT:    retq
379   %a = icmp eq <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1>
380   %b = icmp eq <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1>
381   %c = and <4 x i1> %a, %b
382   ret <4 x i1> %c
385 define <4 x i1> @all_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
386 ; CHECK-LABEL: all_sign_bits_set_vec:
387 ; CHECK:       # %bb.0:
388 ; CHECK-NEXT:    pand %xmm1, %xmm0
389 ; CHECK-NEXT:    pxor %xmm1, %xmm1
390 ; CHECK-NEXT:    pcmpgtd %xmm0, %xmm1
391 ; CHECK-NEXT:    movdqa %xmm1, %xmm0
392 ; CHECK-NEXT:    retq
393   %a = icmp slt <4 x i32> %P, zeroinitializer
394   %b = icmp slt <4 x i32> %Q, zeroinitializer
395   %c = and <4 x i1> %a, %b
396   ret <4 x i1> %c
399 define <4 x i1> @any_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
400 ; CHECK-LABEL: any_bits_set_vec:
401 ; CHECK:       # %bb.0:
402 ; CHECK-NEXT:    por %xmm1, %xmm0
403 ; CHECK-NEXT:    pxor %xmm1, %xmm1
404 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
405 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
406 ; CHECK-NEXT:    pxor %xmm1, %xmm0
407 ; CHECK-NEXT:    retq
408   %a = icmp ne <4 x i32> %P, zeroinitializer
409   %b = icmp ne <4 x i32> %Q, zeroinitializer
410   %c = or <4 x i1> %a, %b
411   ret <4 x i1> %c
414 define <4 x i1> @any_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
415 ; CHECK-LABEL: any_sign_bits_set_vec:
416 ; CHECK:       # %bb.0:
417 ; CHECK-NEXT:    por %xmm1, %xmm0
418 ; CHECK-NEXT:    pxor %xmm1, %xmm1
419 ; CHECK-NEXT:    pcmpgtd %xmm0, %xmm1
420 ; CHECK-NEXT:    movdqa %xmm1, %xmm0
421 ; CHECK-NEXT:    retq
422   %a = icmp slt <4 x i32> %P, zeroinitializer
423   %b = icmp slt <4 x i32> %Q, zeroinitializer
424   %c = or <4 x i1> %a, %b
425   ret <4 x i1> %c
428 define <4 x i1> @any_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
429 ; CHECK-LABEL: any_bits_clear_vec:
430 ; CHECK:       # %bb.0:
431 ; CHECK-NEXT:    pand %xmm1, %xmm0
432 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
433 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
434 ; CHECK-NEXT:    pxor %xmm1, %xmm0
435 ; CHECK-NEXT:    retq
436   %a = icmp ne <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1>
437   %b = icmp ne <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1>
438   %c = or <4 x i1> %a, %b
439   ret <4 x i1> %c
442 define <4 x i1> @any_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
443 ; CHECK-LABEL: any_sign_bits_clear_vec:
444 ; CHECK:       # %bb.0:
445 ; CHECK-NEXT:    pand %xmm1, %xmm0
446 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
447 ; CHECK-NEXT:    pcmpgtd %xmm1, %xmm0
448 ; CHECK-NEXT:    retq
449   %a = icmp sgt <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1>
450   %b = icmp sgt <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1>
451   %c = or <4 x i1> %a, %b
452   ret <4 x i1> %c
455 define zeroext i1 @ne_neg1_and_ne_zero(i64 %x) nounwind {
456 ; CHECK-LABEL: ne_neg1_and_ne_zero:
457 ; CHECK:       # %bb.0:
458 ; CHECK-NEXT:    incq %rdi
459 ; CHECK-NEXT:    cmpq $2, %rdi
460 ; CHECK-NEXT:    setae %al
461 ; CHECK-NEXT:    retq
462   %cmp1 = icmp ne i64 %x, -1
463   %cmp2 = icmp ne i64 %x, 0
464   %and = and i1 %cmp1, %cmp2
465   ret i1 %and
468 ; PR32401 - https://bugs.llvm.org/show_bug.cgi?id=32401
470 define zeroext i1 @and_eq(i8 %a, i8 %b, i8 %c, i8 %d) nounwind {
471 ; CHECK-LABEL: and_eq:
472 ; CHECK:       # %bb.0:
473 ; CHECK-NEXT:    xorl %esi, %edi
474 ; CHECK-NEXT:    xorl %ecx, %edx
475 ; CHECK-NEXT:    orb %dl, %dil
476 ; CHECK-NEXT:    sete %al
477 ; CHECK-NEXT:    retq
478   %cmp1 = icmp eq i8 %a, %b
479   %cmp2 = icmp eq i8 %c, %d
480   %and = and i1 %cmp1, %cmp2
481   ret i1 %and
484 define zeroext i1 @or_ne(i8 %a, i8 %b, i8 %c, i8 %d) nounwind {
485 ; CHECK-LABEL: or_ne:
486 ; CHECK:       # %bb.0:
487 ; CHECK-NEXT:    xorl %esi, %edi
488 ; CHECK-NEXT:    xorl %ecx, %edx
489 ; CHECK-NEXT:    orb %dl, %dil
490 ; CHECK-NEXT:    setne %al
491 ; CHECK-NEXT:    retq
492   %cmp1 = icmp ne i8 %a, %b
493   %cmp2 = icmp ne i8 %c, %d
494   %or = or i1 %cmp1, %cmp2
495   ret i1 %or
498 ; This should not be transformed because vector compares + bitwise logic are faster.
500 define <4 x i1> @and_eq_vec(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) nounwind {
501 ; CHECK-LABEL: and_eq_vec:
502 ; CHECK:       # %bb.0:
503 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
504 ; CHECK-NEXT:    pcmpeqd %xmm3, %xmm2
505 ; CHECK-NEXT:    pand %xmm2, %xmm0
506 ; CHECK-NEXT:    retq
507   %cmp1 = icmp eq <4 x i32> %a, %b
508   %cmp2 = icmp eq <4 x i32> %c, %d
509   %and = and <4 x i1> %cmp1, %cmp2
510   ret <4 x i1> %and
513 define i1 @or_icmps_const_1bit_diff(i8 %x) {
514 ; CHECK-LABEL: or_icmps_const_1bit_diff:
515 ; CHECK:       # %bb.0:
516 ; CHECK-NEXT:    addb $-43, %dil
517 ; CHECK-NEXT:    testb $-3, %dil
518 ; CHECK-NEXT:    sete %al
519 ; CHECK-NEXT:    retq
520   %a = icmp eq i8 %x, 43
521   %b = icmp eq i8 %x, 45
522   %r = or i1 %a, %b
523   ret i1 %r
526 define i1 @and_icmps_const_1bit_diff(i32 %x) {
527 ; CHECK-LABEL: and_icmps_const_1bit_diff:
528 ; CHECK:       # %bb.0:
529 ; CHECK-NEXT:    addl $-44, %edi
530 ; CHECK-NEXT:    testl $-17, %edi
531 ; CHECK-NEXT:    setne %al
532 ; CHECK-NEXT:    retq
533   %a = icmp ne i32 %x, 44
534   %b = icmp ne i32 %x, 60
535   %r = and i1 %a, %b
536   ret i1 %r
539 ; Negative test - extra use prevents optimization
541 define i1 @or_icmps_const_1bit_diff_extra_use(i8 %x, i8* %p) {
542 ; CHECK-LABEL: or_icmps_const_1bit_diff_extra_use:
543 ; CHECK:       # %bb.0:
544 ; CHECK-NEXT:    cmpb $45, %dil
545 ; CHECK-NEXT:    sete %cl
546 ; CHECK-NEXT:    cmpb $43, %dil
547 ; CHECK-NEXT:    sete %al
548 ; CHECK-NEXT:    sete (%rsi)
549 ; CHECK-NEXT:    orb %cl, %al
550 ; CHECK-NEXT:    retq
551   %a = icmp eq i8 %x, 43
552   %b = icmp eq i8 %x, 45
553   %r = or i1 %a, %b
554   %z = zext i1 %a to i8
555   store i8 %z, i8* %p
556   ret i1 %r
559 ; Negative test - constant diff is >1 bit
561 define i1 @and_icmps_const_not1bit_diff(i32 %x) {
562 ; CHECK-LABEL: and_icmps_const_not1bit_diff:
563 ; CHECK:       # %bb.0:
564 ; CHECK-NEXT:    cmpl $44, %edi
565 ; CHECK-NEXT:    setne %cl
566 ; CHECK-NEXT:    cmpl $92, %edi
567 ; CHECK-NEXT:    setne %al
568 ; CHECK-NEXT:    andb %cl, %al
569 ; CHECK-NEXT:    retq
570   %a = icmp ne i32 %x, 44
571   %b = icmp ne i32 %x, 92
572   %r = and i1 %a, %b
573   ret i1 %r
576 ; Negative test - wrong comparison
578 define i1 @and_icmps_const_1bit_diff_wrong_pred(i32 %x) {
579 ; CHECK-LABEL: and_icmps_const_1bit_diff_wrong_pred:
580 ; CHECK:       # %bb.0:
581 ; CHECK-NEXT:    cmpl $43, %edi
582 ; CHECK-NEXT:    sete %cl
583 ; CHECK-NEXT:    cmpl $45, %edi
584 ; CHECK-NEXT:    setl %al
585 ; CHECK-NEXT:    orb %cl, %al
586 ; CHECK-NEXT:    retq
587   %a = icmp eq i32 %x, 43
588   %b = icmp slt i32 %x, 45
589   %r = or i1 %a, %b
590   ret i1 %r
593 ; Negative test - no common operand
595 define i1 @and_icmps_const_1bit_diff_common_op(i32 %x, i32 %y) {
596 ; CHECK-LABEL: and_icmps_const_1bit_diff_common_op:
597 ; CHECK:       # %bb.0:
598 ; CHECK-NEXT:    cmpl $43, %edi
599 ; CHECK-NEXT:    sete %cl
600 ; CHECK-NEXT:    cmpl $45, %esi
601 ; CHECK-NEXT:    sete %al
602 ; CHECK-NEXT:    orb %cl, %al
603 ; CHECK-NEXT:    retq
604   %a = icmp eq i32 %x, 43
605   %b = icmp eq i32 %y, 45
606   %r = or i1 %a, %b
607   ret i1 %r
610 ; PR44136 - fold cmpeq(or(X,Y),X) --> cmpeq(and(~X,Y),0)
612 define i1 @or_cmp_eq_i64(i64 %x, i64 %y) {
613 ; NOBMI-LABEL: or_cmp_eq_i64:
614 ; NOBMI:       # %bb.0:
615 ; NOBMI-NEXT:    notq %rdi
616 ; NOBMI-NEXT:    testq %rsi, %rdi
617 ; NOBMI-NEXT:    sete %al
618 ; NOBMI-NEXT:    retq
620 ; BMI-LABEL: or_cmp_eq_i64:
621 ; BMI:       # %bb.0:
622 ; BMI-NEXT:    andnq %rsi, %rdi, %rax
623 ; BMI-NEXT:    sete %al
624 ; BMI-NEXT:    retq
625   %o = or i64 %x, %y
626   %c = icmp eq i64 %o, %x
627   ret i1 %c
630 define i1 @or_cmp_ne_i32(i32 %x, i32 %y) {
631 ; NOBMI-LABEL: or_cmp_ne_i32:
632 ; NOBMI:       # %bb.0:
633 ; NOBMI-NEXT:    notl %esi
634 ; NOBMI-NEXT:    testl %edi, %esi
635 ; NOBMI-NEXT:    setne %al
636 ; NOBMI-NEXT:    retq
638 ; BMI-LABEL: or_cmp_ne_i32:
639 ; BMI:       # %bb.0:
640 ; BMI-NEXT:    andnl %edi, %esi, %eax
641 ; BMI-NEXT:    setne %al
642 ; BMI-NEXT:    retq
643   %o = or i32 %x, %y
644   %c = icmp ne i32 %o, %y
645   ret i1 %c
648 define i1 @or_cmp_eq_i16(i16 zeroext %x, i16 zeroext %y) {
649 ; NOBMI-LABEL: or_cmp_eq_i16:
650 ; NOBMI:       # %bb.0:
651 ; NOBMI-NEXT:    notl %edi
652 ; NOBMI-NEXT:    testl %esi, %edi
653 ; NOBMI-NEXT:    sete %al
654 ; NOBMI-NEXT:    retq
656 ; BMI-LABEL: or_cmp_eq_i16:
657 ; BMI:       # %bb.0:
658 ; BMI-NEXT:    andnl %esi, %edi, %eax
659 ; BMI-NEXT:    sete %al
660 ; BMI-NEXT:    retq
661   %o = or i16 %x, %y
662   %c = icmp eq i16 %x, %o
663   ret i1 %c
666 define i1 @or_cmp_ne_i8(i8 zeroext %x, i8 zeroext %y) {
667 ; CHECK-LABEL: or_cmp_ne_i8:
668 ; CHECK:       # %bb.0:
669 ; CHECK-NEXT:    notb %sil
670 ; CHECK-NEXT:    testb %dil, %sil
671 ; CHECK-NEXT:    setne %al
672 ; CHECK-NEXT:    retq
673   %o = or i8 %x, %y
674   %c = icmp ne i8 %y, %o
675   ret i1 %c
678 ; Don't fold vectors.
679 define <4 x i32> @or_cmp_eq_v4i32(<4 x i32> %x, <4 x i32> %y) {
680 ; CHECK-LABEL: or_cmp_eq_v4i32:
681 ; CHECK:       # %bb.0:
682 ; CHECK-NEXT:    por %xmm0, %xmm1
683 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
684 ; CHECK-NEXT:    retq
685   %o = or <4 x i32> %x, %y
686   %c = icmp eq <4 x i32> %o, %x
687   %s = sext <4 x i1> %c to <4 x i32>
688   ret <4 x i32> %s
691 define <16 x i8> @or_cmp_ne_v4i32(<16 x i8> %x, <16 x i8> %y) {
692 ; CHECK-LABEL: or_cmp_ne_v4i32:
693 ; CHECK:       # %bb.0:
694 ; CHECK-NEXT:    por %xmm0, %xmm1
695 ; CHECK-NEXT:    pcmpeqb %xmm1, %xmm0
696 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
697 ; CHECK-NEXT:    pxor %xmm1, %xmm0
698 ; CHECK-NEXT:    retq
699   %o = or <16 x i8> %x, %y
700   %c = icmp ne <16 x i8> %o, %x
701   %s = sext <16 x i1> %c to <16 x i8>
702   ret <16 x i8> %s