xref: /llvm-project/llvm/test/CodeGen/X86/hoist-and-by-const-from-lshr-in-eqcmp-zero.ll (revision 4318b033bddc64d5654f3e368fddde859ff4d02e)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+sse,sse2                  < %s | FileCheck %s --check-prefixes=CHECK,SSE2,X86,X86-SSE2,X86-BMI1
3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+sse,sse2,+bmi             < %s | FileCheck %s --check-prefixes=CHECK,SSE2,X86,X86-SSE2,X86-BMI1
4; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+sse,sse2,+bmi,+bmi2       < %s | FileCheck %s --check-prefixes=CHECK,SSE2,X86,X86-SSE2,X86-BMI2
5; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+sse,sse2,+bmi,+bmi2,+avx2 < %s | FileCheck %s --check-prefixes=CHECK,AVX2,X86,X86-BMI2
6; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+sse,sse2                  < %s | FileCheck %s --check-prefixes=CHECK,SSE2,X64,X64-SSE2,X64-BMI1
7; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+sse,sse2,+bmi             < %s | FileCheck %s --check-prefixes=CHECK,SSE2,X64,X64-SSE2,X64-BMI1
8; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+sse,sse2,+bmi,+bmi2       < %s | FileCheck %s --check-prefixes=CHECK,SSE2,X64,X64-SSE2,X64-BMI2
9; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+sse,sse2,+bmi,+bmi2,+avx2 < %s | FileCheck %s --check-prefixes=CHECK,AVX2,X64,X64-BMI2
10
11; We are looking for the following pattern here:
12;   (X & (C l>> Y)) ==/!= 0
13; It may be optimal to hoist the constant:
14;   ((X << Y) & C) ==/!= 0
15
16;------------------------------------------------------------------------------;
17; A few scalar test
18;------------------------------------------------------------------------------;
19
20; i8 scalar
21
22define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
23; X86-LABEL: scalar_i8_signbit_eq:
24; X86:       # %bb.0:
25; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
26; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
27; X86-NEXT:    shlb %cl, %al
28; X86-NEXT:    testb $-128, %al
29; X86-NEXT:    sete %al
30; X86-NEXT:    retl
31;
32; X64-LABEL: scalar_i8_signbit_eq:
33; X64:       # %bb.0:
34; X64-NEXT:    movl %esi, %ecx
35; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
36; X64-NEXT:    shlb %cl, %dil
37; X64-NEXT:    testb $-128, %dil
38; X64-NEXT:    sete %al
39; X64-NEXT:    retq
40  %t0 = lshr i8 128, %y
41  %t1 = and i8 %t0, %x
42  %res = icmp eq i8 %t1, 0
43  ret i1 %res
44}
45
46define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
47; X86-LABEL: scalar_i8_lowestbit_eq:
48; X86:       # %bb.0:
49; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
50; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
51; X86-NEXT:    shlb %cl, %al
52; X86-NEXT:    testb $1, %al
53; X86-NEXT:    sete %al
54; X86-NEXT:    retl
55;
56; X64-LABEL: scalar_i8_lowestbit_eq:
57; X64:       # %bb.0:
58; X64-NEXT:    movl %esi, %ecx
59; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
60; X64-NEXT:    shlb %cl, %dil
61; X64-NEXT:    testb $1, %dil
62; X64-NEXT:    sete %al
63; X64-NEXT:    retq
64  %t0 = lshr i8 1, %y
65  %t1 = and i8 %t0, %x
66  %res = icmp eq i8 %t1, 0
67  ret i1 %res
68}
69
70define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
71; X86-LABEL: scalar_i8_bitsinmiddle_eq:
72; X86:       # %bb.0:
73; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
74; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
75; X86-NEXT:    shlb %cl, %al
76; X86-NEXT:    testb $24, %al
77; X86-NEXT:    sete %al
78; X86-NEXT:    retl
79;
80; X64-LABEL: scalar_i8_bitsinmiddle_eq:
81; X64:       # %bb.0:
82; X64-NEXT:    movl %esi, %ecx
83; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
84; X64-NEXT:    shlb %cl, %dil
85; X64-NEXT:    testb $24, %dil
86; X64-NEXT:    sete %al
87; X64-NEXT:    retq
88  %t0 = lshr i8 24, %y
89  %t1 = and i8 %t0, %x
90  %res = icmp eq i8 %t1, 0
91  ret i1 %res
92}
93
94; i16 scalar
95
96define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
97; X86-BMI1-LABEL: scalar_i16_signbit_eq:
98; X86-BMI1:       # %bb.0:
99; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
100; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
101; X86-BMI1-NEXT:    shll %cl, %eax
102; X86-BMI1-NEXT:    testl $32768, %eax # imm = 0x8000
103; X86-BMI1-NEXT:    sete %al
104; X86-BMI1-NEXT:    retl
105;
106; X86-BMI2-LABEL: scalar_i16_signbit_eq:
107; X86-BMI2:       # %bb.0:
108; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
109; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %eax
110; X86-BMI2-NEXT:    testl $32768, %eax # imm = 0x8000
111; X86-BMI2-NEXT:    sete %al
112; X86-BMI2-NEXT:    retl
113;
114; X64-BMI1-LABEL: scalar_i16_signbit_eq:
115; X64-BMI1:       # %bb.0:
116; X64-BMI1-NEXT:    movl %esi, %ecx
117; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
118; X64-BMI1-NEXT:    shll %cl, %edi
119; X64-BMI1-NEXT:    testl $32768, %edi # imm = 0x8000
120; X64-BMI1-NEXT:    sete %al
121; X64-BMI1-NEXT:    retq
122;
123; X64-BMI2-LABEL: scalar_i16_signbit_eq:
124; X64-BMI2:       # %bb.0:
125; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
126; X64-BMI2-NEXT:    testl $32768, %eax # imm = 0x8000
127; X64-BMI2-NEXT:    sete %al
128; X64-BMI2-NEXT:    retq
129  %t0 = lshr i16 32768, %y
130  %t1 = and i16 %t0, %x
131  %res = icmp eq i16 %t1, 0
132  ret i1 %res
133}
134
135define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
136; X86-BMI1-LABEL: scalar_i16_lowestbit_eq:
137; X86-BMI1:       # %bb.0:
138; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
139; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
140; X86-BMI1-NEXT:    shll %cl, %eax
141; X86-BMI1-NEXT:    testb $1, %al
142; X86-BMI1-NEXT:    sete %al
143; X86-BMI1-NEXT:    retl
144;
145; X86-BMI2-LABEL: scalar_i16_lowestbit_eq:
146; X86-BMI2:       # %bb.0:
147; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
148; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %eax
149; X86-BMI2-NEXT:    testb $1, %al
150; X86-BMI2-NEXT:    sete %al
151; X86-BMI2-NEXT:    retl
152;
153; X64-BMI1-LABEL: scalar_i16_lowestbit_eq:
154; X64-BMI1:       # %bb.0:
155; X64-BMI1-NEXT:    movl %esi, %ecx
156; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
157; X64-BMI1-NEXT:    shll %cl, %edi
158; X64-BMI1-NEXT:    testb $1, %dil
159; X64-BMI1-NEXT:    sete %al
160; X64-BMI1-NEXT:    retq
161;
162; X64-BMI2-LABEL: scalar_i16_lowestbit_eq:
163; X64-BMI2:       # %bb.0:
164; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
165; X64-BMI2-NEXT:    testb $1, %al
166; X64-BMI2-NEXT:    sete %al
167; X64-BMI2-NEXT:    retq
168  %t0 = lshr i16 1, %y
169  %t1 = and i16 %t0, %x
170  %res = icmp eq i16 %t1, 0
171  ret i1 %res
172}
173
174define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
175; X86-BMI1-LABEL: scalar_i16_bitsinmiddle_eq:
176; X86-BMI1:       # %bb.0:
177; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
178; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
179; X86-BMI1-NEXT:    shll %cl, %eax
180; X86-BMI1-NEXT:    testl $4080, %eax # imm = 0xFF0
181; X86-BMI1-NEXT:    sete %al
182; X86-BMI1-NEXT:    retl
183;
184; X86-BMI2-LABEL: scalar_i16_bitsinmiddle_eq:
185; X86-BMI2:       # %bb.0:
186; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
187; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %eax
188; X86-BMI2-NEXT:    testl $4080, %eax # imm = 0xFF0
189; X86-BMI2-NEXT:    sete %al
190; X86-BMI2-NEXT:    retl
191;
192; X64-BMI1-LABEL: scalar_i16_bitsinmiddle_eq:
193; X64-BMI1:       # %bb.0:
194; X64-BMI1-NEXT:    movl %esi, %ecx
195; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
196; X64-BMI1-NEXT:    shll %cl, %edi
197; X64-BMI1-NEXT:    testl $4080, %edi # imm = 0xFF0
198; X64-BMI1-NEXT:    sete %al
199; X64-BMI1-NEXT:    retq
200;
201; X64-BMI2-LABEL: scalar_i16_bitsinmiddle_eq:
202; X64-BMI2:       # %bb.0:
203; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
204; X64-BMI2-NEXT:    testl $4080, %eax # imm = 0xFF0
205; X64-BMI2-NEXT:    sete %al
206; X64-BMI2-NEXT:    retq
207  %t0 = lshr i16 4080, %y
208  %t1 = and i16 %t0, %x
209  %res = icmp eq i16 %t1, 0
210  ret i1 %res
211}
212
213; i32 scalar
214
215define i1 @scalar_i32_signbit_eq(i32 %x, i32 %y) nounwind {
216; X86-BMI1-LABEL: scalar_i32_signbit_eq:
217; X86-BMI1:       # %bb.0:
218; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
219; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
220; X86-BMI1-NEXT:    shll %cl, %eax
221; X86-BMI1-NEXT:    testl $-2147483648, %eax # imm = 0x80000000
222; X86-BMI1-NEXT:    sete %al
223; X86-BMI1-NEXT:    retl
224;
225; X86-BMI2-LABEL: scalar_i32_signbit_eq:
226; X86-BMI2:       # %bb.0:
227; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
228; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %eax
229; X86-BMI2-NEXT:    testl $-2147483648, %eax # imm = 0x80000000
230; X86-BMI2-NEXT:    sete %al
231; X86-BMI2-NEXT:    retl
232;
233; X64-BMI1-LABEL: scalar_i32_signbit_eq:
234; X64-BMI1:       # %bb.0:
235; X64-BMI1-NEXT:    movl %esi, %ecx
236; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
237; X64-BMI1-NEXT:    shll %cl, %edi
238; X64-BMI1-NEXT:    testl $-2147483648, %edi # imm = 0x80000000
239; X64-BMI1-NEXT:    sete %al
240; X64-BMI1-NEXT:    retq
241;
242; X64-BMI2-LABEL: scalar_i32_signbit_eq:
243; X64-BMI2:       # %bb.0:
244; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
245; X64-BMI2-NEXT:    testl $-2147483648, %eax # imm = 0x80000000
246; X64-BMI2-NEXT:    sete %al
247; X64-BMI2-NEXT:    retq
248  %t0 = lshr i32 2147483648, %y
249  %t1 = and i32 %t0, %x
250  %res = icmp eq i32 %t1, 0
251  ret i1 %res
252}
253
254define i1 @scalar_i32_lowestbit_eq(i32 %x, i32 %y) nounwind {
255; X86-BMI1-LABEL: scalar_i32_lowestbit_eq:
256; X86-BMI1:       # %bb.0:
257; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
258; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
259; X86-BMI1-NEXT:    shll %cl, %eax
260; X86-BMI1-NEXT:    testb $1, %al
261; X86-BMI1-NEXT:    sete %al
262; X86-BMI1-NEXT:    retl
263;
264; X86-BMI2-LABEL: scalar_i32_lowestbit_eq:
265; X86-BMI2:       # %bb.0:
266; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
267; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %eax
268; X86-BMI2-NEXT:    testb $1, %al
269; X86-BMI2-NEXT:    sete %al
270; X86-BMI2-NEXT:    retl
271;
272; X64-BMI1-LABEL: scalar_i32_lowestbit_eq:
273; X64-BMI1:       # %bb.0:
274; X64-BMI1-NEXT:    movl %esi, %ecx
275; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
276; X64-BMI1-NEXT:    shll %cl, %edi
277; X64-BMI1-NEXT:    testb $1, %dil
278; X64-BMI1-NEXT:    sete %al
279; X64-BMI1-NEXT:    retq
280;
281; X64-BMI2-LABEL: scalar_i32_lowestbit_eq:
282; X64-BMI2:       # %bb.0:
283; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
284; X64-BMI2-NEXT:    testb $1, %al
285; X64-BMI2-NEXT:    sete %al
286; X64-BMI2-NEXT:    retq
287  %t0 = lshr i32 1, %y
288  %t1 = and i32 %t0, %x
289  %res = icmp eq i32 %t1, 0
290  ret i1 %res
291}
292
293define i1 @scalar_i32_bitsinmiddle_eq(i32 %x, i32 %y) nounwind {
294; X86-BMI1-LABEL: scalar_i32_bitsinmiddle_eq:
295; X86-BMI1:       # %bb.0:
296; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
297; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
298; X86-BMI1-NEXT:    shll %cl, %eax
299; X86-BMI1-NEXT:    testl $16776960, %eax # imm = 0xFFFF00
300; X86-BMI1-NEXT:    sete %al
301; X86-BMI1-NEXT:    retl
302;
303; X86-BMI2-LABEL: scalar_i32_bitsinmiddle_eq:
304; X86-BMI2:       # %bb.0:
305; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
306; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %eax
307; X86-BMI2-NEXT:    testl $16776960, %eax # imm = 0xFFFF00
308; X86-BMI2-NEXT:    sete %al
309; X86-BMI2-NEXT:    retl
310;
311; X64-BMI1-LABEL: scalar_i32_bitsinmiddle_eq:
312; X64-BMI1:       # %bb.0:
313; X64-BMI1-NEXT:    movl %esi, %ecx
314; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
315; X64-BMI1-NEXT:    shll %cl, %edi
316; X64-BMI1-NEXT:    testl $16776960, %edi # imm = 0xFFFF00
317; X64-BMI1-NEXT:    sete %al
318; X64-BMI1-NEXT:    retq
319;
320; X64-BMI2-LABEL: scalar_i32_bitsinmiddle_eq:
321; X64-BMI2:       # %bb.0:
322; X64-BMI2-NEXT:    shlxl %esi, %edi, %eax
323; X64-BMI2-NEXT:    testl $16776960, %eax # imm = 0xFFFF00
324; X64-BMI2-NEXT:    sete %al
325; X64-BMI2-NEXT:    retq
326  %t0 = lshr i32 16776960, %y
327  %t1 = and i32 %t0, %x
328  %res = icmp eq i32 %t1, 0
329  ret i1 %res
330}
331
332; i64 scalar
333
334define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
335; X86-BMI1-LABEL: scalar_i64_signbit_eq:
336; X86-BMI1:       # %bb.0:
337; X86-BMI1-NEXT:    pushl %esi
338; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
339; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
340; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edx
341; X86-BMI1-NEXT:    movl %eax, %esi
342; X86-BMI1-NEXT:    shll %cl, %esi
343; X86-BMI1-NEXT:    shldl %cl, %eax, %edx
344; X86-BMI1-NEXT:    testb $32, %cl
345; X86-BMI1-NEXT:    cmovnel %esi, %edx
346; X86-BMI1-NEXT:    testl $-2147483648, %edx # imm = 0x80000000
347; X86-BMI1-NEXT:    sete %al
348; X86-BMI1-NEXT:    popl %esi
349; X86-BMI1-NEXT:    retl
350;
351; X86-BMI2-LABEL: scalar_i64_signbit_eq:
352; X86-BMI2:       # %bb.0:
353; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
354; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
355; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
356; X86-BMI2-NEXT:    shldl %cl, %eax, %edx
357; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
358; X86-BMI2-NEXT:    testb $32, %cl
359; X86-BMI2-NEXT:    cmovel %edx, %eax
360; X86-BMI2-NEXT:    testl $-2147483648, %eax # imm = 0x80000000
361; X86-BMI2-NEXT:    sete %al
362; X86-BMI2-NEXT:    retl
363;
364; X64-BMI1-LABEL: scalar_i64_signbit_eq:
365; X64-BMI1:       # %bb.0:
366; X64-BMI1-NEXT:    movq %rsi, %rcx
367; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $rcx
368; X64-BMI1-NEXT:    shlq %cl, %rdi
369; X64-BMI1-NEXT:    shrq $63, %rdi
370; X64-BMI1-NEXT:    sete %al
371; X64-BMI1-NEXT:    retq
372;
373; X64-BMI2-LABEL: scalar_i64_signbit_eq:
374; X64-BMI2:       # %bb.0:
375; X64-BMI2-NEXT:    shlxq %rsi, %rdi, %rax
376; X64-BMI2-NEXT:    shrq $63, %rax
377; X64-BMI2-NEXT:    sete %al
378; X64-BMI2-NEXT:    retq
379  %t0 = lshr i64 9223372036854775808, %y
380  %t1 = and i64 %t0, %x
381  %res = icmp eq i64 %t1, 0
382  ret i1 %res
383}
384
385define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
386; X86-BMI1-LABEL: scalar_i64_lowestbit_eq:
387; X86-BMI1:       # %bb.0:
388; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
389; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
390; X86-BMI1-NEXT:    shll %cl, %eax
391; X86-BMI1-NEXT:    xorl %edx, %edx
392; X86-BMI1-NEXT:    testb $32, %cl
393; X86-BMI1-NEXT:    cmovel %eax, %edx
394; X86-BMI1-NEXT:    testb $1, %dl
395; X86-BMI1-NEXT:    sete %al
396; X86-BMI1-NEXT:    retl
397;
398; X86-BMI2-LABEL: scalar_i64_lowestbit_eq:
399; X86-BMI2:       # %bb.0:
400; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
401; X86-BMI2-NEXT:    shlxl %eax, {{[0-9]+}}(%esp), %ecx
402; X86-BMI2-NEXT:    xorl %edx, %edx
403; X86-BMI2-NEXT:    testb $32, %al
404; X86-BMI2-NEXT:    cmovel %ecx, %edx
405; X86-BMI2-NEXT:    testb $1, %dl
406; X86-BMI2-NEXT:    sete %al
407; X86-BMI2-NEXT:    retl
408;
409; X64-BMI1-LABEL: scalar_i64_lowestbit_eq:
410; X64-BMI1:       # %bb.0:
411; X64-BMI1-NEXT:    movq %rsi, %rcx
412; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $rcx
413; X64-BMI1-NEXT:    shlq %cl, %rdi
414; X64-BMI1-NEXT:    testb $1, %dil
415; X64-BMI1-NEXT:    sete %al
416; X64-BMI1-NEXT:    retq
417;
418; X64-BMI2-LABEL: scalar_i64_lowestbit_eq:
419; X64-BMI2:       # %bb.0:
420; X64-BMI2-NEXT:    shlxq %rsi, %rdi, %rax
421; X64-BMI2-NEXT:    testb $1, %al
422; X64-BMI2-NEXT:    sete %al
423; X64-BMI2-NEXT:    retq
424  %t0 = lshr i64 1, %y
425  %t1 = and i64 %t0, %x
426  %res = icmp eq i64 %t1, 0
427  ret i1 %res
428}
429
430define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
431; X86-BMI1-LABEL: scalar_i64_bitsinmiddle_eq:
432; X86-BMI1:       # %bb.0:
433; X86-BMI1-NEXT:    pushl %esi
434; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
435; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %eax
436; X86-BMI1-NEXT:    movl {{[0-9]+}}(%esp), %edx
437; X86-BMI1-NEXT:    movl %eax, %esi
438; X86-BMI1-NEXT:    shll %cl, %esi
439; X86-BMI1-NEXT:    shldl %cl, %eax, %edx
440; X86-BMI1-NEXT:    xorl %eax, %eax
441; X86-BMI1-NEXT:    testb $32, %cl
442; X86-BMI1-NEXT:    cmovnel %esi, %edx
443; X86-BMI1-NEXT:    movzwl %dx, %ecx
444; X86-BMI1-NEXT:    cmovel %esi, %eax
445; X86-BMI1-NEXT:    andl $-65536, %eax # imm = 0xFFFF0000
446; X86-BMI1-NEXT:    orl %ecx, %eax
447; X86-BMI1-NEXT:    sete %al
448; X86-BMI1-NEXT:    popl %esi
449; X86-BMI1-NEXT:    retl
450;
451; X86-BMI2-LABEL: scalar_i64_bitsinmiddle_eq:
452; X86-BMI2:       # %bb.0:
453; X86-BMI2-NEXT:    pushl %esi
454; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
455; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %eax
456; X86-BMI2-NEXT:    movl {{[0-9]+}}(%esp), %edx
457; X86-BMI2-NEXT:    shldl %cl, %eax, %edx
458; X86-BMI2-NEXT:    shlxl %ecx, %eax, %eax
459; X86-BMI2-NEXT:    xorl %esi, %esi
460; X86-BMI2-NEXT:    testb $32, %cl
461; X86-BMI2-NEXT:    cmovnel %eax, %edx
462; X86-BMI2-NEXT:    movzwl %dx, %ecx
463; X86-BMI2-NEXT:    cmovel %eax, %esi
464; X86-BMI2-NEXT:    andl $-65536, %esi # imm = 0xFFFF0000
465; X86-BMI2-NEXT:    orl %ecx, %esi
466; X86-BMI2-NEXT:    sete %al
467; X86-BMI2-NEXT:    popl %esi
468; X86-BMI2-NEXT:    retl
469;
470; X64-BMI1-LABEL: scalar_i64_bitsinmiddle_eq:
471; X64-BMI1:       # %bb.0:
472; X64-BMI1-NEXT:    movq %rsi, %rcx
473; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $rcx
474; X64-BMI1-NEXT:    shlq %cl, %rdi
475; X64-BMI1-NEXT:    shrq $16, %rdi
476; X64-BMI1-NEXT:    testl %edi, %edi
477; X64-BMI1-NEXT:    sete %al
478; X64-BMI1-NEXT:    retq
479;
480; X64-BMI2-LABEL: scalar_i64_bitsinmiddle_eq:
481; X64-BMI2:       # %bb.0:
482; X64-BMI2-NEXT:    shlxq %rsi, %rdi, %rax
483; X64-BMI2-NEXT:    shrq $16, %rax
484; X64-BMI2-NEXT:    testl %eax, %eax
485; X64-BMI2-NEXT:    sete %al
486; X64-BMI2-NEXT:    retq
487  %t0 = lshr i64 281474976645120, %y
488  %t1 = and i64 %t0, %x
489  %res = icmp eq i64 %t1, 0
490  ret i1 %res
491}
492
493;------------------------------------------------------------------------------;
494; A few trivial vector tests
495;------------------------------------------------------------------------------;
496
497define <4 x i1> @vec_4xi32_splat_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
498; X86-SSE2-LABEL: vec_4xi32_splat_eq:
499; X86-SSE2:       # %bb.0:
500; X86-SSE2-NEXT:    pxor %xmm2, %xmm2
501; X86-SSE2-NEXT:    pslld $23, %xmm1
502; X86-SSE2-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1
503; X86-SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
504; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3]
505; X86-SSE2-NEXT:    pmuludq %xmm1, %xmm0
506; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
507; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
508; X86-SSE2-NEXT:    pmuludq %xmm3, %xmm1
509; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
510; X86-SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
511; X86-SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
512; X86-SSE2-NEXT:    pcmpeqd %xmm2, %xmm0
513; X86-SSE2-NEXT:    retl
514;
515; AVX2-LABEL: vec_4xi32_splat_eq:
516; AVX2:       # %bb.0:
517; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [1,1,1,1]
518; AVX2-NEXT:    vpxor %xmm3, %xmm3, %xmm3
519; AVX2-NEXT:    vpsllvd %xmm1, %xmm0, %xmm0
520; AVX2-NEXT:    vpand %xmm2, %xmm0, %xmm0
521; AVX2-NEXT:    vpcmpeqd %xmm3, %xmm0, %xmm0
522; AVX2-NEXT:    ret{{[l|q]}}
523;
524; X64-SSE2-LABEL: vec_4xi32_splat_eq:
525; X64-SSE2:       # %bb.0:
526; X64-SSE2-NEXT:    pxor %xmm2, %xmm2
527; X64-SSE2-NEXT:    pslld $23, %xmm1
528; X64-SSE2-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
529; X64-SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
530; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3]
531; X64-SSE2-NEXT:    pmuludq %xmm1, %xmm0
532; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
533; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
534; X64-SSE2-NEXT:    pmuludq %xmm3, %xmm1
535; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
536; X64-SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
537; X64-SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
538; X64-SSE2-NEXT:    pcmpeqd %xmm2, %xmm0
539; X64-SSE2-NEXT:    retq
540  %t0 = lshr <4 x i32> <i32 1, i32 1, i32 1, i32 1>, %y
541  %t1 = and <4 x i32> %t0, %x
542  %res = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 0, i32 0>
543  ret <4 x i1> %res
544}
545
546define <4 x i1> @vec_4xi32_nonsplat_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
547; SSE2-LABEL: vec_4xi32_nonsplat_eq:
548; SSE2:       # %bb.0:
549; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3]
550; SSE2-NEXT:    pshuflw {{.*#+}} xmm3 = xmm2[2,3,3,3,4,5,6,7]
551; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [0,1,16776960,2147483648]
552; SSE2-NEXT:    movdqa %xmm4, %xmm5
553; SSE2-NEXT:    psrld %xmm3, %xmm5
554; SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[0,1,1,1,4,5,6,7]
555; SSE2-NEXT:    movdqa %xmm4, %xmm3
556; SSE2-NEXT:    psrld %xmm2, %xmm3
557; SSE2-NEXT:    punpckhqdq {{.*#+}} xmm3 = xmm3[1],xmm5[1]
558; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[2,3,3,3,4,5,6,7]
559; SSE2-NEXT:    psrld %xmm1, %xmm4
560; SSE2-NEXT:    pslldq {{.*#+}} xmm4 = zero,zero,zero,zero,zero,zero,zero,zero,xmm4[0,1,2,3,4,5,6,7]
561; SSE2-NEXT:    shufps {{.*#+}} xmm4 = xmm4[0,3],xmm3[0,3]
562; SSE2-NEXT:    andps %xmm4, %xmm0
563; SSE2-NEXT:    pxor %xmm1, %xmm1
564; SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
565; SSE2-NEXT:    ret{{[l|q]}}
566;
567; AVX2-LABEL: vec_4xi32_nonsplat_eq:
568; AVX2:       # %bb.0:
569; AVX2-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,16776960,2147483648]
570; AVX2-NEXT:    vpsrlvd %xmm1, %xmm2, %xmm1
571; AVX2-NEXT:    vpand %xmm0, %xmm1, %xmm0
572; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
573; AVX2-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
574; AVX2-NEXT:    ret{{[l|q]}}
575  %t0 = lshr <4 x i32> <i32 0, i32 1, i32 16776960, i32 2147483648>, %y
576  %t1 = and <4 x i32> %t0, %x
577  %res = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 0, i32 0>
578  ret <4 x i1> %res
579}
580
581define <4 x i1> @vec_4xi32_nonsplat_undef0_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
582; X86-SSE2-LABEL: vec_4xi32_nonsplat_undef0_eq:
583; X86-SSE2:       # %bb.0:
584; X86-SSE2-NEXT:    pxor %xmm2, %xmm2
585; X86-SSE2-NEXT:    pslld $23, %xmm1
586; X86-SSE2-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1
587; X86-SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
588; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3]
589; X86-SSE2-NEXT:    pmuludq %xmm1, %xmm0
590; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
591; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
592; X86-SSE2-NEXT:    pmuludq %xmm3, %xmm1
593; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
594; X86-SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
595; X86-SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
596; X86-SSE2-NEXT:    pcmpeqd %xmm2, %xmm0
597; X86-SSE2-NEXT:    retl
598;
599; AVX2-LABEL: vec_4xi32_nonsplat_undef0_eq:
600; AVX2:       # %bb.0:
601; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [1,1,1,1]
602; AVX2-NEXT:    vpxor %xmm3, %xmm3, %xmm3
603; AVX2-NEXT:    vpsllvd %xmm1, %xmm0, %xmm0
604; AVX2-NEXT:    vpand %xmm2, %xmm0, %xmm0
605; AVX2-NEXT:    vpcmpeqd %xmm3, %xmm0, %xmm0
606; AVX2-NEXT:    ret{{[l|q]}}
607;
608; X64-SSE2-LABEL: vec_4xi32_nonsplat_undef0_eq:
609; X64-SSE2:       # %bb.0:
610; X64-SSE2-NEXT:    pxor %xmm2, %xmm2
611; X64-SSE2-NEXT:    pslld $23, %xmm1
612; X64-SSE2-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
613; X64-SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
614; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3]
615; X64-SSE2-NEXT:    pmuludq %xmm1, %xmm0
616; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
617; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
618; X64-SSE2-NEXT:    pmuludq %xmm3, %xmm1
619; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
620; X64-SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
621; X64-SSE2-NEXT:    pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
622; X64-SSE2-NEXT:    pcmpeqd %xmm2, %xmm0
623; X64-SSE2-NEXT:    retq
624  %t0 = lshr <4 x i32> <i32 1, i32 1, i32 undef, i32 1>, %y
625  %t1 = and <4 x i32> %t0, %x
626  %res = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 0, i32 0>
627  ret <4 x i1> %res
628}
629define <4 x i1> @vec_4xi32_nonsplat_undef1_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
630; X86-SSE2-LABEL: vec_4xi32_nonsplat_undef1_eq:
631; X86-SSE2:       # %bb.0:
632; X86-SSE2-NEXT:    pshuflw {{.*#+}} xmm3 = xmm1[2,3,3,3,4,5,6,7]
633; X86-SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [1,1,1,1]
634; X86-SSE2-NEXT:    movdqa %xmm2, %xmm4
635; X86-SSE2-NEXT:    psrld %xmm3, %xmm4
636; X86-SSE2-NEXT:    pshuflw {{.*#+}} xmm3 = xmm1[0,1,1,1,4,5,6,7]
637; X86-SSE2-NEXT:    movdqa %xmm2, %xmm5
638; X86-SSE2-NEXT:    psrld %xmm3, %xmm5
639; X86-SSE2-NEXT:    punpcklqdq {{.*#+}} xmm5 = xmm5[0],xmm4[0]
640; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,2,3]
641; X86-SSE2-NEXT:    pshuflw {{.*#+}} xmm3 = xmm1[2,3,3,3,4,5,6,7]
642; X86-SSE2-NEXT:    movdqa %xmm2, %xmm4
643; X86-SSE2-NEXT:    psrld %xmm3, %xmm4
644; X86-SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,1,1,4,5,6,7]
645; X86-SSE2-NEXT:    psrld %xmm1, %xmm2
646; X86-SSE2-NEXT:    punpckhqdq {{.*#+}} xmm2 = xmm2[1],xmm4[1]
647; X86-SSE2-NEXT:    shufps {{.*#+}} xmm5 = xmm5[0,3],xmm2[0,3]
648; X86-SSE2-NEXT:    andps %xmm5, %xmm0
649; X86-SSE2-NEXT:    pxor %xmm1, %xmm1
650; X86-SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
651; X86-SSE2-NEXT:    retl
652;
653; AVX2-LABEL: vec_4xi32_nonsplat_undef1_eq:
654; AVX2:       # %bb.0:
655; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [1,1,1,1]
656; AVX2-NEXT:    vpsrlvd %xmm1, %xmm2, %xmm1
657; AVX2-NEXT:    vpand %xmm0, %xmm1, %xmm0
658; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
659; AVX2-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
660; AVX2-NEXT:    ret{{[l|q]}}
661;
662; X64-SSE2-LABEL: vec_4xi32_nonsplat_undef1_eq:
663; X64-SSE2:       # %bb.0:
664; X64-SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[2,3,3,3,4,5,6,7]
665; X64-SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [1,1,1,1]
666; X64-SSE2-NEXT:    movdqa %xmm3, %xmm4
667; X64-SSE2-NEXT:    psrld %xmm2, %xmm4
668; X64-SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[0,1,1,1,4,5,6,7]
669; X64-SSE2-NEXT:    movdqa %xmm3, %xmm5
670; X64-SSE2-NEXT:    psrld %xmm2, %xmm5
671; X64-SSE2-NEXT:    punpcklqdq {{.*#+}} xmm5 = xmm5[0],xmm4[0]
672; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,2,3]
673; X64-SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[2,3,3,3,4,5,6,7]
674; X64-SSE2-NEXT:    movdqa %xmm3, %xmm4
675; X64-SSE2-NEXT:    psrld %xmm2, %xmm4
676; X64-SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,1,1,4,5,6,7]
677; X64-SSE2-NEXT:    psrld %xmm1, %xmm3
678; X64-SSE2-NEXT:    punpckhqdq {{.*#+}} xmm3 = xmm3[1],xmm4[1]
679; X64-SSE2-NEXT:    shufps {{.*#+}} xmm5 = xmm5[0,3],xmm3[0,3]
680; X64-SSE2-NEXT:    andps %xmm5, %xmm0
681; X64-SSE2-NEXT:    pxor %xmm1, %xmm1
682; X64-SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
683; X64-SSE2-NEXT:    retq
684  %t0 = lshr <4 x i32> <i32 1, i32 1, i32 1, i32 1>, %y
685  %t1 = and <4 x i32> %t0, %x
686  %res = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 undef, i32 0>
687  ret <4 x i1> %res
688}
689define <4 x i1> @vec_4xi32_nonsplat_undef2_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
690; X86-SSE2-LABEL: vec_4xi32_nonsplat_undef2_eq:
691; X86-SSE2:       # %bb.0:
692; X86-SSE2-NEXT:    pshuflw {{.*#+}} xmm3 = xmm1[2,3,3,3,4,5,6,7]
693; X86-SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [1,1,u,1]
694; X86-SSE2-NEXT:    movdqa %xmm2, %xmm4
695; X86-SSE2-NEXT:    psrld %xmm3, %xmm4
696; X86-SSE2-NEXT:    pshuflw {{.*#+}} xmm3 = xmm1[0,1,1,1,4,5,6,7]
697; X86-SSE2-NEXT:    movdqa %xmm2, %xmm5
698; X86-SSE2-NEXT:    psrld %xmm3, %xmm5
699; X86-SSE2-NEXT:    punpcklqdq {{.*#+}} xmm5 = xmm5[0],xmm4[0]
700; X86-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,2,3]
701; X86-SSE2-NEXT:    pshuflw {{.*#+}} xmm3 = xmm1[2,3,3,3,4,5,6,7]
702; X86-SSE2-NEXT:    movdqa %xmm2, %xmm4
703; X86-SSE2-NEXT:    psrld %xmm3, %xmm4
704; X86-SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,1,1,4,5,6,7]
705; X86-SSE2-NEXT:    psrld %xmm1, %xmm2
706; X86-SSE2-NEXT:    punpckhqdq {{.*#+}} xmm2 = xmm2[1],xmm4[1]
707; X86-SSE2-NEXT:    shufps {{.*#+}} xmm5 = xmm5[0,3],xmm2[0,3]
708; X86-SSE2-NEXT:    andps %xmm5, %xmm0
709; X86-SSE2-NEXT:    pxor %xmm1, %xmm1
710; X86-SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
711; X86-SSE2-NEXT:    retl
712;
713; AVX2-LABEL: vec_4xi32_nonsplat_undef2_eq:
714; AVX2:       # %bb.0:
715; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [1,1,1,1]
716; AVX2-NEXT:    vpsrlvd %xmm1, %xmm2, %xmm1
717; AVX2-NEXT:    vpand %xmm0, %xmm1, %xmm0
718; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
719; AVX2-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
720; AVX2-NEXT:    ret{{[l|q]}}
721;
722; X64-SSE2-LABEL: vec_4xi32_nonsplat_undef2_eq:
723; X64-SSE2:       # %bb.0:
724; X64-SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[2,3,3,3,4,5,6,7]
725; X64-SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [1,1,u,1]
726; X64-SSE2-NEXT:    movdqa %xmm3, %xmm4
727; X64-SSE2-NEXT:    psrld %xmm2, %xmm4
728; X64-SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[0,1,1,1,4,5,6,7]
729; X64-SSE2-NEXT:    movdqa %xmm3, %xmm5
730; X64-SSE2-NEXT:    psrld %xmm2, %xmm5
731; X64-SSE2-NEXT:    punpcklqdq {{.*#+}} xmm5 = xmm5[0],xmm4[0]
732; X64-SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,2,3]
733; X64-SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[2,3,3,3,4,5,6,7]
734; X64-SSE2-NEXT:    movdqa %xmm3, %xmm4
735; X64-SSE2-NEXT:    psrld %xmm2, %xmm4
736; X64-SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,1,1,4,5,6,7]
737; X64-SSE2-NEXT:    psrld %xmm1, %xmm3
738; X64-SSE2-NEXT:    punpckhqdq {{.*#+}} xmm3 = xmm3[1],xmm4[1]
739; X64-SSE2-NEXT:    shufps {{.*#+}} xmm5 = xmm5[0,3],xmm3[0,3]
740; X64-SSE2-NEXT:    andps %xmm5, %xmm0
741; X64-SSE2-NEXT:    pxor %xmm1, %xmm1
742; X64-SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
743; X64-SSE2-NEXT:    retq
744  %t0 = lshr <4 x i32> <i32 1, i32 1, i32 undef, i32 1>, %y
745  %t1 = and <4 x i32> %t0, %x
746  %res = icmp eq <4 x i32> %t1, <i32 0, i32 0, i32 undef, i32 0>
747  ret <4 x i1> %res
748}
749
750;------------------------------------------------------------------------------;
751; A special tests
752;------------------------------------------------------------------------------;
753
754define i1 @scalar_i8_signbit_ne(i8 %x, i8 %y) nounwind {
755; X86-LABEL: scalar_i8_signbit_ne:
756; X86:       # %bb.0:
757; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
758; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
759; X86-NEXT:    shlb %cl, %al
760; X86-NEXT:    shrb $7, %al
761; X86-NEXT:    retl
762;
763; X64-LABEL: scalar_i8_signbit_ne:
764; X64:       # %bb.0:
765; X64-NEXT:    movl %esi, %ecx
766; X64-NEXT:    movl %edi, %eax
767; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
768; X64-NEXT:    shlb %cl, %al
769; X64-NEXT:    shrb $7, %al
770; X64-NEXT:    # kill: def $al killed $al killed $eax
771; X64-NEXT:    retq
772  %t0 = lshr i8 128, %y
773  %t1 = and i8 %t0, %x
774  %res = icmp ne i8 %t1, 0 ;  we are perfectly happy with 'ne' predicate
775  ret i1 %res
776}
777
778;------------------------------------------------------------------------------;
779; What if X is a constant too?
780;------------------------------------------------------------------------------;
781
782define i1 @scalar_i32_x_is_const_eq(i32 %y) nounwind {
783; X86-LABEL: scalar_i32_x_is_const_eq:
784; X86:       # %bb.0:
785; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
786; X86-NEXT:    movl $-1437226411, %ecx # imm = 0xAA55AA55
787; X86-NEXT:    btl %eax, %ecx
788; X86-NEXT:    setae %al
789; X86-NEXT:    retl
790;
791; X64-LABEL: scalar_i32_x_is_const_eq:
792; X64:       # %bb.0:
793; X64-NEXT:    movl $-1437226411, %eax # imm = 0xAA55AA55
794; X64-NEXT:    btl %edi, %eax
795; X64-NEXT:    setae %al
796; X64-NEXT:    retq
797  %t0 = lshr i32 2857740885, %y
798  %t1 = and i32 %t0, 1
799  %res = icmp eq i32 %t1, 0
800  ret i1 %res
801}
802define i1 @scalar_i32_x_is_const2_eq(i32 %y) nounwind {
803; X86-BMI1-LABEL: scalar_i32_x_is_const2_eq:
804; X86-BMI1:       # %bb.0:
805; X86-BMI1-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
806; X86-BMI1-NEXT:    movl $1, %eax
807; X86-BMI1-NEXT:    shrl %cl, %eax
808; X86-BMI1-NEXT:    testl %eax, %eax
809; X86-BMI1-NEXT:    sete %al
810; X86-BMI1-NEXT:    retl
811;
812; X86-BMI2-LABEL: scalar_i32_x_is_const2_eq:
813; X86-BMI2:       # %bb.0:
814; X86-BMI2-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
815; X86-BMI2-NEXT:    movl $1, %ecx
816; X86-BMI2-NEXT:    shrxl %eax, %ecx, %eax
817; X86-BMI2-NEXT:    testl %eax, %eax
818; X86-BMI2-NEXT:    sete %al
819; X86-BMI2-NEXT:    retl
820;
821; X64-BMI1-LABEL: scalar_i32_x_is_const2_eq:
822; X64-BMI1:       # %bb.0:
823; X64-BMI1-NEXT:    movl %edi, %ecx
824; X64-BMI1-NEXT:    movl $1, %eax
825; X64-BMI1-NEXT:    # kill: def $cl killed $cl killed $ecx
826; X64-BMI1-NEXT:    shrl %cl, %eax
827; X64-BMI1-NEXT:    testl %eax, %eax
828; X64-BMI1-NEXT:    sete %al
829; X64-BMI1-NEXT:    retq
830;
831; X64-BMI2-LABEL: scalar_i32_x_is_const2_eq:
832; X64-BMI2:       # %bb.0:
833; X64-BMI2-NEXT:    movl $1, %eax
834; X64-BMI2-NEXT:    shrxl %edi, %eax, %eax
835; X64-BMI2-NEXT:    testl %eax, %eax
836; X64-BMI2-NEXT:    sete %al
837; X64-BMI2-NEXT:    retq
838  %t0 = lshr i32 1, %y
839  %t1 = and i32 %t0, 2857740885
840  %res = icmp eq i32 %t1, 0
841  ret i1 %res
842}
843
844;------------------------------------------------------------------------------;
845; A few negative tests
846;------------------------------------------------------------------------------;
847
848define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
849; CHECK-LABEL: negative_scalar_i8_bitsinmiddle_slt:
850; CHECK:       # %bb.0:
851; CHECK-NEXT:    xorl %eax, %eax
852; CHECK-NEXT:    ret{{[l|q]}}
853  %t0 = lshr i8 24, %y
854  %t1 = and i8 %t0, %x
855  %res = icmp slt i8 %t1, 0
856  ret i1 %res
857}
858
859define i1 @scalar_i8_signbit_eq_with_nonzero(i8 %x, i8 %y) nounwind {
860; X86-LABEL: scalar_i8_signbit_eq_with_nonzero:
861; X86:       # %bb.0:
862; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
863; X86-NEXT:    movb $-128, %al
864; X86-NEXT:    shrb %cl, %al
865; X86-NEXT:    andb {{[0-9]+}}(%esp), %al
866; X86-NEXT:    cmpb $1, %al
867; X86-NEXT:    sete %al
868; X86-NEXT:    retl
869;
870; X64-LABEL: scalar_i8_signbit_eq_with_nonzero:
871; X64:       # %bb.0:
872; X64-NEXT:    movl %esi, %ecx
873; X64-NEXT:    movb $-128, %al
874; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
875; X64-NEXT:    shrb %cl, %al
876; X64-NEXT:    andb %dil, %al
877; X64-NEXT:    cmpb $1, %al
878; X64-NEXT:    sete %al
879; X64-NEXT:    retq
880  %t0 = lshr i8 128, %y
881  %t1 = and i8 %t0, %x
882  %res = icmp eq i8 %t1, 1 ; should be comparing with 0
883  ret i1 %res
884}
885