xref: /llvm-project/llvm/test/CodeGen/X86/ptest.ll (revision b0c892296b830eece7edd213ddddfc396ffcc8a9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2,-avx | FileCheck %s --check-prefix=SSE2
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1,-avx | FileCheck %s --check-prefix=SSE41
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx,-avx2   | FileCheck %s --check-prefixes=AVX,AVX1
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512vl,+avx512dq,+avx512bw | FileCheck %s --check-prefixes=AVX,AVX512
6
7define i32 @veccond128(<4 x i32> %input) {
8; SSE2-LABEL: veccond128:
9; SSE2:       # %bb.0: # %entry
10; SSE2-NEXT:    pxor %xmm1, %xmm1
11; SSE2-NEXT:    pcmpeqd %xmm0, %xmm1
12; SSE2-NEXT:    movmskps %xmm1, %eax
13; SSE2-NEXT:    xorl $15, %eax
14; SSE2-NEXT:    je .LBB0_2
15; SSE2-NEXT:  # %bb.1: # %if-true-block
16; SSE2-NEXT:    xorl %eax, %eax
17; SSE2-NEXT:    retq
18; SSE2-NEXT:  .LBB0_2: # %endif-block
19; SSE2-NEXT:    movl $1, %eax
20; SSE2-NEXT:    retq
21;
22; SSE41-LABEL: veccond128:
23; SSE41:       # %bb.0: # %entry
24; SSE41-NEXT:    ptest %xmm0, %xmm0
25; SSE41-NEXT:    je .LBB0_2
26; SSE41-NEXT:  # %bb.1: # %if-true-block
27; SSE41-NEXT:    xorl %eax, %eax
28; SSE41-NEXT:    retq
29; SSE41-NEXT:  .LBB0_2: # %endif-block
30; SSE41-NEXT:    movl $1, %eax
31; SSE41-NEXT:    retq
32;
33; AVX-LABEL: veccond128:
34; AVX:       # %bb.0: # %entry
35; AVX-NEXT:    vptest %xmm0, %xmm0
36; AVX-NEXT:    je .LBB0_2
37; AVX-NEXT:  # %bb.1: # %if-true-block
38; AVX-NEXT:    xorl %eax, %eax
39; AVX-NEXT:    retq
40; AVX-NEXT:  .LBB0_2: # %endif-block
41; AVX-NEXT:    movl $1, %eax
42; AVX-NEXT:    retq
43entry:
44  %0 = bitcast <4 x i32> %input to i128
45  %1 = icmp ne i128 %0, 0
46  br i1 %1, label %if-true-block, label %endif-block
47if-true-block:
48  ret i32 0
49endif-block:
50  ret i32 1
51}
52
53define i32 @veccond256(<8 x i32> %input) {
54; SSE2-LABEL: veccond256:
55; SSE2:       # %bb.0: # %entry
56; SSE2-NEXT:    por %xmm1, %xmm0
57; SSE2-NEXT:    pxor %xmm1, %xmm1
58; SSE2-NEXT:    pcmpeqd %xmm0, %xmm1
59; SSE2-NEXT:    movmskps %xmm1, %eax
60; SSE2-NEXT:    xorl $15, %eax
61; SSE2-NEXT:    je .LBB1_2
62; SSE2-NEXT:  # %bb.1: # %if-true-block
63; SSE2-NEXT:    xorl %eax, %eax
64; SSE2-NEXT:    retq
65; SSE2-NEXT:  .LBB1_2: # %endif-block
66; SSE2-NEXT:    movl $1, %eax
67; SSE2-NEXT:    retq
68;
69; SSE41-LABEL: veccond256:
70; SSE41:       # %bb.0: # %entry
71; SSE41-NEXT:    por %xmm1, %xmm0
72; SSE41-NEXT:    ptest %xmm0, %xmm0
73; SSE41-NEXT:    je .LBB1_2
74; SSE41-NEXT:  # %bb.1: # %if-true-block
75; SSE41-NEXT:    xorl %eax, %eax
76; SSE41-NEXT:    retq
77; SSE41-NEXT:  .LBB1_2: # %endif-block
78; SSE41-NEXT:    movl $1, %eax
79; SSE41-NEXT:    retq
80;
81; AVX-LABEL: veccond256:
82; AVX:       # %bb.0: # %entry
83; AVX-NEXT:    vptest %ymm0, %ymm0
84; AVX-NEXT:    je .LBB1_2
85; AVX-NEXT:  # %bb.1: # %if-true-block
86; AVX-NEXT:    xorl %eax, %eax
87; AVX-NEXT:    vzeroupper
88; AVX-NEXT:    retq
89; AVX-NEXT:  .LBB1_2: # %endif-block
90; AVX-NEXT:    movl $1, %eax
91; AVX-NEXT:    vzeroupper
92; AVX-NEXT:    retq
93entry:
94  %0 = bitcast <8 x i32> %input to i256
95  %1 = icmp ne i256 %0, 0
96  br i1 %1, label %if-true-block, label %endif-block
97if-true-block:
98  ret i32 0
99endif-block:
100  ret i32 1
101}
102
103define i32 @veccond512(<16 x i32> %input) {
104; SSE2-LABEL: veccond512:
105; SSE2:       # %bb.0: # %entry
106; SSE2-NEXT:    por %xmm3, %xmm1
107; SSE2-NEXT:    por %xmm2, %xmm0
108; SSE2-NEXT:    por %xmm1, %xmm0
109; SSE2-NEXT:    pxor %xmm1, %xmm1
110; SSE2-NEXT:    pcmpeqd %xmm0, %xmm1
111; SSE2-NEXT:    movmskps %xmm1, %eax
112; SSE2-NEXT:    xorl $15, %eax
113; SSE2-NEXT:    je .LBB2_2
114; SSE2-NEXT:  # %bb.1: # %if-true-block
115; SSE2-NEXT:    xorl %eax, %eax
116; SSE2-NEXT:    retq
117; SSE2-NEXT:  .LBB2_2: # %endif-block
118; SSE2-NEXT:    movl $1, %eax
119; SSE2-NEXT:    retq
120;
121; SSE41-LABEL: veccond512:
122; SSE41:       # %bb.0: # %entry
123; SSE41-NEXT:    por %xmm3, %xmm1
124; SSE41-NEXT:    por %xmm2, %xmm0
125; SSE41-NEXT:    por %xmm1, %xmm0
126; SSE41-NEXT:    ptest %xmm0, %xmm0
127; SSE41-NEXT:    je .LBB2_2
128; SSE41-NEXT:  # %bb.1: # %if-true-block
129; SSE41-NEXT:    xorl %eax, %eax
130; SSE41-NEXT:    retq
131; SSE41-NEXT:  .LBB2_2: # %endif-block
132; SSE41-NEXT:    movl $1, %eax
133; SSE41-NEXT:    retq
134;
135; AVX1-LABEL: veccond512:
136; AVX1:       # %bb.0: # %entry
137; AVX1-NEXT:    vorps %ymm1, %ymm0, %ymm0
138; AVX1-NEXT:    vptest %ymm0, %ymm0
139; AVX1-NEXT:    je .LBB2_2
140; AVX1-NEXT:  # %bb.1: # %if-true-block
141; AVX1-NEXT:    xorl %eax, %eax
142; AVX1-NEXT:    vzeroupper
143; AVX1-NEXT:    retq
144; AVX1-NEXT:  .LBB2_2: # %endif-block
145; AVX1-NEXT:    movl $1, %eax
146; AVX1-NEXT:    vzeroupper
147; AVX1-NEXT:    retq
148;
149; AVX512-LABEL: veccond512:
150; AVX512:       # %bb.0: # %entry
151; AVX512-NEXT:    vptestmd %zmm0, %zmm0, %k0
152; AVX512-NEXT:    kortestw %k0, %k0
153; AVX512-NEXT:    je .LBB2_2
154; AVX512-NEXT:  # %bb.1: # %if-true-block
155; AVX512-NEXT:    xorl %eax, %eax
156; AVX512-NEXT:    vzeroupper
157; AVX512-NEXT:    retq
158; AVX512-NEXT:  .LBB2_2: # %endif-block
159; AVX512-NEXT:    movl $1, %eax
160; AVX512-NEXT:    vzeroupper
161; AVX512-NEXT:    retq
162entry:
163  %0 = bitcast <16 x i32> %input to i512
164  %1 = icmp ne i512 %0, 0
165  br i1 %1, label %if-true-block, label %endif-block
166if-true-block:
167  ret i32 0
168endif-block:
169  ret i32 1
170}
171
172define i32 @vectest128(<4 x i32> %input) {
173; SSE2-LABEL: vectest128:
174; SSE2:       # %bb.0:
175; SSE2-NEXT:    pxor %xmm1, %xmm1
176; SSE2-NEXT:    pcmpeqd %xmm0, %xmm1
177; SSE2-NEXT:    movmskps %xmm1, %ecx
178; SSE2-NEXT:    xorl %eax, %eax
179; SSE2-NEXT:    xorl $15, %ecx
180; SSE2-NEXT:    setne %al
181; SSE2-NEXT:    retq
182;
183; SSE41-LABEL: vectest128:
184; SSE41:       # %bb.0:
185; SSE41-NEXT:    xorl %eax, %eax
186; SSE41-NEXT:    ptest %xmm0, %xmm0
187; SSE41-NEXT:    setne %al
188; SSE41-NEXT:    retq
189;
190; AVX-LABEL: vectest128:
191; AVX:       # %bb.0:
192; AVX-NEXT:    xorl %eax, %eax
193; AVX-NEXT:    vptest %xmm0, %xmm0
194; AVX-NEXT:    setne %al
195; AVX-NEXT:    retq
196  %t0 = bitcast <4 x i32> %input to i128
197  %t1 = icmp ne i128 %t0, 0
198  %t2 = zext i1 %t1 to i32
199  ret i32 %t2
200}
201
202define i32 @vectest256(<8 x i32> %input) {
203; SSE2-LABEL: vectest256:
204; SSE2:       # %bb.0:
205; SSE2-NEXT:    por %xmm1, %xmm0
206; SSE2-NEXT:    pxor %xmm1, %xmm1
207; SSE2-NEXT:    pcmpeqd %xmm0, %xmm1
208; SSE2-NEXT:    movmskps %xmm1, %ecx
209; SSE2-NEXT:    xorl %eax, %eax
210; SSE2-NEXT:    xorl $15, %ecx
211; SSE2-NEXT:    setne %al
212; SSE2-NEXT:    retq
213;
214; SSE41-LABEL: vectest256:
215; SSE41:       # %bb.0:
216; SSE41-NEXT:    por %xmm1, %xmm0
217; SSE41-NEXT:    xorl %eax, %eax
218; SSE41-NEXT:    ptest %xmm0, %xmm0
219; SSE41-NEXT:    setne %al
220; SSE41-NEXT:    retq
221;
222; AVX-LABEL: vectest256:
223; AVX:       # %bb.0:
224; AVX-NEXT:    xorl %eax, %eax
225; AVX-NEXT:    vptest %ymm0, %ymm0
226; AVX-NEXT:    setne %al
227; AVX-NEXT:    vzeroupper
228; AVX-NEXT:    retq
229  %t0 = bitcast <8 x i32> %input to i256
230  %t1 = icmp ne i256 %t0, 0
231  %t2 = zext i1 %t1 to i32
232  ret i32 %t2
233}
234
235define i32 @vectest512(<16 x i32> %input) {
236; SSE2-LABEL: vectest512:
237; SSE2:       # %bb.0:
238; SSE2-NEXT:    por %xmm3, %xmm1
239; SSE2-NEXT:    por %xmm2, %xmm0
240; SSE2-NEXT:    por %xmm1, %xmm0
241; SSE2-NEXT:    pxor %xmm1, %xmm1
242; SSE2-NEXT:    pcmpeqd %xmm0, %xmm1
243; SSE2-NEXT:    movmskps %xmm1, %ecx
244; SSE2-NEXT:    xorl %eax, %eax
245; SSE2-NEXT:    xorl $15, %ecx
246; SSE2-NEXT:    setne %al
247; SSE2-NEXT:    retq
248;
249; SSE41-LABEL: vectest512:
250; SSE41:       # %bb.0:
251; SSE41-NEXT:    por %xmm3, %xmm1
252; SSE41-NEXT:    por %xmm2, %xmm0
253; SSE41-NEXT:    por %xmm1, %xmm0
254; SSE41-NEXT:    xorl %eax, %eax
255; SSE41-NEXT:    ptest %xmm0, %xmm0
256; SSE41-NEXT:    setne %al
257; SSE41-NEXT:    retq
258;
259; AVX1-LABEL: vectest512:
260; AVX1:       # %bb.0:
261; AVX1-NEXT:    vorps %ymm1, %ymm0, %ymm0
262; AVX1-NEXT:    xorl %eax, %eax
263; AVX1-NEXT:    vptest %ymm0, %ymm0
264; AVX1-NEXT:    setne %al
265; AVX1-NEXT:    vzeroupper
266; AVX1-NEXT:    retq
267;
268; AVX512-LABEL: vectest512:
269; AVX512:       # %bb.0:
270; AVX512-NEXT:    vptestmd %zmm0, %zmm0, %k0
271; AVX512-NEXT:    xorl %eax, %eax
272; AVX512-NEXT:    kortestw %k0, %k0
273; AVX512-NEXT:    setne %al
274; AVX512-NEXT:    vzeroupper
275; AVX512-NEXT:    retq
276  %t0 = bitcast <16 x i32> %input to i512
277  %t1 = icmp ne i512 %t0, 0
278  %t2 = zext i1 %t1 to i32
279  ret i32 %t2
280}
281
282define i32 @vecsel128(<4 x i32> %input, i32 %a, i32 %b) {
283; SSE2-LABEL: vecsel128:
284; SSE2:       # %bb.0:
285; SSE2-NEXT:    movl %edi, %eax
286; SSE2-NEXT:    pxor %xmm1, %xmm1
287; SSE2-NEXT:    pcmpeqd %xmm0, %xmm1
288; SSE2-NEXT:    movmskps %xmm1, %ecx
289; SSE2-NEXT:    xorl $15, %ecx
290; SSE2-NEXT:    cmovel %esi, %eax
291; SSE2-NEXT:    retq
292;
293; SSE41-LABEL: vecsel128:
294; SSE41:       # %bb.0:
295; SSE41-NEXT:    movl %edi, %eax
296; SSE41-NEXT:    ptest %xmm0, %xmm0
297; SSE41-NEXT:    cmovel %esi, %eax
298; SSE41-NEXT:    retq
299;
300; AVX-LABEL: vecsel128:
301; AVX:       # %bb.0:
302; AVX-NEXT:    movl %edi, %eax
303; AVX-NEXT:    vptest %xmm0, %xmm0
304; AVX-NEXT:    cmovel %esi, %eax
305; AVX-NEXT:    retq
306  %t0 = bitcast <4 x i32> %input to i128
307  %t1 = icmp ne i128 %t0, 0
308  %t2 = select i1 %t1, i32 %a, i32 %b
309  ret i32 %t2
310}
311
312define i32 @vecsel256(<8 x i32> %input, i32 %a, i32 %b) {
313; SSE2-LABEL: vecsel256:
314; SSE2:       # %bb.0:
315; SSE2-NEXT:    movl %edi, %eax
316; SSE2-NEXT:    por %xmm1, %xmm0
317; SSE2-NEXT:    pxor %xmm1, %xmm1
318; SSE2-NEXT:    pcmpeqd %xmm0, %xmm1
319; SSE2-NEXT:    movmskps %xmm1, %ecx
320; SSE2-NEXT:    xorl $15, %ecx
321; SSE2-NEXT:    cmovel %esi, %eax
322; SSE2-NEXT:    retq
323;
324; SSE41-LABEL: vecsel256:
325; SSE41:       # %bb.0:
326; SSE41-NEXT:    movl %edi, %eax
327; SSE41-NEXT:    por %xmm1, %xmm0
328; SSE41-NEXT:    ptest %xmm0, %xmm0
329; SSE41-NEXT:    cmovel %esi, %eax
330; SSE41-NEXT:    retq
331;
332; AVX-LABEL: vecsel256:
333; AVX:       # %bb.0:
334; AVX-NEXT:    movl %edi, %eax
335; AVX-NEXT:    vptest %ymm0, %ymm0
336; AVX-NEXT:    cmovel %esi, %eax
337; AVX-NEXT:    vzeroupper
338; AVX-NEXT:    retq
339  %t0 = bitcast <8 x i32> %input to i256
340  %t1 = icmp ne i256 %t0, 0
341  %t2 = select i1 %t1, i32 %a, i32 %b
342  ret i32 %t2
343}
344
345define i32 @vecsel512(<16 x i32> %input, i32 %a, i32 %b) {
346; SSE2-LABEL: vecsel512:
347; SSE2:       # %bb.0:
348; SSE2-NEXT:    movl %edi, %eax
349; SSE2-NEXT:    por %xmm3, %xmm1
350; SSE2-NEXT:    por %xmm2, %xmm0
351; SSE2-NEXT:    por %xmm1, %xmm0
352; SSE2-NEXT:    pxor %xmm1, %xmm1
353; SSE2-NEXT:    pcmpeqd %xmm0, %xmm1
354; SSE2-NEXT:    movmskps %xmm1, %ecx
355; SSE2-NEXT:    xorl $15, %ecx
356; SSE2-NEXT:    cmovel %esi, %eax
357; SSE2-NEXT:    retq
358;
359; SSE41-LABEL: vecsel512:
360; SSE41:       # %bb.0:
361; SSE41-NEXT:    movl %edi, %eax
362; SSE41-NEXT:    por %xmm3, %xmm1
363; SSE41-NEXT:    por %xmm2, %xmm0
364; SSE41-NEXT:    por %xmm1, %xmm0
365; SSE41-NEXT:    ptest %xmm0, %xmm0
366; SSE41-NEXT:    cmovel %esi, %eax
367; SSE41-NEXT:    retq
368;
369; AVX1-LABEL: vecsel512:
370; AVX1:       # %bb.0:
371; AVX1-NEXT:    movl %edi, %eax
372; AVX1-NEXT:    vorps %ymm1, %ymm0, %ymm0
373; AVX1-NEXT:    vptest %ymm0, %ymm0
374; AVX1-NEXT:    cmovel %esi, %eax
375; AVX1-NEXT:    vzeroupper
376; AVX1-NEXT:    retq
377;
378; AVX512-LABEL: vecsel512:
379; AVX512:       # %bb.0:
380; AVX512-NEXT:    movl %edi, %eax
381; AVX512-NEXT:    vptestmd %zmm0, %zmm0, %k0
382; AVX512-NEXT:    kortestw %k0, %k0
383; AVX512-NEXT:    cmovel %esi, %eax
384; AVX512-NEXT:    vzeroupper
385; AVX512-NEXT:    retq
386  %t0 = bitcast <16 x i32> %input to i512
387  %t1 = icmp ne i512 %t0, 0
388  %t2 = select i1 %t1, i32 %a, i32 %b
389  ret i32 %t2
390}
391