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(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
119entry:
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
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:    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
146entry:
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
151
152bb1:
153  ret i32 4
154
155return:
156  ret i32 192
157}
158
159define 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
173entry:
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
178
179bb1:
180  ret i32 4
181
182return:
183  ret i32 192
184}
185
186define 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
200entry:
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
205
206bb1:
207  ret i32 4
208
209return:
210  ret i32 192
211}
212
213; PR3351 - (P != 0) | (Q != 0) -> (P|Q) != 0
214define 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
225entry:
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
230
231bb1:
232  ret i32 4
233
234return:
235  ret i32 192
236}
237
238define 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
252entry:
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
257
258bb1:
259  ret i32 4
260
261return:
262  ret i32 192
263}
264
265define 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
279entry:
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
284
285bb1:
286  ret i32 4
287
288return:
289  ret i32 192
290}
291
292define 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
306entry:
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
311
312bb1:
313  ret i32 4
314
315return:
316  ret i32 192
317}
318
319; PR44565 - https://bugs.llvm.org/show_bug.cgi?id=44565
320
321define 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
340true:
341  ret i32 42
342false:
343  ret i32 88
344}
345
346define <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
357}
358
359define <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
370}
371
372define <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
383}
384
385define <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
397}
398
399define <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
412}
413
414define <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
426}
427
428define <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
440}
441
442define <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
453}
454
455define 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
466}
467
468; PR32401 - https://bugs.llvm.org/show_bug.cgi?id=32401
469
470define 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
482}
483
484define 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
496}
497
498; This should not be transformed because vector compares + bitwise logic are faster.
499
500define <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
511}
512
513define 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
524}
525
526define <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
539}
540
541define 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
552}
553
554define <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:    pcmpeqd %xmm2, %xmm2
561; CHECK-NEXT:    pxor %xmm0, %xmm2
562; CHECK-NEXT:    pandn %xmm2, %xmm1
563; CHECK-NEXT:    movdqa %xmm1, %xmm0
564; CHECK-NEXT:    retq
565  %a = icmp ne <4 x i32> %x, <i32 44, i32 60, i32 44, i32 60>
566  %b = icmp ne <4 x i32> %x, <i32 60, i32 44, i32 60, i32 44>
567  %t = and <4 x i1> %a, %b
568  %r = sext <4 x i1> %t to <4 x i32>
569  ret <4 x i32> %r
570}
571
572; Negative test - extra use prevents optimization
573
574define i1 @or_icmps_const_1bit_diff_extra_use(i8 %x, i8* %p) {
575; CHECK-LABEL: or_icmps_const_1bit_diff_extra_use:
576; CHECK:       # %bb.0:
577; CHECK-NEXT:    cmpb $45, %dil
578; CHECK-NEXT:    sete %cl
579; CHECK-NEXT:    cmpb $43, %dil
580; CHECK-NEXT:    sete %al
581; CHECK-NEXT:    sete (%rsi)
582; CHECK-NEXT:    orb %cl, %al
583; CHECK-NEXT:    retq
584  %a = icmp eq i8 %x, 43
585  %b = icmp eq i8 %x, 45
586  %r = or i1 %a, %b
587  %z = zext i1 %a to i8
588  store i8 %z, i8* %p
589  ret i1 %r
590}
591
592; Negative test - constant diff is >1 bit
593
594define i1 @and_icmps_const_not1bit_diff(i32 %x) {
595; CHECK-LABEL: and_icmps_const_not1bit_diff:
596; CHECK:       # %bb.0:
597; CHECK-NEXT:    cmpl $44, %edi
598; CHECK-NEXT:    setne %cl
599; CHECK-NEXT:    cmpl $92, %edi
600; CHECK-NEXT:    setne %al
601; CHECK-NEXT:    andb %cl, %al
602; CHECK-NEXT:    retq
603  %a = icmp ne i32 %x, 44
604  %b = icmp ne i32 %x, 92
605  %r = and i1 %a, %b
606  ret i1 %r
607}
608
609; Negative test - wrong comparison
610
611define i1 @and_icmps_const_1bit_diff_wrong_pred(i32 %x) {
612; CHECK-LABEL: and_icmps_const_1bit_diff_wrong_pred:
613; CHECK:       # %bb.0:
614; CHECK-NEXT:    cmpl $43, %edi
615; CHECK-NEXT:    sete %cl
616; CHECK-NEXT:    cmpl $45, %edi
617; CHECK-NEXT:    setl %al
618; CHECK-NEXT:    orb %cl, %al
619; CHECK-NEXT:    retq
620  %a = icmp eq i32 %x, 43
621  %b = icmp slt i32 %x, 45
622  %r = or i1 %a, %b
623  ret i1 %r
624}
625
626; Negative test - no common operand
627
628define i1 @and_icmps_const_1bit_diff_common_op(i32 %x, i32 %y) {
629; CHECK-LABEL: and_icmps_const_1bit_diff_common_op:
630; CHECK:       # %bb.0:
631; CHECK-NEXT:    cmpl $43, %edi
632; CHECK-NEXT:    sete %cl
633; CHECK-NEXT:    cmpl $45, %esi
634; CHECK-NEXT:    sete %al
635; CHECK-NEXT:    orb %cl, %al
636; CHECK-NEXT:    retq
637  %a = icmp eq i32 %x, 43
638  %b = icmp eq i32 %y, 45
639  %r = or i1 %a, %b
640  ret i1 %r
641}
642
643; PR44136 - fold cmpeq(or(X,Y),X) --> cmpeq(and(~X,Y),0)
644
645define i1 @or_cmp_eq_i64(i64 %x, i64 %y) {
646; NOBMI-LABEL: or_cmp_eq_i64:
647; NOBMI:       # %bb.0:
648; NOBMI-NEXT:    notq %rdi
649; NOBMI-NEXT:    testq %rsi, %rdi
650; NOBMI-NEXT:    sete %al
651; NOBMI-NEXT:    retq
652;
653; BMI-LABEL: or_cmp_eq_i64:
654; BMI:       # %bb.0:
655; BMI-NEXT:    andnq %rsi, %rdi, %rax
656; BMI-NEXT:    sete %al
657; BMI-NEXT:    retq
658  %o = or i64 %x, %y
659  %c = icmp eq i64 %o, %x
660  ret i1 %c
661}
662
663define i1 @or_cmp_ne_i32(i32 %x, i32 %y) {
664; NOBMI-LABEL: or_cmp_ne_i32:
665; NOBMI:       # %bb.0:
666; NOBMI-NEXT:    notl %esi
667; NOBMI-NEXT:    testl %edi, %esi
668; NOBMI-NEXT:    setne %al
669; NOBMI-NEXT:    retq
670;
671; BMI-LABEL: or_cmp_ne_i32:
672; BMI:       # %bb.0:
673; BMI-NEXT:    andnl %edi, %esi, %eax
674; BMI-NEXT:    setne %al
675; BMI-NEXT:    retq
676  %o = or i32 %x, %y
677  %c = icmp ne i32 %o, %y
678  ret i1 %c
679}
680
681define i1 @or_cmp_eq_i16(i16 zeroext %x, i16 zeroext %y) {
682; NOBMI-LABEL: or_cmp_eq_i16:
683; NOBMI:       # %bb.0:
684; NOBMI-NEXT:    notl %edi
685; NOBMI-NEXT:    testl %esi, %edi
686; NOBMI-NEXT:    sete %al
687; NOBMI-NEXT:    retq
688;
689; BMI-LABEL: or_cmp_eq_i16:
690; BMI:       # %bb.0:
691; BMI-NEXT:    andnl %esi, %edi, %eax
692; BMI-NEXT:    sete %al
693; BMI-NEXT:    retq
694  %o = or i16 %x, %y
695  %c = icmp eq i16 %x, %o
696  ret i1 %c
697}
698
699define i1 @or_cmp_ne_i8(i8 zeroext %x, i8 zeroext %y) {
700; CHECK-LABEL: or_cmp_ne_i8:
701; CHECK:       # %bb.0:
702; CHECK-NEXT:    notb %sil
703; CHECK-NEXT:    testb %dil, %sil
704; CHECK-NEXT:    setne %al
705; CHECK-NEXT:    retq
706  %o = or i8 %x, %y
707  %c = icmp ne i8 %y, %o
708  ret i1 %c
709}
710
711; Don't fold vectors.
712define <4 x i32> @or_cmp_eq_v4i32(<4 x i32> %x, <4 x i32> %y) {
713; CHECK-LABEL: or_cmp_eq_v4i32:
714; CHECK:       # %bb.0:
715; CHECK-NEXT:    por %xmm0, %xmm1
716; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
717; CHECK-NEXT:    retq
718  %o = or <4 x i32> %x, %y
719  %c = icmp eq <4 x i32> %o, %x
720  %s = sext <4 x i1> %c to <4 x i32>
721  ret <4 x i32> %s
722}
723
724define <16 x i8> @or_cmp_ne_v4i32(<16 x i8> %x, <16 x i8> %y) {
725; CHECK-LABEL: or_cmp_ne_v4i32:
726; CHECK:       # %bb.0:
727; CHECK-NEXT:    por %xmm0, %xmm1
728; CHECK-NEXT:    pcmpeqb %xmm1, %xmm0
729; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
730; CHECK-NEXT:    pxor %xmm1, %xmm0
731; CHECK-NEXT:    retq
732  %o = or <16 x i8> %x, %y
733  %c = icmp ne <16 x i8> %o, %x
734  %s = sext <16 x i1> %c to <16 x i8>
735  ret <16 x i8> %s
736}
737