xref: /llvm-project/llvm/test/CodeGen/X86/icmp-pow2-logic-npow2.ll (revision c3bf6d20ac306b829dc99939b3a8f9487f7f1c9a)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=i686-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=X86
3; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=X64
4
5declare i64 @llvm.abs.i64(i64, i1)
6declare <2 x i64> @llvm.abs.2xi64(<2 x i64>, i1)
7declare i32 @llvm.abs.i32(i32, i1)
8declare i16 @llvm.abs.i16(i16, i1)
9declare i8 @llvm.abs.i8(i8, i1)
10
11define i1 @eq_pow_or(i32 %0) nounwind {
12; X86-LABEL: eq_pow_or:
13; X86:       # %bb.0:
14; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
15; X86-NEXT:    addl $32, %eax
16; X86-NEXT:    testl $-65, %eax
17; X86-NEXT:    sete %al
18; X86-NEXT:    retl
19;
20; X64-LABEL: eq_pow_or:
21; X64:       # %bb.0:
22; X64-NEXT:    addl $32, %edi
23; X64-NEXT:    testl $-65, %edi
24; X64-NEXT:    sete %al
25; X64-NEXT:    retq
26  %2 = icmp eq i32 %0, 32
27  %3 = icmp eq i32 %0, -32
28  %4 = or i1 %2, %3
29  ret i1 %4
30}
31
32define i1 @ne_pow_and(i8 %0) nounwind {
33; X86-LABEL: ne_pow_and:
34; X86:       # %bb.0:
35; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
36; X86-NEXT:    addb $16, %al
37; X86-NEXT:    testb $-33, %al
38; X86-NEXT:    setne %al
39; X86-NEXT:    retl
40;
41; X64-LABEL: ne_pow_and:
42; X64:       # %bb.0:
43; X64-NEXT:    addb $16, %dil
44; X64-NEXT:    testb $-33, %dil
45; X64-NEXT:    setne %al
46; X64-NEXT:    retq
47  %2 = icmp ne i8 %0, 16
48  %3 = icmp ne i8 %0, -16
49  %4 = and i1 %2, %3
50  ret i1 %4
51}
52
53define i1 @eq_pow_mismatch_or(i32 %0) nounwind {
54; X86-LABEL: eq_pow_mismatch_or:
55; X86:       # %bb.0:
56; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
57; X86-NEXT:    cmpl $16, %eax
58; X86-NEXT:    sete %cl
59; X86-NEXT:    cmpl $-32, %eax
60; X86-NEXT:    sete %al
61; X86-NEXT:    orb %cl, %al
62; X86-NEXT:    retl
63;
64; X64-LABEL: eq_pow_mismatch_or:
65; X64:       # %bb.0:
66; X64-NEXT:    cmpl $16, %edi
67; X64-NEXT:    sete %cl
68; X64-NEXT:    cmpl $-32, %edi
69; X64-NEXT:    sete %al
70; X64-NEXT:    orb %cl, %al
71; X64-NEXT:    retq
72  %2 = icmp eq i32 %0, 16
73  %3 = icmp eq i32 %0, -32
74  %4 = or i1 %2, %3
75  ret i1 %4
76}
77
78define i1 @ne_non_pow_and(i8 %0) nounwind {
79; X86-LABEL: ne_non_pow_and:
80; X86:       # %bb.0:
81; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
82; X86-NEXT:    cmpb $17, %al
83; X86-NEXT:    setne %cl
84; X86-NEXT:    cmpb $-17, %al
85; X86-NEXT:    setne %al
86; X86-NEXT:    andb %cl, %al
87; X86-NEXT:    retl
88;
89; X64-LABEL: ne_non_pow_and:
90; X64:       # %bb.0:
91; X64-NEXT:    cmpb $17, %dil
92; X64-NEXT:    setne %cl
93; X64-NEXT:    cmpb $-17, %dil
94; X64-NEXT:    setne %al
95; X64-NEXT:    andb %cl, %al
96; X64-NEXT:    retq
97  %2 = icmp ne i8 %0, 17
98  %3 = icmp ne i8 %0, -17
99  %4 = and i1 %2, %3
100  ret i1 %4
101}
102
103define i1 @ne_pow_or(i32 %0) nounwind {
104; X86-LABEL: ne_pow_or:
105; X86:       # %bb.0:
106; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
107; X86-NEXT:    movl %eax, %ecx
108; X86-NEXT:    xorl $32, %ecx
109; X86-NEXT:    xorl $-32, %eax
110; X86-NEXT:    orl %ecx, %eax
111; X86-NEXT:    setne %al
112; X86-NEXT:    retl
113;
114; X64-LABEL: ne_pow_or:
115; X64:       # %bb.0:
116; X64-NEXT:    movl %edi, %eax
117; X64-NEXT:    xorl $32, %eax
118; X64-NEXT:    xorl $-32, %edi
119; X64-NEXT:    orl %eax, %edi
120; X64-NEXT:    setne %al
121; X64-NEXT:    retq
122  %2 = icmp ne i32 %0, 32
123  %3 = icmp ne i32 %0, -32
124  %4 = or i1 %2, %3
125  ret i1 %4
126}
127
128define i1 @eq_pow_and(i8 %0) nounwind {
129; X86-LABEL: eq_pow_and:
130; X86:       # %bb.0:
131; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
132; X86-NEXT:    movl %eax, %ecx
133; X86-NEXT:    xorb $16, %cl
134; X86-NEXT:    xorb $-16, %al
135; X86-NEXT:    orb %cl, %al
136; X86-NEXT:    sete %al
137; X86-NEXT:    retl
138;
139; X64-LABEL: eq_pow_and:
140; X64:       # %bb.0:
141; X64-NEXT:    movl %edi, %eax
142; X64-NEXT:    xorb $16, %al
143; X64-NEXT:    xorb $-16, %dil
144; X64-NEXT:    orb %al, %dil
145; X64-NEXT:    sete %al
146; X64-NEXT:    retq
147  %2 = icmp eq i8 %0, 16
148  %3 = icmp eq i8 %0, -16
149  %4 = and i1 %2, %3
150  ret i1 %4
151}
152
153define i1 @abs_eq_pow2(i32 %0) nounwind {
154; X86-LABEL: abs_eq_pow2:
155; X86:       # %bb.0:
156; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
157; X86-NEXT:    addl $4, %eax
158; X86-NEXT:    testl $-9, %eax
159; X86-NEXT:    sete %al
160; X86-NEXT:    retl
161;
162; X64-LABEL: abs_eq_pow2:
163; X64:       # %bb.0:
164; X64-NEXT:    addl $4, %edi
165; X64-NEXT:    testl $-9, %edi
166; X64-NEXT:    sete %al
167; X64-NEXT:    retq
168  %2 = tail call i32 @llvm.abs.i32(i32 %0, i1 true)
169  %3 = icmp eq i32 %2, 4
170  ret i1 %3
171}
172
173define i1 @abs_ne_pow2(i64 %0) nounwind {
174; X86-LABEL: abs_ne_pow2:
175; X86:       # %bb.0:
176; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
177; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
178; X86-NEXT:    addl $2, %eax
179; X86-NEXT:    adcl $0, %ecx
180; X86-NEXT:    andl $-5, %eax
181; X86-NEXT:    orl %ecx, %eax
182; X86-NEXT:    setne %al
183; X86-NEXT:    retl
184;
185; X64-LABEL: abs_ne_pow2:
186; X64:       # %bb.0:
187; X64-NEXT:    addq $2, %rdi
188; X64-NEXT:    testq $-5, %rdi
189; X64-NEXT:    setne %al
190; X64-NEXT:    retq
191  %2 = tail call i64 @llvm.abs.i64(i64 %0, i1 true)
192  %3 = icmp ne i64 %2, 2
193  ret i1 %3
194}
195
196define i1 @abs_ne_nonpow2(i16 %0) nounwind {
197; X86-LABEL: abs_ne_nonpow2:
198; X86:       # %bb.0:
199; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
200; X86-NEXT:    movswl %ax, %ecx
201; X86-NEXT:    sarl $15, %ecx
202; X86-NEXT:    xorl %ecx, %eax
203; X86-NEXT:    subl %ecx, %eax
204; X86-NEXT:    movzwl %ax, %eax
205; X86-NEXT:    cmpl $57344, %eax # imm = 0xE000
206; X86-NEXT:    setne %al
207; X86-NEXT:    retl
208;
209; X64-LABEL: abs_ne_nonpow2:
210; X64:       # %bb.0:
211; X64-NEXT:    movl %edi, %eax
212; X64-NEXT:    negw %ax
213; X64-NEXT:    cmovsw %di, %ax
214; X64-NEXT:    movzwl %ax, %eax
215; X64-NEXT:    cmpl $57344, %eax # imm = 0xE000
216; X64-NEXT:    setne %al
217; X64-NEXT:    retq
218  %2 = tail call i16 @llvm.abs.i16(i16 %0, i1 true)
219  %3 = icmp ne i16 %2, -8192
220  ret i1 %3
221}
222
223define <2 x i1> @abs_ne_vec(<2 x i64> %0) nounwind {
224; X86-LABEL: abs_ne_vec:
225; X86:       # %bb.0:
226; X86-NEXT:    pushl %edi
227; X86-NEXT:    pushl %esi
228; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
229; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
230; X86-NEXT:    movl %ecx, %esi
231; X86-NEXT:    sarl $31, %esi
232; X86-NEXT:    xorl %esi, %ecx
233; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
234; X86-NEXT:    xorl %esi, %edx
235; X86-NEXT:    subl %esi, %edx
236; X86-NEXT:    sbbl %esi, %ecx
237; X86-NEXT:    movl %eax, %esi
238; X86-NEXT:    sarl $31, %esi
239; X86-NEXT:    xorl %esi, %eax
240; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
241; X86-NEXT:    xorl %esi, %edi
242; X86-NEXT:    subl %esi, %edi
243; X86-NEXT:    sbbl %esi, %eax
244; X86-NEXT:    xorl $8, %edi
245; X86-NEXT:    orl %eax, %edi
246; X86-NEXT:    setne %al
247; X86-NEXT:    xorl $8, %edx
248; X86-NEXT:    orl %ecx, %edx
249; X86-NEXT:    setne %dl
250; X86-NEXT:    popl %esi
251; X86-NEXT:    popl %edi
252; X86-NEXT:    retl
253;
254; X64-LABEL: abs_ne_vec:
255; X64:       # %bb.0:
256; X64-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]
257; X64-NEXT:    psrad $31, %xmm1
258; X64-NEXT:    pxor %xmm1, %xmm0
259; X64-NEXT:    psubq %xmm1, %xmm0
260; X64-NEXT:    pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
261; X64-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,0,3,2]
262; X64-NEXT:    pand %xmm1, %xmm0
263; X64-NEXT:    pcmpeqd %xmm1, %xmm1
264; X64-NEXT:    pxor %xmm1, %xmm0
265; X64-NEXT:    retq
266  %2 = tail call <2 x i64> @llvm.abs.2xi64(<2 x i64> %0, i1 true)
267  %3 = icmp ne <2 x i64> %2, <i64 8, i64 8>
268  ret <2 x i1> %3
269}
270