[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / CodeGen / X86 / setcc-logic.ll
blob3faa493ebccd0d1ec43084609356667d7052705c
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(ptr %P, ptr %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 ptr %P, null
121   %b = icmp eq ptr %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(ptr %P, ptr %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 ptr %P, null
227   %b = icmp ne ptr %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:    cmpl $3, %eax
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:    testq $-2, %rdi
460 ; CHECK-NEXT:    setne %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 <4 x i32> @or_icmps_const_1bit_diff_vec(<4 x i32> %x) {
527 ; CHECK-LABEL: or_icmps_const_1bit_diff_vec:
528 ; CHECK:       # %bb.0:
529 ; CHECK-NEXT:    movdqa {{.*#+}} xmm1 = [43,45,43,45]
530 ; CHECK-NEXT:    pcmpeqd %xmm0, %xmm1
531 ; CHECK-NEXT:    pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
532 ; CHECK-NEXT:    por %xmm1, %xmm0
533 ; CHECK-NEXT:    retq
534   %a = icmp eq <4 x i32> %x, <i32 43, i32 45, i32 43, i32 45>
535   %b = icmp eq <4 x i32> %x, <i32 45, i32 43, i32 45, i32 43>
536   %t = or <4 x i1> %a, %b
537   %r = sext <4 x i1> %t to <4 x i32>
538   ret <4 x i32> %r
541 define i1 @and_icmps_const_1bit_diff(i32 %x) {
542 ; CHECK-LABEL: and_icmps_const_1bit_diff:
543 ; CHECK:       # %bb.0:
544 ; CHECK-NEXT:    addl $-44, %edi
545 ; CHECK-NEXT:    testl $-17, %edi
546 ; CHECK-NEXT:    setne %al
547 ; CHECK-NEXT:    retq
548   %a = icmp ne i32 %x, 44
549   %b = icmp ne i32 %x, 60
550   %r = and i1 %a, %b
551   ret i1 %r
554 define <4 x i32> @and_icmps_const_1bit_diff_vec(<4 x i32> %x) {
555 ; CHECK-LABEL: and_icmps_const_1bit_diff_vec:
556 ; CHECK:       # %bb.0:
557 ; CHECK-NEXT:    movdqa {{.*#+}} xmm1 = [44,60,44,60]
558 ; CHECK-NEXT:    pcmpeqd %xmm0, %xmm1
559 ; CHECK-NEXT:    pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
560 ; CHECK-NEXT:    por %xmm1, %xmm0
561 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
562 ; CHECK-NEXT:    pxor %xmm1, %xmm0
563 ; CHECK-NEXT:    retq
564   %a = icmp ne <4 x i32> %x, <i32 44, i32 60, i32 44, i32 60>
565   %b = icmp ne <4 x i32> %x, <i32 60, i32 44, i32 60, i32 44>
566   %t = and <4 x i1> %a, %b
567   %r = sext <4 x i1> %t to <4 x i32>
568   ret <4 x i32> %r
571 ; Negative test - extra use prevents optimization
573 define i1 @or_icmps_const_1bit_diff_extra_use(i8 %x, ptr %p) {
574 ; CHECK-LABEL: or_icmps_const_1bit_diff_extra_use:
575 ; CHECK:       # %bb.0:
576 ; CHECK-NEXT:    cmpb $45, %dil
577 ; CHECK-NEXT:    sete %cl
578 ; CHECK-NEXT:    cmpb $43, %dil
579 ; CHECK-NEXT:    sete %al
580 ; CHECK-NEXT:    sete (%rsi)
581 ; CHECK-NEXT:    orb %cl, %al
582 ; CHECK-NEXT:    retq
583   %a = icmp eq i8 %x, 43
584   %b = icmp eq i8 %x, 45
585   %r = or i1 %a, %b
586   %z = zext i1 %a to i8
587   store i8 %z, ptr %p
588   ret i1 %r
591 ; Negative test - constant diff is >1 bit
593 define i1 @and_icmps_const_not1bit_diff(i32 %x) {
594 ; CHECK-LABEL: and_icmps_const_not1bit_diff:
595 ; CHECK:       # %bb.0:
596 ; CHECK-NEXT:    cmpl $44, %edi
597 ; CHECK-NEXT:    setne %cl
598 ; CHECK-NEXT:    cmpl $92, %edi
599 ; CHECK-NEXT:    setne %al
600 ; CHECK-NEXT:    andb %cl, %al
601 ; CHECK-NEXT:    retq
602   %a = icmp ne i32 %x, 44
603   %b = icmp ne i32 %x, 92
604   %r = and i1 %a, %b
605   ret i1 %r
608 ; Negative test - wrong comparison
610 define i1 @and_icmps_const_1bit_diff_wrong_pred(i32 %x) {
611 ; CHECK-LABEL: and_icmps_const_1bit_diff_wrong_pred:
612 ; CHECK:       # %bb.0:
613 ; CHECK-NEXT:    cmpl $43, %edi
614 ; CHECK-NEXT:    sete %cl
615 ; CHECK-NEXT:    cmpl $45, %edi
616 ; CHECK-NEXT:    setl %al
617 ; CHECK-NEXT:    orb %cl, %al
618 ; CHECK-NEXT:    retq
619   %a = icmp eq i32 %x, 43
620   %b = icmp slt i32 %x, 45
621   %r = or i1 %a, %b
622   ret i1 %r
625 ; Negative test - no common operand
627 define i1 @and_icmps_const_1bit_diff_common_op(i32 %x, i32 %y) {
628 ; CHECK-LABEL: and_icmps_const_1bit_diff_common_op:
629 ; CHECK:       # %bb.0:
630 ; CHECK-NEXT:    cmpl $43, %edi
631 ; CHECK-NEXT:    sete %cl
632 ; CHECK-NEXT:    cmpl $45, %esi
633 ; CHECK-NEXT:    sete %al
634 ; CHECK-NEXT:    orb %cl, %al
635 ; CHECK-NEXT:    retq
636   %a = icmp eq i32 %x, 43
637   %b = icmp eq i32 %y, 45
638   %r = or i1 %a, %b
639   ret i1 %r
642 ; PR44136 - fold cmpeq(or(X,Y),X) --> cmpeq(and(~X,Y),0)
644 define i1 @or_cmp_eq_i64(i64 %x, i64 %y) {
645 ; NOBMI-LABEL: or_cmp_eq_i64:
646 ; NOBMI:       # %bb.0:
647 ; NOBMI-NEXT:    notq %rdi
648 ; NOBMI-NEXT:    testq %rsi, %rdi
649 ; NOBMI-NEXT:    sete %al
650 ; NOBMI-NEXT:    retq
652 ; BMI-LABEL: or_cmp_eq_i64:
653 ; BMI:       # %bb.0:
654 ; BMI-NEXT:    andnq %rsi, %rdi, %rax
655 ; BMI-NEXT:    sete %al
656 ; BMI-NEXT:    retq
657   %o = or i64 %x, %y
658   %c = icmp eq i64 %o, %x
659   ret i1 %c
662 define i1 @or_cmp_ne_i32(i32 %x, i32 %y) {
663 ; NOBMI-LABEL: or_cmp_ne_i32:
664 ; NOBMI:       # %bb.0:
665 ; NOBMI-NEXT:    notl %esi
666 ; NOBMI-NEXT:    testl %edi, %esi
667 ; NOBMI-NEXT:    setne %al
668 ; NOBMI-NEXT:    retq
670 ; BMI-LABEL: or_cmp_ne_i32:
671 ; BMI:       # %bb.0:
672 ; BMI-NEXT:    andnl %edi, %esi, %eax
673 ; BMI-NEXT:    setne %al
674 ; BMI-NEXT:    retq
675   %o = or i32 %x, %y
676   %c = icmp ne i32 %o, %y
677   ret i1 %c
680 define i1 @or_cmp_eq_i16(i16 zeroext %x, i16 zeroext %y) {
681 ; NOBMI-LABEL: or_cmp_eq_i16:
682 ; NOBMI:       # %bb.0:
683 ; NOBMI-NEXT:    notl %edi
684 ; NOBMI-NEXT:    testl %esi, %edi
685 ; NOBMI-NEXT:    sete %al
686 ; NOBMI-NEXT:    retq
688 ; BMI-LABEL: or_cmp_eq_i16:
689 ; BMI:       # %bb.0:
690 ; BMI-NEXT:    andnl %esi, %edi, %eax
691 ; BMI-NEXT:    sete %al
692 ; BMI-NEXT:    retq
693   %o = or i16 %x, %y
694   %c = icmp eq i16 %x, %o
695   ret i1 %c
698 define i1 @or_cmp_ne_i8(i8 zeroext %x, i8 zeroext %y) {
699 ; CHECK-LABEL: or_cmp_ne_i8:
700 ; CHECK:       # %bb.0:
701 ; CHECK-NEXT:    notb %sil
702 ; CHECK-NEXT:    testb %dil, %sil
703 ; CHECK-NEXT:    setne %al
704 ; CHECK-NEXT:    retq
705   %o = or i8 %x, %y
706   %c = icmp ne i8 %y, %o
707   ret i1 %c
710 ; Don't fold vectors.
711 define <4 x i32> @or_cmp_eq_v4i32(<4 x i32> %x, <4 x i32> %y) {
712 ; CHECK-LABEL: or_cmp_eq_v4i32:
713 ; CHECK:       # %bb.0:
714 ; CHECK-NEXT:    por %xmm0, %xmm1
715 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
716 ; CHECK-NEXT:    retq
717   %o = or <4 x i32> %x, %y
718   %c = icmp eq <4 x i32> %o, %x
719   %s = sext <4 x i1> %c to <4 x i32>
720   ret <4 x i32> %s
723 define <16 x i8> @or_cmp_ne_v4i32(<16 x i8> %x, <16 x i8> %y) {
724 ; CHECK-LABEL: or_cmp_ne_v4i32:
725 ; CHECK:       # %bb.0:
726 ; CHECK-NEXT:    por %xmm0, %xmm1
727 ; CHECK-NEXT:    pcmpeqb %xmm1, %xmm0
728 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
729 ; CHECK-NEXT:    pxor %xmm1, %xmm0
730 ; CHECK-NEXT:    retq
731   %o = or <16 x i8> %x, %y
732   %c = icmp ne <16 x i8> %o, %x
733   %s = sext <16 x i1> %c to <16 x i8>
734   ret <16 x i8> %s