xref: /llvm-project/llvm/test/CodeGen/X86/setcc-logic.ll (revision a4951eca40c070e020aa5d2689c08177fbeb780d)
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
4
5define 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
15}
16
17define 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
27}
28
29define 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
40}
41
42define 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
54}
55
56define 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
66}
67
68define 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
80}
81
82define 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
93}
94
95define 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
105}
106
107; PR3351 - (P == 0) & (Q == 0) -> (P|Q) == 0
108define 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
119entry:
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
124
125bb1:
126  ret i32 4
127
128return:
129  ret i32 192
130}
131
132define 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:    orl %esi, %edi
136; CHECK-NEXT:    js .LBB9_2
137; CHECK-NEXT:  # %bb.1: # %bb1
138; CHECK-NEXT:    movl $4, %eax
139; CHECK-NEXT:    retq
140; CHECK-NEXT:  .LBB9_2: # %return
141; CHECK-NEXT:    movl $192, %eax
142; CHECK-NEXT:    retq
143entry:
144  %a = icmp sgt i32 %P, -1
145  %b = icmp sgt i32 %Q, -1
146  %c = and i1 %a, %b
147  br i1 %c, label %bb1, label %return
148
149bb1:
150  ret i32 4
151
152return:
153  ret i32 192
154}
155
156define i32 @all_bits_set_branch(i32 %P, i32 %Q) nounwind {
157; CHECK-LABEL: all_bits_set_branch:
158; CHECK:       # %bb.0: # %entry
159; CHECK-NEXT:    andl %esi, %edi
160; CHECK-NEXT:    cmpl $-1, %edi
161; CHECK-NEXT:    jne .LBB10_2
162; CHECK-NEXT:  # %bb.1: # %bb1
163; CHECK-NEXT:    movl $4, %eax
164; CHECK-NEXT:    retq
165; CHECK-NEXT:  .LBB10_2: # %return
166; CHECK-NEXT:    movl $192, %eax
167; CHECK-NEXT:    retq
168entry:
169  %a = icmp eq i32 %P, -1
170  %b = icmp eq i32 %Q, -1
171  %c = and i1 %a, %b
172  br i1 %c, label %bb1, label %return
173
174bb1:
175  ret i32 4
176
177return:
178  ret i32 192
179}
180
181define i32 @all_sign_bits_set_branch(i32 %P, i32 %Q) nounwind {
182; CHECK-LABEL: all_sign_bits_set_branch:
183; CHECK:       # %bb.0: # %entry
184; CHECK-NEXT:    testl %esi, %edi
185; CHECK-NEXT:    jns .LBB11_2
186; CHECK-NEXT:  # %bb.1: # %bb1
187; CHECK-NEXT:    movl $4, %eax
188; CHECK-NEXT:    retq
189; CHECK-NEXT:  .LBB11_2: # %return
190; CHECK-NEXT:    movl $192, %eax
191; CHECK-NEXT:    retq
192entry:
193  %a = icmp slt i32 %P, 0
194  %b = icmp slt i32 %Q, 0
195  %c = and i1 %a, %b
196  br i1 %c, label %bb1, label %return
197
198bb1:
199  ret i32 4
200
201return:
202  ret i32 192
203}
204
205; PR3351 - (P != 0) | (Q != 0) -> (P|Q) != 0
206define i32 @any_bits_set_branch(ptr %P, ptr %Q) nounwind {
207; CHECK-LABEL: any_bits_set_branch:
208; CHECK:       # %bb.0: # %entry
209; CHECK-NEXT:    orq %rsi, %rdi
210; CHECK-NEXT:    je .LBB12_2
211; CHECK-NEXT:  # %bb.1: # %bb1
212; CHECK-NEXT:    movl $4, %eax
213; CHECK-NEXT:    retq
214; CHECK-NEXT:  .LBB12_2: # %return
215; CHECK-NEXT:    movl $192, %eax
216; CHECK-NEXT:    retq
217entry:
218  %a = icmp ne ptr %P, null
219  %b = icmp ne ptr %Q, null
220  %c = or i1 %a, %b
221  br i1 %c, label %bb1, label %return
222
223bb1:
224  ret i32 4
225
226return:
227  ret i32 192
228}
229
230define i32 @any_sign_bits_set_branch(i32 %P, i32 %Q) nounwind {
231; CHECK-LABEL: any_sign_bits_set_branch:
232; CHECK:       # %bb.0: # %entry
233; CHECK-NEXT:    orl %esi, %edi
234; CHECK-NEXT:    jns .LBB13_2
235; CHECK-NEXT:  # %bb.1: # %bb1
236; CHECK-NEXT:    movl $4, %eax
237; CHECK-NEXT:    retq
238; CHECK-NEXT:  .LBB13_2: # %return
239; CHECK-NEXT:    movl $192, %eax
240; CHECK-NEXT:    retq
241entry:
242  %a = icmp slt i32 %P, 0
243  %b = icmp slt i32 %Q, 0
244  %c = or i1 %a, %b
245  br i1 %c, label %bb1, label %return
246
247bb1:
248  ret i32 4
249
250return:
251  ret i32 192
252}
253
254define i32 @any_bits_clear_branch(i32 %P, i32 %Q) nounwind {
255; CHECK-LABEL: any_bits_clear_branch:
256; CHECK:       # %bb.0: # %entry
257; CHECK-NEXT:    andl %esi, %edi
258; CHECK-NEXT:    cmpl $-1, %edi
259; CHECK-NEXT:    je .LBB14_2
260; CHECK-NEXT:  # %bb.1: # %bb1
261; CHECK-NEXT:    movl $4, %eax
262; CHECK-NEXT:    retq
263; CHECK-NEXT:  .LBB14_2: # %return
264; CHECK-NEXT:    movl $192, %eax
265; CHECK-NEXT:    retq
266entry:
267  %a = icmp ne i32 %P, -1
268  %b = icmp ne i32 %Q, -1
269  %c = or i1 %a, %b
270  br i1 %c, label %bb1, label %return
271
272bb1:
273  ret i32 4
274
275return:
276  ret i32 192
277}
278
279define i32 @any_sign_bits_clear_branch(i32 %P, i32 %Q) nounwind {
280; CHECK-LABEL: any_sign_bits_clear_branch:
281; CHECK:       # %bb.0: # %entry
282; CHECK-NEXT:    testl %esi, %edi
283; CHECK-NEXT:    js .LBB15_2
284; CHECK-NEXT:  # %bb.1: # %bb1
285; CHECK-NEXT:    movl $4, %eax
286; CHECK-NEXT:    retq
287; CHECK-NEXT:  .LBB15_2: # %return
288; CHECK-NEXT:    movl $192, %eax
289; CHECK-NEXT:    retq
290entry:
291  %a = icmp sgt i32 %P, -1
292  %b = icmp sgt i32 %Q, -1
293  %c = or i1 %a, %b
294  br i1 %c, label %bb1, label %return
295
296bb1:
297  ret i32 4
298
299return:
300  ret i32 192
301}
302
303; PR44565 - https://bugs.llvm.org/show_bug.cgi?id=44565
304
305define i32 @vec_extract_branch(<2 x double> %x)  {
306; CHECK-LABEL: vec_extract_branch:
307; CHECK:       # %bb.0:
308; CHECK-NEXT:    xorpd %xmm1, %xmm1
309; CHECK-NEXT:    cmpltpd %xmm0, %xmm1
310; CHECK-NEXT:    movmskpd %xmm1, %eax
311; CHECK-NEXT:    cmpl $3, %eax
312; CHECK-NEXT:    jne .LBB16_2
313; CHECK-NEXT:  # %bb.1: # %true
314; CHECK-NEXT:    movl $42, %eax
315; CHECK-NEXT:    retq
316; CHECK-NEXT:  .LBB16_2: # %false
317; CHECK-NEXT:    movl $88, %eax
318; CHECK-NEXT:    retq
319  %t1 = fcmp ogt <2 x double> %x, zeroinitializer
320  %t2 = extractelement <2 x i1> %t1, i32 0
321  %t3 = extractelement <2 x i1> %t1, i32 1
322  %t4 = and i1 %t2, %t3
323  br i1 %t4, label %true, label %false
324true:
325  ret i32 42
326false:
327  ret i32 88
328}
329
330define <4 x i1> @all_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
331; CHECK-LABEL: all_bits_clear_vec:
332; CHECK:       # %bb.0:
333; CHECK-NEXT:    por %xmm1, %xmm0
334; CHECK-NEXT:    pxor %xmm1, %xmm1
335; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
336; CHECK-NEXT:    retq
337  %a = icmp eq <4 x i32> %P, zeroinitializer
338  %b = icmp eq <4 x i32> %Q, zeroinitializer
339  %c = and <4 x i1> %a, %b
340  ret <4 x i1> %c
341}
342
343define <4 x i1> @all_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
344; CHECK-LABEL: all_sign_bits_clear_vec:
345; CHECK:       # %bb.0:
346; CHECK-NEXT:    por %xmm1, %xmm0
347; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
348; CHECK-NEXT:    pcmpgtd %xmm1, %xmm0
349; CHECK-NEXT:    retq
350  %a = icmp sgt <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1>
351  %b = icmp sgt <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1>
352  %c = and <4 x i1> %a, %b
353  ret <4 x i1> %c
354}
355
356define <4 x i1> @all_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
357; CHECK-LABEL: all_bits_set_vec:
358; CHECK:       # %bb.0:
359; CHECK-NEXT:    pand %xmm1, %xmm0
360; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
361; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
362; CHECK-NEXT:    retq
363  %a = icmp eq <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1>
364  %b = icmp eq <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1>
365  %c = and <4 x i1> %a, %b
366  ret <4 x i1> %c
367}
368
369define <4 x i1> @all_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
370; CHECK-LABEL: all_sign_bits_set_vec:
371; CHECK:       # %bb.0:
372; CHECK-NEXT:    pand %xmm1, %xmm0
373; CHECK-NEXT:    pxor %xmm1, %xmm1
374; CHECK-NEXT:    pcmpgtd %xmm0, %xmm1
375; CHECK-NEXT:    movdqa %xmm1, %xmm0
376; CHECK-NEXT:    retq
377  %a = icmp slt <4 x i32> %P, zeroinitializer
378  %b = icmp slt <4 x i32> %Q, zeroinitializer
379  %c = and <4 x i1> %a, %b
380  ret <4 x i1> %c
381}
382
383define <4 x i1> @any_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
384; CHECK-LABEL: any_bits_set_vec:
385; CHECK:       # %bb.0:
386; CHECK-NEXT:    por %xmm1, %xmm0
387; CHECK-NEXT:    pxor %xmm1, %xmm1
388; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
389; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
390; CHECK-NEXT:    pxor %xmm1, %xmm0
391; CHECK-NEXT:    retq
392  %a = icmp ne <4 x i32> %P, zeroinitializer
393  %b = icmp ne <4 x i32> %Q, zeroinitializer
394  %c = or <4 x i1> %a, %b
395  ret <4 x i1> %c
396}
397
398define <4 x i1> @any_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
399; CHECK-LABEL: any_sign_bits_set_vec:
400; CHECK:       # %bb.0:
401; CHECK-NEXT:    por %xmm1, %xmm0
402; CHECK-NEXT:    pxor %xmm1, %xmm1
403; CHECK-NEXT:    pcmpgtd %xmm0, %xmm1
404; CHECK-NEXT:    movdqa %xmm1, %xmm0
405; CHECK-NEXT:    retq
406  %a = icmp slt <4 x i32> %P, zeroinitializer
407  %b = icmp slt <4 x i32> %Q, zeroinitializer
408  %c = or <4 x i1> %a, %b
409  ret <4 x i1> %c
410}
411
412define <4 x i1> @any_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
413; CHECK-LABEL: any_bits_clear_vec:
414; CHECK:       # %bb.0:
415; CHECK-NEXT:    pand %xmm1, %xmm0
416; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
417; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
418; CHECK-NEXT:    pxor %xmm1, %xmm0
419; CHECK-NEXT:    retq
420  %a = icmp ne <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1>
421  %b = icmp ne <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1>
422  %c = or <4 x i1> %a, %b
423  ret <4 x i1> %c
424}
425
426define <4 x i1> @any_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind {
427; CHECK-LABEL: any_sign_bits_clear_vec:
428; CHECK:       # %bb.0:
429; CHECK-NEXT:    pand %xmm1, %xmm0
430; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
431; CHECK-NEXT:    pcmpgtd %xmm1, %xmm0
432; CHECK-NEXT:    retq
433  %a = icmp sgt <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1>
434  %b = icmp sgt <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1>
435  %c = or <4 x i1> %a, %b
436  ret <4 x i1> %c
437}
438
439define zeroext i1 @ne_neg1_and_ne_zero(i64 %x) nounwind {
440; CHECK-LABEL: ne_neg1_and_ne_zero:
441; CHECK:       # %bb.0:
442; CHECK-NEXT:    incq %rdi
443; CHECK-NEXT:    testq $-2, %rdi
444; CHECK-NEXT:    setne %al
445; CHECK-NEXT:    retq
446  %cmp1 = icmp ne i64 %x, -1
447  %cmp2 = icmp ne i64 %x, 0
448  %and = and i1 %cmp1, %cmp2
449  ret i1 %and
450}
451
452; PR32401 - https://bugs.llvm.org/show_bug.cgi?id=32401
453
454define zeroext i1 @and_eq(i8 %a, i8 %b, i8 %c, i8 %d) nounwind {
455; CHECK-LABEL: and_eq:
456; CHECK:       # %bb.0:
457; CHECK-NEXT:    xorl %esi, %edi
458; CHECK-NEXT:    xorl %ecx, %edx
459; CHECK-NEXT:    orb %dl, %dil
460; CHECK-NEXT:    sete %al
461; CHECK-NEXT:    retq
462  %cmp1 = icmp eq i8 %a, %b
463  %cmp2 = icmp eq i8 %c, %d
464  %and = and i1 %cmp1, %cmp2
465  ret i1 %and
466}
467
468define zeroext i1 @or_ne(i8 %a, i8 %b, i8 %c, i8 %d) nounwind {
469; CHECK-LABEL: or_ne:
470; CHECK:       # %bb.0:
471; CHECK-NEXT:    xorl %esi, %edi
472; CHECK-NEXT:    xorl %ecx, %edx
473; CHECK-NEXT:    orb %dl, %dil
474; CHECK-NEXT:    setne %al
475; CHECK-NEXT:    retq
476  %cmp1 = icmp ne i8 %a, %b
477  %cmp2 = icmp ne i8 %c, %d
478  %or = or i1 %cmp1, %cmp2
479  ret i1 %or
480}
481
482; This should not be transformed because vector compares + bitwise logic are faster.
483
484define <4 x i1> @and_eq_vec(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) nounwind {
485; CHECK-LABEL: and_eq_vec:
486; CHECK:       # %bb.0:
487; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
488; CHECK-NEXT:    pcmpeqd %xmm3, %xmm2
489; CHECK-NEXT:    pand %xmm2, %xmm0
490; CHECK-NEXT:    retq
491  %cmp1 = icmp eq <4 x i32> %a, %b
492  %cmp2 = icmp eq <4 x i32> %c, %d
493  %and = and <4 x i1> %cmp1, %cmp2
494  ret <4 x i1> %and
495}
496
497define i1 @or_icmps_const_1bit_diff(i8 %x) {
498; CHECK-LABEL: or_icmps_const_1bit_diff:
499; CHECK:       # %bb.0:
500; CHECK-NEXT:    addb $-43, %dil
501; CHECK-NEXT:    testb $-3, %dil
502; CHECK-NEXT:    sete %al
503; CHECK-NEXT:    retq
504  %a = icmp eq i8 %x, 43
505  %b = icmp eq i8 %x, 45
506  %r = or i1 %a, %b
507  ret i1 %r
508}
509
510define <4 x i32> @or_icmps_const_1bit_diff_vec(<4 x i32> %x) {
511; CHECK-LABEL: or_icmps_const_1bit_diff_vec:
512; CHECK:       # %bb.0:
513; CHECK-NEXT:    movdqa {{.*#+}} xmm1 = [43,45,43,45]
514; CHECK-NEXT:    pcmpeqd %xmm0, %xmm1
515; CHECK-NEXT:    pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
516; CHECK-NEXT:    por %xmm1, %xmm0
517; CHECK-NEXT:    retq
518  %a = icmp eq <4 x i32> %x, <i32 43, i32 45, i32 43, i32 45>
519  %b = icmp eq <4 x i32> %x, <i32 45, i32 43, i32 45, i32 43>
520  %t = or <4 x i1> %a, %b
521  %r = sext <4 x i1> %t to <4 x i32>
522  ret <4 x i32> %r
523}
524
525define i1 @and_icmps_const_1bit_diff(i32 %x) {
526; CHECK-LABEL: and_icmps_const_1bit_diff:
527; CHECK:       # %bb.0:
528; CHECK-NEXT:    addl $-44, %edi
529; CHECK-NEXT:    testl $-17, %edi
530; CHECK-NEXT:    setne %al
531; CHECK-NEXT:    retq
532  %a = icmp ne i32 %x, 44
533  %b = icmp ne i32 %x, 60
534  %r = and i1 %a, %b
535  ret i1 %r
536}
537
538define <4 x i32> @and_icmps_const_1bit_diff_vec(<4 x i32> %x) {
539; CHECK-LABEL: and_icmps_const_1bit_diff_vec:
540; CHECK:       # %bb.0:
541; CHECK-NEXT:    movdqa {{.*#+}} xmm1 = [44,60,44,60]
542; CHECK-NEXT:    pcmpeqd %xmm0, %xmm1
543; CHECK-NEXT:    pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
544; CHECK-NEXT:    por %xmm1, %xmm0
545; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
546; CHECK-NEXT:    pxor %xmm1, %xmm0
547; CHECK-NEXT:    retq
548  %a = icmp ne <4 x i32> %x, <i32 44, i32 60, i32 44, i32 60>
549  %b = icmp ne <4 x i32> %x, <i32 60, i32 44, i32 60, i32 44>
550  %t = and <4 x i1> %a, %b
551  %r = sext <4 x i1> %t to <4 x i32>
552  ret <4 x i32> %r
553}
554
555; Negative test - extra use prevents optimization
556
557define i1 @or_icmps_const_1bit_diff_extra_use(i8 %x, ptr %p) {
558; CHECK-LABEL: or_icmps_const_1bit_diff_extra_use:
559; CHECK:       # %bb.0:
560; CHECK-NEXT:    cmpb $45, %dil
561; CHECK-NEXT:    sete %cl
562; CHECK-NEXT:    cmpb $43, %dil
563; CHECK-NEXT:    sete %al
564; CHECK-NEXT:    sete (%rsi)
565; CHECK-NEXT:    orb %cl, %al
566; CHECK-NEXT:    retq
567  %a = icmp eq i8 %x, 43
568  %b = icmp eq i8 %x, 45
569  %r = or i1 %a, %b
570  %z = zext i1 %a to i8
571  store i8 %z, ptr %p
572  ret i1 %r
573}
574
575; Negative test - constant diff is >1 bit
576
577define i1 @and_icmps_const_not1bit_diff(i32 %x) {
578; CHECK-LABEL: and_icmps_const_not1bit_diff:
579; CHECK:       # %bb.0:
580; CHECK-NEXT:    cmpl $44, %edi
581; CHECK-NEXT:    setne %cl
582; CHECK-NEXT:    cmpl $92, %edi
583; CHECK-NEXT:    setne %al
584; CHECK-NEXT:    andb %cl, %al
585; CHECK-NEXT:    retq
586  %a = icmp ne i32 %x, 44
587  %b = icmp ne i32 %x, 92
588  %r = and i1 %a, %b
589  ret i1 %r
590}
591
592; Negative test - wrong comparison
593
594define i1 @and_icmps_const_1bit_diff_wrong_pred(i32 %x) {
595; CHECK-LABEL: and_icmps_const_1bit_diff_wrong_pred:
596; CHECK:       # %bb.0:
597; CHECK-NEXT:    cmpl $43, %edi
598; CHECK-NEXT:    sete %cl
599; CHECK-NEXT:    cmpl $45, %edi
600; CHECK-NEXT:    setl %al
601; CHECK-NEXT:    orb %cl, %al
602; CHECK-NEXT:    retq
603  %a = icmp eq i32 %x, 43
604  %b = icmp slt i32 %x, 45
605  %r = or i1 %a, %b
606  ret i1 %r
607}
608
609; Negative test - no common operand
610
611define i1 @and_icmps_const_1bit_diff_common_op(i32 %x, i32 %y) {
612; CHECK-LABEL: and_icmps_const_1bit_diff_common_op:
613; CHECK:       # %bb.0:
614; CHECK-NEXT:    cmpl $43, %edi
615; CHECK-NEXT:    sete %cl
616; CHECK-NEXT:    cmpl $45, %esi
617; CHECK-NEXT:    sete %al
618; CHECK-NEXT:    orb %cl, %al
619; CHECK-NEXT:    retq
620  %a = icmp eq i32 %x, 43
621  %b = icmp eq i32 %y, 45
622  %r = or i1 %a, %b
623  ret i1 %r
624}
625
626; PR44136 - fold cmpeq(or(X,Y),X) --> cmpeq(and(~X,Y),0)
627
628define i1 @or_cmp_eq_i64(i64 %x, i64 %y) {
629; NOBMI-LABEL: or_cmp_eq_i64:
630; NOBMI:       # %bb.0:
631; NOBMI-NEXT:    notq %rdi
632; NOBMI-NEXT:    testq %rsi, %rdi
633; NOBMI-NEXT:    sete %al
634; NOBMI-NEXT:    retq
635;
636; BMI-LABEL: or_cmp_eq_i64:
637; BMI:       # %bb.0:
638; BMI-NEXT:    andnq %rsi, %rdi, %rax
639; BMI-NEXT:    sete %al
640; BMI-NEXT:    retq
641  %o = or i64 %x, %y
642  %c = icmp eq i64 %o, %x
643  ret i1 %c
644}
645
646define i1 @or_cmp_ne_i32(i32 %x, i32 %y) {
647; NOBMI-LABEL: or_cmp_ne_i32:
648; NOBMI:       # %bb.0:
649; NOBMI-NEXT:    notl %esi
650; NOBMI-NEXT:    testl %edi, %esi
651; NOBMI-NEXT:    setne %al
652; NOBMI-NEXT:    retq
653;
654; BMI-LABEL: or_cmp_ne_i32:
655; BMI:       # %bb.0:
656; BMI-NEXT:    andnl %edi, %esi, %eax
657; BMI-NEXT:    setne %al
658; BMI-NEXT:    retq
659  %o = or i32 %x, %y
660  %c = icmp ne i32 %o, %y
661  ret i1 %c
662}
663
664define i1 @or_cmp_eq_i16(i16 zeroext %x, i16 zeroext %y) {
665; NOBMI-LABEL: or_cmp_eq_i16:
666; NOBMI:       # %bb.0:
667; NOBMI-NEXT:    notl %edi
668; NOBMI-NEXT:    testl %esi, %edi
669; NOBMI-NEXT:    sete %al
670; NOBMI-NEXT:    retq
671;
672; BMI-LABEL: or_cmp_eq_i16:
673; BMI:       # %bb.0:
674; BMI-NEXT:    andnl %esi, %edi, %eax
675; BMI-NEXT:    sete %al
676; BMI-NEXT:    retq
677  %o = or i16 %x, %y
678  %c = icmp eq i16 %x, %o
679  ret i1 %c
680}
681
682define i1 @or_cmp_ne_i8(i8 zeroext %x, i8 zeroext %y) {
683; CHECK-LABEL: or_cmp_ne_i8:
684; CHECK:       # %bb.0:
685; CHECK-NEXT:    notb %sil
686; CHECK-NEXT:    testb %dil, %sil
687; CHECK-NEXT:    setne %al
688; CHECK-NEXT:    retq
689  %o = or i8 %x, %y
690  %c = icmp ne i8 %y, %o
691  ret i1 %c
692}
693
694; Don't fold vectors.
695define <4 x i32> @or_cmp_eq_v4i32(<4 x i32> %x, <4 x i32> %y) {
696; CHECK-LABEL: or_cmp_eq_v4i32:
697; CHECK:       # %bb.0:
698; CHECK-NEXT:    por %xmm0, %xmm1
699; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
700; CHECK-NEXT:    retq
701  %o = or <4 x i32> %x, %y
702  %c = icmp eq <4 x i32> %o, %x
703  %s = sext <4 x i1> %c to <4 x i32>
704  ret <4 x i32> %s
705}
706
707define <16 x i8> @or_cmp_ne_v4i32(<16 x i8> %x, <16 x i8> %y) {
708; CHECK-LABEL: or_cmp_ne_v4i32:
709; CHECK:       # %bb.0:
710; CHECK-NEXT:    por %xmm0, %xmm1
711; CHECK-NEXT:    pcmpeqb %xmm1, %xmm0
712; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
713; CHECK-NEXT:    pxor %xmm1, %xmm0
714; CHECK-NEXT:    retq
715  %o = or <16 x i8> %x, %y
716  %c = icmp ne <16 x i8> %o, %x
717  %s = sext <16 x i1> %c to <16 x i8>
718  ret <16 x i8> %s
719}
720