1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE2
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE42
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
6
7; Lower common integer comparisons such as 'isPositive' efficiently:
8; https://llvm.org/bugs/show_bug.cgi?id=26701
9
10define <16 x i8> @test_pcmpgtb(<16 x i8> %x) {
11; SSE-LABEL: test_pcmpgtb:
12; SSE:       # BB#0:
13; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
14; SSE-NEXT:    pcmpgtb %xmm1, %xmm0
15; SSE-NEXT:    retq
16;
17; AVX-LABEL: test_pcmpgtb:
18; AVX:       # BB#0:
19; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
20; AVX-NEXT:    vpcmpgtb %xmm1, %xmm0, %xmm0
21; AVX-NEXT:    retq
22  %sign = ashr <16 x i8> %x, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
23  %not = xor <16 x i8> %sign, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
24  ret <16 x i8> %not
25}
26
27define <8 x i16> @test_pcmpgtw(<8 x i16> %x) {
28; SSE-LABEL: test_pcmpgtw:
29; SSE:       # BB#0:
30; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
31; SSE-NEXT:    pcmpgtw %xmm1, %xmm0
32; SSE-NEXT:    retq
33;
34; AVX-LABEL: test_pcmpgtw:
35; AVX:       # BB#0:
36; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
37; AVX-NEXT:    vpcmpgtw %xmm1, %xmm0, %xmm0
38; AVX-NEXT:    retq
39  %sign = ashr <8 x i16> %x, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>
40  %not = xor <8 x i16> %sign, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
41  ret <8 x i16> %not
42}
43
44define <4 x i32> @test_pcmpgtd(<4 x i32> %x) {
45; SSE-LABEL: test_pcmpgtd:
46; SSE:       # BB#0:
47; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
48; SSE-NEXT:    pcmpgtd %xmm1, %xmm0
49; SSE-NEXT:    retq
50;
51; AVX-LABEL: test_pcmpgtd:
52; AVX:       # BB#0:
53; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
54; AVX-NEXT:    vpcmpgtd %xmm1, %xmm0, %xmm0
55; AVX-NEXT:    retq
56  %sign = ashr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>
57  %not = xor <4 x i32> %sign, <i32 -1, i32 -1, i32 -1, i32 -1>
58  ret <4 x i32> %not
59}
60
61define <2 x i64> @test_pcmpgtq(<2 x i64> %x) {
62; SSE2-LABEL: test_pcmpgtq:
63; SSE2:       # BB#0:
64; SSE2-NEXT:    psrad $31, %xmm0
65; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]
66; SSE2-NEXT:    pcmpeqd %xmm0, %xmm0
67; SSE2-NEXT:    pxor %xmm1, %xmm0
68; SSE2-NEXT:    retq
69;
70; SSE42-LABEL: test_pcmpgtq:
71; SSE42:       # BB#0:
72; SSE42-NEXT:    pcmpeqd %xmm1, %xmm1
73; SSE42-NEXT:    pcmpgtq %xmm1, %xmm0
74; SSE42-NEXT:    retq
75;
76; AVX-LABEL: test_pcmpgtq:
77; AVX:       # BB#0:
78; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
79; AVX-NEXT:    vpcmpgtq %xmm1, %xmm0, %xmm0
80; AVX-NEXT:    retq
81  %sign = ashr <2 x i64> %x, <i64 63, i64 63>
82  %not = xor <2 x i64> %sign, <i64 -1, i64 -1>
83  ret <2 x i64> %not
84}
85
86define <1 x i128> @test_strange_type(<1 x i128> %x) {
87; SSE2-LABEL: test_strange_type:
88; SSE2:       # BB#0:
89; SSE2-NEXT:    sarq $63, %rsi
90; SSE2-NEXT:    notq %rsi
91; SSE2-NEXT:    movd %rsi, %xmm0
92; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
93; SSE2-NEXT:    movd %xmm0, %rax
94; SSE2-NEXT:    movq %rsi, %rdx
95; SSE2-NEXT:    retq
96;
97; SSE42-LABEL: test_strange_type:
98; SSE42:       # BB#0:
99; SSE42-NEXT:    sarq $63, %rsi
100; SSE42-NEXT:    notq %rsi
101; SSE42-NEXT:    movd %rsi, %xmm0
102; SSE42-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
103; SSE42-NEXT:    movd %xmm0, %rax
104; SSE42-NEXT:    pextrq $1, %xmm0, %rdx
105; SSE42-NEXT:    retq
106;
107; AVX1-LABEL: test_strange_type:
108; AVX1:       # BB#0:
109; AVX1-NEXT:    sarq $63, %rsi
110; AVX1-NEXT:    notq %rsi
111; AVX1-NEXT:    vmovq %rsi, %xmm0
112; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
113; AVX1-NEXT:    vmovq %xmm0, %rax
114; AVX1-NEXT:    vpextrq $1, %xmm0, %rdx
115; AVX1-NEXT:    retq
116;
117; AVX2-LABEL: test_strange_type:
118; AVX2:       # BB#0:
119; AVX2-NEXT:    sarq $63, %rsi
120; AVX2-NEXT:    notq %rsi
121; AVX2-NEXT:    vmovq %rsi, %xmm0
122; AVX2-NEXT:    vpbroadcastq %xmm0, %xmm0
123; AVX2-NEXT:    vmovq %xmm0, %rax
124; AVX2-NEXT:    vpextrq $1, %xmm0, %rdx
125; AVX2-NEXT:    retq
126  %sign = ashr <1 x i128> %x, <i128 127>
127  %not = xor <1 x i128> %sign, <i128 -1>
128  ret <1 x i128> %not
129}
130
131define <32 x i8> @test_pcmpgtb_256(<32 x i8> %x) {
132; SSE-LABEL: test_pcmpgtb_256:
133; SSE:       # BB#0:
134; SSE-NEXT:    pcmpeqd %xmm2, %xmm2
135; SSE-NEXT:    pcmpgtb %xmm2, %xmm0
136; SSE-NEXT:    pcmpgtb %xmm2, %xmm1
137; SSE-NEXT:    retq
138;
139; AVX1-LABEL: test_pcmpgtb_256:
140; AVX1:       # BB#0:
141; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
142; AVX1-NEXT:    vpxor %xmm2, %xmm2, %xmm2
143; AVX1-NEXT:    vpcmpgtb %xmm1, %xmm2, %xmm1
144; AVX1-NEXT:    vpcmpgtb %xmm0, %xmm2, %xmm0
145; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
146; AVX1-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
147; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm1, %ymm1
148; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
149; AVX1-NEXT:    retq
150;
151; AVX2-LABEL: test_pcmpgtb_256:
152; AVX2:       # BB#0:
153; AVX2-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
154; AVX2-NEXT:    vpcmpgtb %ymm1, %ymm0, %ymm0
155; AVX2-NEXT:    retq
156  %sign = ashr <32 x i8> %x, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
157  %not = xor <32 x i8> %sign, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
158  ret <32 x i8> %not
159}
160
161define <16 x i16> @test_pcmpgtw_256(<16 x i16> %x) {
162; SSE-LABEL: test_pcmpgtw_256:
163; SSE:       # BB#0:
164; SSE-NEXT:    pcmpeqd %xmm2, %xmm2
165; SSE-NEXT:    pcmpgtw %xmm2, %xmm0
166; SSE-NEXT:    pcmpgtw %xmm2, %xmm1
167; SSE-NEXT:    retq
168;
169; AVX1-LABEL: test_pcmpgtw_256:
170; AVX1:       # BB#0:
171; AVX1-NEXT:    vpsraw $15, %xmm0, %xmm1
172; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
173; AVX1-NEXT:    vpsraw $15, %xmm0, %xmm0
174; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
175; AVX1-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
176; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm1, %ymm1
177; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
178; AVX1-NEXT:    retq
179;
180; AVX2-LABEL: test_pcmpgtw_256:
181; AVX2:       # BB#0:
182; AVX2-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
183; AVX2-NEXT:    vpcmpgtw %ymm1, %ymm0, %ymm0
184; AVX2-NEXT:    retq
185  %sign = ashr <16 x i16> %x, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>
186  %not = xor <16 x i16> %sign, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
187  ret <16 x i16> %not
188}
189
190define <8 x i32> @test_pcmpgtd_256(<8 x i32> %x) {
191; SSE-LABEL: test_pcmpgtd_256:
192; SSE:       # BB#0:
193; SSE-NEXT:    pcmpeqd %xmm2, %xmm2
194; SSE-NEXT:    pcmpgtd %xmm2, %xmm0
195; SSE-NEXT:    pcmpgtd %xmm2, %xmm1
196; SSE-NEXT:    retq
197;
198; AVX1-LABEL: test_pcmpgtd_256:
199; AVX1:       # BB#0:
200; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm1
201; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
202; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm0
203; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
204; AVX1-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
205; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm1, %ymm1
206; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
207; AVX1-NEXT:    retq
208;
209; AVX2-LABEL: test_pcmpgtd_256:
210; AVX2:       # BB#0:
211; AVX2-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
212; AVX2-NEXT:    vpcmpgtd %ymm1, %ymm0, %ymm0
213; AVX2-NEXT:    retq
214  %sign = ashr <8 x i32> %x, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
215  %not = xor <8 x i32> %sign, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
216  ret <8 x i32> %not
217}
218
219define <4 x i64> @test_pcmpgtq_256(<4 x i64> %x) {
220; SSE2-LABEL: test_pcmpgtq_256:
221; SSE2:       # BB#0:
222; SSE2-NEXT:    psrad $31, %xmm1
223; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
224; SSE2-NEXT:    psrad $31, %xmm0
225; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
226; SSE2-NEXT:    pcmpeqd %xmm2, %xmm2
227; SSE2-NEXT:    pxor %xmm2, %xmm0
228; SSE2-NEXT:    pxor %xmm2, %xmm1
229; SSE2-NEXT:    retq
230;
231; SSE42-LABEL: test_pcmpgtq_256:
232; SSE42:       # BB#0:
233; SSE42-NEXT:    pcmpeqd %xmm2, %xmm2
234; SSE42-NEXT:    pcmpgtq %xmm2, %xmm0
235; SSE42-NEXT:    pcmpgtq %xmm2, %xmm1
236; SSE42-NEXT:    retq
237;
238; AVX1-LABEL: test_pcmpgtq_256:
239; AVX1:       # BB#0:
240; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm1
241; AVX1-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
242; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
243; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm0
244; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
245; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
246; AVX1-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
247; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm1, %ymm1
248; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
249; AVX1-NEXT:    retq
250;
251; AVX2-LABEL: test_pcmpgtq_256:
252; AVX2:       # BB#0:
253; AVX2-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
254; AVX2-NEXT:    vpcmpgtq %ymm1, %ymm0, %ymm0
255; AVX2-NEXT:    retq
256  %sign = ashr <4 x i64> %x, <i64 63, i64 63, i64 63, i64 63>
257  %not = xor <4 x i64> %sign, <i64 -1, i64 -1, i64 -1, i64 -1>
258  ret <4 x i64> %not
259}
260
261