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-prefixes=SSE,SSE2
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+ssse3 | FileCheck %s --check-prefixes=SSE,SSSE3
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE41
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1
6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2
7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+avx512vl,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX,AVX512
8
9declare <1 x i8> @llvm.usub.sat.v1i8(<1 x i8>, <1 x i8>)
10declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>)
11declare <4 x i8> @llvm.usub.sat.v4i8(<4 x i8>, <4 x i8>)
12declare <8 x i8> @llvm.usub.sat.v8i8(<8 x i8>, <8 x i8>)
13declare <12 x i8> @llvm.usub.sat.v12i8(<12 x i8>, <12 x i8>)
14declare <16 x i8> @llvm.usub.sat.v16i8(<16 x i8>, <16 x i8>)
15declare <32 x i8> @llvm.usub.sat.v32i8(<32 x i8>, <32 x i8>)
16declare <64 x i8> @llvm.usub.sat.v64i8(<64 x i8>, <64 x i8>)
17
18declare <1 x i16> @llvm.usub.sat.v1i16(<1 x i16>, <1 x i16>)
19declare <2 x i16> @llvm.usub.sat.v2i16(<2 x i16>, <2 x i16>)
20declare <4 x i16> @llvm.usub.sat.v4i16(<4 x i16>, <4 x i16>)
21declare <8 x i16> @llvm.usub.sat.v8i16(<8 x i16>, <8 x i16>)
22declare <12 x i16> @llvm.usub.sat.v12i16(<12 x i16>, <12 x i16>)
23declare <16 x i16> @llvm.usub.sat.v16i16(<16 x i16>, <16 x i16>)
24declare <32 x i16> @llvm.usub.sat.v32i16(<32 x i16>, <32 x i16>)
25
26declare <16 x i1> @llvm.usub.sat.v16i1(<16 x i1>, <16 x i1>)
27declare <16 x i4> @llvm.usub.sat.v16i4(<16 x i4>, <16 x i4>)
28
29declare <2 x i32> @llvm.usub.sat.v2i32(<2 x i32>, <2 x i32>)
30declare <4 x i32> @llvm.usub.sat.v4i32(<4 x i32>, <4 x i32>)
31declare <8 x i32> @llvm.usub.sat.v8i32(<8 x i32>, <8 x i32>)
32declare <16 x i32> @llvm.usub.sat.v16i32(<16 x i32>, <16 x i32>)
33declare <2 x i64> @llvm.usub.sat.v2i64(<2 x i64>, <2 x i64>)
34declare <4 x i64> @llvm.usub.sat.v4i64(<4 x i64>, <4 x i64>)
35declare <8 x i64> @llvm.usub.sat.v8i64(<8 x i64>, <8 x i64>)
36
37declare <4 x i24> @llvm.usub.sat.v4i24(<4 x i24>, <4 x i24>)
38declare <2 x i128> @llvm.usub.sat.v2i128(<2 x i128>, <2 x i128>)
39
40; Legal types, depending on architecture.
41
42define <16 x i8> @v16i8(<16 x i8> %x, <16 x i8> %y) nounwind {
43; SSE-LABEL: v16i8:
44; SSE:       # %bb.0:
45; SSE-NEXT:    psubusb %xmm1, %xmm0
46; SSE-NEXT:    retq
47;
48; AVX-LABEL: v16i8:
49; AVX:       # %bb.0:
50; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
51; AVX-NEXT:    retq
52  %z = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %x, <16 x i8> %y)
53  ret <16 x i8> %z
54}
55
56define <32 x i8> @v32i8(<32 x i8> %x, <32 x i8> %y) nounwind {
57; SSE-LABEL: v32i8:
58; SSE:       # %bb.0:
59; SSE-NEXT:    psubusb %xmm2, %xmm0
60; SSE-NEXT:    psubusb %xmm3, %xmm1
61; SSE-NEXT:    retq
62;
63; AVX1-LABEL: v32i8:
64; AVX1:       # %bb.0:
65; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
66; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
67; AVX1-NEXT:    vpsubusb %xmm2, %xmm3, %xmm2
68; AVX1-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
69; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
70; AVX1-NEXT:    retq
71;
72; AVX2-LABEL: v32i8:
73; AVX2:       # %bb.0:
74; AVX2-NEXT:    vpsubusb %ymm1, %ymm0, %ymm0
75; AVX2-NEXT:    retq
76;
77; AVX512-LABEL: v32i8:
78; AVX512:       # %bb.0:
79; AVX512-NEXT:    vpsubusb %ymm1, %ymm0, %ymm0
80; AVX512-NEXT:    retq
81  %z = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %x, <32 x i8> %y)
82  ret <32 x i8> %z
83}
84
85define <64 x i8> @v64i8(<64 x i8> %x, <64 x i8> %y) nounwind {
86; SSE-LABEL: v64i8:
87; SSE:       # %bb.0:
88; SSE-NEXT:    psubusb %xmm4, %xmm0
89; SSE-NEXT:    psubusb %xmm5, %xmm1
90; SSE-NEXT:    psubusb %xmm6, %xmm2
91; SSE-NEXT:    psubusb %xmm7, %xmm3
92; SSE-NEXT:    retq
93;
94; AVX1-LABEL: v64i8:
95; AVX1:       # %bb.0:
96; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
97; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
98; AVX1-NEXT:    vpsubusb %xmm4, %xmm5, %xmm4
99; AVX1-NEXT:    vpsubusb %xmm2, %xmm0, %xmm0
100; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm0, %ymm0
101; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm2
102; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
103; AVX1-NEXT:    vpsubusb %xmm2, %xmm4, %xmm2
104; AVX1-NEXT:    vpsubusb %xmm3, %xmm1, %xmm1
105; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
106; AVX1-NEXT:    retq
107;
108; AVX2-LABEL: v64i8:
109; AVX2:       # %bb.0:
110; AVX2-NEXT:    vpsubusb %ymm2, %ymm0, %ymm0
111; AVX2-NEXT:    vpsubusb %ymm3, %ymm1, %ymm1
112; AVX2-NEXT:    retq
113;
114; AVX512-LABEL: v64i8:
115; AVX512:       # %bb.0:
116; AVX512-NEXT:    vpsubusb %zmm1, %zmm0, %zmm0
117; AVX512-NEXT:    retq
118  %z = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %x, <64 x i8> %y)
119  ret <64 x i8> %z
120}
121
122define <8 x i16> @v8i16(<8 x i16> %x, <8 x i16> %y) nounwind {
123; SSE-LABEL: v8i16:
124; SSE:       # %bb.0:
125; SSE-NEXT:    psubusw %xmm1, %xmm0
126; SSE-NEXT:    retq
127;
128; AVX-LABEL: v8i16:
129; AVX:       # %bb.0:
130; AVX-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
131; AVX-NEXT:    retq
132  %z = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %x, <8 x i16> %y)
133  ret <8 x i16> %z
134}
135
136define <16 x i16> @v16i16(<16 x i16> %x, <16 x i16> %y) nounwind {
137; SSE-LABEL: v16i16:
138; SSE:       # %bb.0:
139; SSE-NEXT:    psubusw %xmm2, %xmm0
140; SSE-NEXT:    psubusw %xmm3, %xmm1
141; SSE-NEXT:    retq
142;
143; AVX1-LABEL: v16i16:
144; AVX1:       # %bb.0:
145; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
146; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
147; AVX1-NEXT:    vpsubusw %xmm2, %xmm3, %xmm2
148; AVX1-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
149; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
150; AVX1-NEXT:    retq
151;
152; AVX2-LABEL: v16i16:
153; AVX2:       # %bb.0:
154; AVX2-NEXT:    vpsubusw %ymm1, %ymm0, %ymm0
155; AVX2-NEXT:    retq
156;
157; AVX512-LABEL: v16i16:
158; AVX512:       # %bb.0:
159; AVX512-NEXT:    vpsubusw %ymm1, %ymm0, %ymm0
160; AVX512-NEXT:    retq
161  %z = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %x, <16 x i16> %y)
162  ret <16 x i16> %z
163}
164
165define <32 x i16> @v32i16(<32 x i16> %x, <32 x i16> %y) nounwind {
166; SSE-LABEL: v32i16:
167; SSE:       # %bb.0:
168; SSE-NEXT:    psubusw %xmm4, %xmm0
169; SSE-NEXT:    psubusw %xmm5, %xmm1
170; SSE-NEXT:    psubusw %xmm6, %xmm2
171; SSE-NEXT:    psubusw %xmm7, %xmm3
172; SSE-NEXT:    retq
173;
174; AVX1-LABEL: v32i16:
175; AVX1:       # %bb.0:
176; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
177; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
178; AVX1-NEXT:    vpsubusw %xmm4, %xmm5, %xmm4
179; AVX1-NEXT:    vpsubusw %xmm2, %xmm0, %xmm0
180; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm0, %ymm0
181; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm2
182; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
183; AVX1-NEXT:    vpsubusw %xmm2, %xmm4, %xmm2
184; AVX1-NEXT:    vpsubusw %xmm3, %xmm1, %xmm1
185; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
186; AVX1-NEXT:    retq
187;
188; AVX2-LABEL: v32i16:
189; AVX2:       # %bb.0:
190; AVX2-NEXT:    vpsubusw %ymm2, %ymm0, %ymm0
191; AVX2-NEXT:    vpsubusw %ymm3, %ymm1, %ymm1
192; AVX2-NEXT:    retq
193;
194; AVX512-LABEL: v32i16:
195; AVX512:       # %bb.0:
196; AVX512-NEXT:    vpsubusw %zmm1, %zmm0, %zmm0
197; AVX512-NEXT:    retq
198  %z = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %x, <32 x i16> %y)
199  ret <32 x i16> %z
200}
201
202; Too narrow vectors, legalized by widening.
203
204define void @v8i8(<8 x i8>* %px, <8 x i8>* %py, <8 x i8>* %pz) nounwind {
205; SSE-LABEL: v8i8:
206; SSE:       # %bb.0:
207; SSE-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero
208; SSE-NEXT:    movq {{.*#+}} xmm1 = mem[0],zero
209; SSE-NEXT:    psubusb %xmm1, %xmm0
210; SSE-NEXT:    movq %xmm0, (%rdx)
211; SSE-NEXT:    retq
212;
213; AVX1-LABEL: v8i8:
214; AVX1:       # %bb.0:
215; AVX1-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
216; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
217; AVX1-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
218; AVX1-NEXT:    vmovq %xmm0, (%rdx)
219; AVX1-NEXT:    retq
220;
221; AVX2-LABEL: v8i8:
222; AVX2:       # %bb.0:
223; AVX2-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
224; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
225; AVX2-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
226; AVX2-NEXT:    vmovq %xmm0, (%rdx)
227; AVX2-NEXT:    retq
228;
229; AVX512-LABEL: v8i8:
230; AVX512:       # %bb.0:
231; AVX512-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
232; AVX512-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
233; AVX512-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
234; AVX512-NEXT:    vpmovzxbw {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
235; AVX512-NEXT:    vpmovwb %xmm0, (%rdx)
236; AVX512-NEXT:    retq
237  %x = load <8 x i8>, <8 x i8>* %px
238  %y = load <8 x i8>, <8 x i8>* %py
239  %z = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %x, <8 x i8> %y)
240  store <8 x i8> %z, <8 x i8>* %pz
241  ret void
242}
243
244define void @v4i8(<4 x i8>* %px, <4 x i8>* %py, <4 x i8>* %pz) nounwind {
245; SSE-LABEL: v4i8:
246; SSE:       # %bb.0:
247; SSE-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
248; SSE-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
249; SSE-NEXT:    psubusb %xmm1, %xmm0
250; SSE-NEXT:    movd %xmm0, (%rdx)
251; SSE-NEXT:    retq
252;
253; AVX1-LABEL: v4i8:
254; AVX1:       # %bb.0:
255; AVX1-NEXT:    vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
256; AVX1-NEXT:    vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero
257; AVX1-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
258; AVX1-NEXT:    vmovd %xmm0, (%rdx)
259; AVX1-NEXT:    retq
260;
261; AVX2-LABEL: v4i8:
262; AVX2:       # %bb.0:
263; AVX2-NEXT:    vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
264; AVX2-NEXT:    vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero
265; AVX2-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
266; AVX2-NEXT:    vmovd %xmm0, (%rdx)
267; AVX2-NEXT:    retq
268;
269; AVX512-LABEL: v4i8:
270; AVX512:       # %bb.0:
271; AVX512-NEXT:    vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
272; AVX512-NEXT:    vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero
273; AVX512-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
274; AVX512-NEXT:    vpmovzxbd {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero
275; AVX512-NEXT:    vpmovdb %xmm0, (%rdx)
276; AVX512-NEXT:    retq
277  %x = load <4 x i8>, <4 x i8>* %px
278  %y = load <4 x i8>, <4 x i8>* %py
279  %z = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %x, <4 x i8> %y)
280  store <4 x i8> %z, <4 x i8>* %pz
281  ret void
282}
283
284define void @v2i8(<2 x i8>* %px, <2 x i8>* %py, <2 x i8>* %pz) nounwind {
285; SSE2-LABEL: v2i8:
286; SSE2:       # %bb.0:
287; SSE2-NEXT:    movzwl (%rdi), %eax
288; SSE2-NEXT:    movd %eax, %xmm0
289; SSE2-NEXT:    movzwl (%rsi), %eax
290; SSE2-NEXT:    movd %eax, %xmm1
291; SSE2-NEXT:    psubusb %xmm1, %xmm0
292; SSE2-NEXT:    movd %xmm0, %eax
293; SSE2-NEXT:    movw %ax, (%rdx)
294; SSE2-NEXT:    retq
295;
296; SSSE3-LABEL: v2i8:
297; SSSE3:       # %bb.0:
298; SSSE3-NEXT:    movzwl (%rdi), %eax
299; SSSE3-NEXT:    movd %eax, %xmm0
300; SSSE3-NEXT:    movzwl (%rsi), %eax
301; SSSE3-NEXT:    movd %eax, %xmm1
302; SSSE3-NEXT:    psubusb %xmm1, %xmm0
303; SSSE3-NEXT:    movd %xmm0, %eax
304; SSSE3-NEXT:    movw %ax, (%rdx)
305; SSSE3-NEXT:    retq
306;
307; SSE41-LABEL: v2i8:
308; SSE41:       # %bb.0:
309; SSE41-NEXT:    movzwl (%rdi), %eax
310; SSE41-NEXT:    movd %eax, %xmm0
311; SSE41-NEXT:    movzwl (%rsi), %eax
312; SSE41-NEXT:    movd %eax, %xmm1
313; SSE41-NEXT:    psubusb %xmm1, %xmm0
314; SSE41-NEXT:    pextrw $0, %xmm0, (%rdx)
315; SSE41-NEXT:    retq
316;
317; AVX1-LABEL: v2i8:
318; AVX1:       # %bb.0:
319; AVX1-NEXT:    movzwl (%rdi), %eax
320; AVX1-NEXT:    vmovd %eax, %xmm0
321; AVX1-NEXT:    movzwl (%rsi), %eax
322; AVX1-NEXT:    vmovd %eax, %xmm1
323; AVX1-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
324; AVX1-NEXT:    vpextrw $0, %xmm0, (%rdx)
325; AVX1-NEXT:    retq
326;
327; AVX2-LABEL: v2i8:
328; AVX2:       # %bb.0:
329; AVX2-NEXT:    movzwl (%rdi), %eax
330; AVX2-NEXT:    vmovd %eax, %xmm0
331; AVX2-NEXT:    movzwl (%rsi), %eax
332; AVX2-NEXT:    vmovd %eax, %xmm1
333; AVX2-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
334; AVX2-NEXT:    vpextrw $0, %xmm0, (%rdx)
335; AVX2-NEXT:    retq
336;
337; AVX512-LABEL: v2i8:
338; AVX512:       # %bb.0:
339; AVX512-NEXT:    movzwl (%rdi), %eax
340; AVX512-NEXT:    vmovd %eax, %xmm0
341; AVX512-NEXT:    movzwl (%rsi), %eax
342; AVX512-NEXT:    vmovd %eax, %xmm1
343; AVX512-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
344; AVX512-NEXT:    vpmovzxbq {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,zero,zero,zero,zero,xmm0[1],zero,zero,zero,zero,zero,zero,zero
345; AVX512-NEXT:    vpmovqb %xmm0, (%rdx)
346; AVX512-NEXT:    retq
347  %x = load <2 x i8>, <2 x i8>* %px
348  %y = load <2 x i8>, <2 x i8>* %py
349  %z = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %x, <2 x i8> %y)
350  store <2 x i8> %z, <2 x i8>* %pz
351  ret void
352}
353
354define void @v4i16(<4 x i16>* %px, <4 x i16>* %py, <4 x i16>* %pz) nounwind {
355; SSE-LABEL: v4i16:
356; SSE:       # %bb.0:
357; SSE-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero
358; SSE-NEXT:    movq {{.*#+}} xmm1 = mem[0],zero
359; SSE-NEXT:    psubusw %xmm1, %xmm0
360; SSE-NEXT:    movq %xmm0, (%rdx)
361; SSE-NEXT:    retq
362;
363; AVX1-LABEL: v4i16:
364; AVX1:       # %bb.0:
365; AVX1-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
366; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
367; AVX1-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
368; AVX1-NEXT:    vmovq %xmm0, (%rdx)
369; AVX1-NEXT:    retq
370;
371; AVX2-LABEL: v4i16:
372; AVX2:       # %bb.0:
373; AVX2-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
374; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
375; AVX2-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
376; AVX2-NEXT:    vmovq %xmm0, (%rdx)
377; AVX2-NEXT:    retq
378;
379; AVX512-LABEL: v4i16:
380; AVX512:       # %bb.0:
381; AVX512-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
382; AVX512-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
383; AVX512-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
384; AVX512-NEXT:    vpmovzxwd {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero
385; AVX512-NEXT:    vpmovdw %xmm0, (%rdx)
386; AVX512-NEXT:    retq
387  %x = load <4 x i16>, <4 x i16>* %px
388  %y = load <4 x i16>, <4 x i16>* %py
389  %z = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %x, <4 x i16> %y)
390  store <4 x i16> %z, <4 x i16>* %pz
391  ret void
392}
393
394define void @v2i16(<2 x i16>* %px, <2 x i16>* %py, <2 x i16>* %pz) nounwind {
395; SSE-LABEL: v2i16:
396; SSE:       # %bb.0:
397; SSE-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
398; SSE-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
399; SSE-NEXT:    psubusw %xmm1, %xmm0
400; SSE-NEXT:    movd %xmm0, (%rdx)
401; SSE-NEXT:    retq
402;
403; AVX1-LABEL: v2i16:
404; AVX1:       # %bb.0:
405; AVX1-NEXT:    vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
406; AVX1-NEXT:    vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero
407; AVX1-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
408; AVX1-NEXT:    vmovd %xmm0, (%rdx)
409; AVX1-NEXT:    retq
410;
411; AVX2-LABEL: v2i16:
412; AVX2:       # %bb.0:
413; AVX2-NEXT:    vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
414; AVX2-NEXT:    vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero
415; AVX2-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
416; AVX2-NEXT:    vmovd %xmm0, (%rdx)
417; AVX2-NEXT:    retq
418;
419; AVX512-LABEL: v2i16:
420; AVX512:       # %bb.0:
421; AVX512-NEXT:    vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
422; AVX512-NEXT:    vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero
423; AVX512-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
424; AVX512-NEXT:    vpmovzxwq {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero
425; AVX512-NEXT:    vpmovqw %xmm0, (%rdx)
426; AVX512-NEXT:    retq
427  %x = load <2 x i16>, <2 x i16>* %px
428  %y = load <2 x i16>, <2 x i16>* %py
429  %z = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %x, <2 x i16> %y)
430  store <2 x i16> %z, <2 x i16>* %pz
431  ret void
432}
433
434define <12 x i8> @v12i8(<12 x i8> %x, <12 x i8> %y) nounwind {
435; SSE-LABEL: v12i8:
436; SSE:       # %bb.0:
437; SSE-NEXT:    psubusb %xmm1, %xmm0
438; SSE-NEXT:    retq
439;
440; AVX-LABEL: v12i8:
441; AVX:       # %bb.0:
442; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
443; AVX-NEXT:    retq
444  %z = call <12 x i8> @llvm.usub.sat.v12i8(<12 x i8> %x, <12 x i8> %y)
445  ret <12 x i8> %z
446}
447
448define void @v12i16(<12 x i16>* %px, <12 x i16>* %py, <12 x i16>* %pz) nounwind {
449; SSE-LABEL: v12i16:
450; SSE:       # %bb.0:
451; SSE-NEXT:    movdqa (%rdi), %xmm0
452; SSE-NEXT:    movdqa 16(%rdi), %xmm1
453; SSE-NEXT:    psubusw (%rsi), %xmm0
454; SSE-NEXT:    psubusw 16(%rsi), %xmm1
455; SSE-NEXT:    movq %xmm1, 16(%rdx)
456; SSE-NEXT:    movdqa %xmm0, (%rdx)
457; SSE-NEXT:    retq
458;
459; AVX1-LABEL: v12i16:
460; AVX1:       # %bb.0:
461; AVX1-NEXT:    vmovdqa (%rdi), %xmm0
462; AVX1-NEXT:    vmovdqa 16(%rdi), %xmm1
463; AVX1-NEXT:    vpsubusw 16(%rsi), %xmm1, %xmm1
464; AVX1-NEXT:    vpsubusw (%rsi), %xmm0, %xmm0
465; AVX1-NEXT:    vmovdqa %xmm0, (%rdx)
466; AVX1-NEXT:    vmovq %xmm1, 16(%rdx)
467; AVX1-NEXT:    retq
468;
469; AVX2-LABEL: v12i16:
470; AVX2:       # %bb.0:
471; AVX2-NEXT:    vmovdqa (%rdi), %ymm0
472; AVX2-NEXT:    vpsubusw (%rsi), %ymm0, %ymm0
473; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
474; AVX2-NEXT:    vmovq %xmm1, 16(%rdx)
475; AVX2-NEXT:    vmovdqa %xmm0, (%rdx)
476; AVX2-NEXT:    vzeroupper
477; AVX2-NEXT:    retq
478;
479; AVX512-LABEL: v12i16:
480; AVX512:       # %bb.0:
481; AVX512-NEXT:    vmovdqa (%rdi), %ymm0
482; AVX512-NEXT:    vpsubusw (%rsi), %ymm0, %ymm0
483; AVX512-NEXT:    vextracti128 $1, %ymm0, %xmm1
484; AVX512-NEXT:    vmovq %xmm1, 16(%rdx)
485; AVX512-NEXT:    vmovdqa %xmm0, (%rdx)
486; AVX512-NEXT:    vzeroupper
487; AVX512-NEXT:    retq
488  %x = load <12 x i16>, <12 x i16>* %px
489  %y = load <12 x i16>, <12 x i16>* %py
490  %z = call <12 x i16> @llvm.usub.sat.v12i16(<12 x i16> %x, <12 x i16> %y)
491  store <12 x i16> %z, <12 x i16>* %pz
492  ret void
493}
494
495; Scalarization
496
497define void @v1i8(<1 x i8>* %px, <1 x i8>* %py, <1 x i8>* %pz) nounwind {
498; SSE-LABEL: v1i8:
499; SSE:       # %bb.0:
500; SSE-NEXT:    movb (%rdi), %al
501; SSE-NEXT:    xorl %ecx, %ecx
502; SSE-NEXT:    subb (%rsi), %al
503; SSE-NEXT:    movzbl %al, %eax
504; SSE-NEXT:    cmovbl %ecx, %eax
505; SSE-NEXT:    movb %al, (%rdx)
506; SSE-NEXT:    retq
507;
508; AVX-LABEL: v1i8:
509; AVX:       # %bb.0:
510; AVX-NEXT:    movb (%rdi), %al
511; AVX-NEXT:    xorl %ecx, %ecx
512; AVX-NEXT:    subb (%rsi), %al
513; AVX-NEXT:    movzbl %al, %eax
514; AVX-NEXT:    cmovbl %ecx, %eax
515; AVX-NEXT:    movb %al, (%rdx)
516; AVX-NEXT:    retq
517  %x = load <1 x i8>, <1 x i8>* %px
518  %y = load <1 x i8>, <1 x i8>* %py
519  %z = call <1 x i8> @llvm.usub.sat.v1i8(<1 x i8> %x, <1 x i8> %y)
520  store <1 x i8> %z, <1 x i8>* %pz
521  ret void
522}
523
524define void @v1i16(<1 x i16>* %px, <1 x i16>* %py, <1 x i16>* %pz) nounwind {
525; SSE-LABEL: v1i16:
526; SSE:       # %bb.0:
527; SSE-NEXT:    movzwl (%rdi), %eax
528; SSE-NEXT:    xorl %ecx, %ecx
529; SSE-NEXT:    subw (%rsi), %ax
530; SSE-NEXT:    cmovbl %ecx, %eax
531; SSE-NEXT:    movw %ax, (%rdx)
532; SSE-NEXT:    retq
533;
534; AVX-LABEL: v1i16:
535; AVX:       # %bb.0:
536; AVX-NEXT:    movzwl (%rdi), %eax
537; AVX-NEXT:    xorl %ecx, %ecx
538; AVX-NEXT:    subw (%rsi), %ax
539; AVX-NEXT:    cmovbl %ecx, %eax
540; AVX-NEXT:    movw %ax, (%rdx)
541; AVX-NEXT:    retq
542  %x = load <1 x i16>, <1 x i16>* %px
543  %y = load <1 x i16>, <1 x i16>* %py
544  %z = call <1 x i16> @llvm.usub.sat.v1i16(<1 x i16> %x, <1 x i16> %y)
545  store <1 x i16> %z, <1 x i16>* %pz
546  ret void
547}
548
549; Promotion
550
551define <16 x i4> @v16i4(<16 x i4> %x, <16 x i4> %y) nounwind {
552; SSE-LABEL: v16i4:
553; SSE:       # %bb.0:
554; SSE-NEXT:    psllw $4, %xmm1
555; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240]
556; SSE-NEXT:    pand %xmm2, %xmm1
557; SSE-NEXT:    psllw $4, %xmm0
558; SSE-NEXT:    pand %xmm2, %xmm0
559; SSE-NEXT:    psubusb %xmm1, %xmm0
560; SSE-NEXT:    psrlw $4, %xmm0
561; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
562; SSE-NEXT:    retq
563;
564; AVX-LABEL: v16i4:
565; AVX:       # %bb.0:
566; AVX-NEXT:    vpsllw $4, %xmm1, %xmm1
567; AVX-NEXT:    vmovdqa {{.*#+}} xmm2 = [240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240]
568; AVX-NEXT:    vpand %xmm2, %xmm1, %xmm1
569; AVX-NEXT:    vpsllw $4, %xmm0, %xmm0
570; AVX-NEXT:    vpand %xmm2, %xmm0, %xmm0
571; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
572; AVX-NEXT:    vpsrlw $4, %xmm0, %xmm0
573; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
574; AVX-NEXT:    retq
575  %z = call <16 x i4> @llvm.usub.sat.v16i4(<16 x i4> %x, <16 x i4> %y)
576  ret <16 x i4> %z
577}
578
579define <16 x i1> @v16i1(<16 x i1> %x, <16 x i1> %y) nounwind {
580; SSE-LABEL: v16i1:
581; SSE:       # %bb.0:
582; SSE-NEXT:    psllw $7, %xmm1
583; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
584; SSE-NEXT:    pand %xmm2, %xmm1
585; SSE-NEXT:    psllw $7, %xmm0
586; SSE-NEXT:    pand %xmm2, %xmm0
587; SSE-NEXT:    psubusb %xmm1, %xmm0
588; SSE-NEXT:    psrlw $7, %xmm0
589; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
590; SSE-NEXT:    retq
591;
592; AVX1-LABEL: v16i1:
593; AVX1:       # %bb.0:
594; AVX1-NEXT:    vpsllw $7, %xmm1, %xmm1
595; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
596; AVX1-NEXT:    vpand %xmm2, %xmm1, %xmm1
597; AVX1-NEXT:    vpsllw $7, %xmm0, %xmm0
598; AVX1-NEXT:    vpand %xmm2, %xmm0, %xmm0
599; AVX1-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
600; AVX1-NEXT:    vpsrlw $7, %xmm0, %xmm0
601; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
602; AVX1-NEXT:    retq
603;
604; AVX2-LABEL: v16i1:
605; AVX2:       # %bb.0:
606; AVX2-NEXT:    vpsllw $7, %xmm1, %xmm1
607; AVX2-NEXT:    vmovdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
608; AVX2-NEXT:    vpand %xmm2, %xmm1, %xmm1
609; AVX2-NEXT:    vpsllw $7, %xmm0, %xmm0
610; AVX2-NEXT:    vpand %xmm2, %xmm0, %xmm0
611; AVX2-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
612; AVX2-NEXT:    vpsrlw $7, %xmm0, %xmm0
613; AVX2-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
614; AVX2-NEXT:    retq
615;
616; AVX512-LABEL: v16i1:
617; AVX512:       # %bb.0:
618; AVX512-NEXT:    vpsllw $7, %xmm0, %xmm0
619; AVX512-NEXT:    vpmovb2m %xmm0, %k0
620; AVX512-NEXT:    vpsllw $7, %xmm1, %xmm0
621; AVX512-NEXT:    vpmovb2m %xmm0, %k1
622; AVX512-NEXT:    kandnw %k0, %k1, %k0
623; AVX512-NEXT:    vpmovm2b %k0, %xmm0
624; AVX512-NEXT:    retq
625  %z = call <16 x i1> @llvm.usub.sat.v16i1(<16 x i1> %x, <16 x i1> %y)
626  ret <16 x i1> %z
627}
628
629; Expanded
630
631define <2 x i32> @v2i32(<2 x i32> %x, <2 x i32> %y) nounwind {
632; SSE2-LABEL: v2i32:
633; SSE2:       # %bb.0:
634; SSE2-NEXT:    psllq $32, %xmm1
635; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [9223372039002259456,9223372039002259456]
636; SSE2-NEXT:    movdqa %xmm1, %xmm3
637; SSE2-NEXT:    pxor %xmm2, %xmm3
638; SSE2-NEXT:    psllq $32, %xmm0
639; SSE2-NEXT:    pxor %xmm0, %xmm2
640; SSE2-NEXT:    movdqa %xmm2, %xmm4
641; SSE2-NEXT:    pcmpeqd %xmm3, %xmm4
642; SSE2-NEXT:    pcmpgtd %xmm3, %xmm2
643; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[0,0,2,2]
644; SSE2-NEXT:    pand %xmm4, %xmm3
645; SSE2-NEXT:    por %xmm2, %xmm3
646; SSE2-NEXT:    psubq %xmm1, %xmm0
647; SSE2-NEXT:    pand %xmm3, %xmm0
648; SSE2-NEXT:    psrlq $32, %xmm0
649; SSE2-NEXT:    retq
650;
651; SSSE3-LABEL: v2i32:
652; SSSE3:       # %bb.0:
653; SSSE3-NEXT:    psllq $32, %xmm1
654; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [9223372039002259456,9223372039002259456]
655; SSSE3-NEXT:    movdqa %xmm1, %xmm3
656; SSSE3-NEXT:    pxor %xmm2, %xmm3
657; SSSE3-NEXT:    psllq $32, %xmm0
658; SSSE3-NEXT:    pxor %xmm0, %xmm2
659; SSSE3-NEXT:    movdqa %xmm2, %xmm4
660; SSSE3-NEXT:    pcmpeqd %xmm3, %xmm4
661; SSSE3-NEXT:    pcmpgtd %xmm3, %xmm2
662; SSSE3-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[0,0,2,2]
663; SSSE3-NEXT:    pand %xmm4, %xmm3
664; SSSE3-NEXT:    por %xmm2, %xmm3
665; SSSE3-NEXT:    psubq %xmm1, %xmm0
666; SSSE3-NEXT:    pand %xmm3, %xmm0
667; SSSE3-NEXT:    psrlq $32, %xmm0
668; SSSE3-NEXT:    retq
669;
670; SSE41-LABEL: v2i32:
671; SSE41:       # %bb.0:
672; SSE41-NEXT:    movdqa %xmm0, %xmm2
673; SSE41-NEXT:    psllq $32, %xmm1
674; SSE41-NEXT:    movdqa {{.*#+}} xmm0 = [9223372039002259456,9223372039002259456]
675; SSE41-NEXT:    movdqa %xmm1, %xmm3
676; SSE41-NEXT:    pxor %xmm0, %xmm3
677; SSE41-NEXT:    psllq $32, %xmm2
678; SSE41-NEXT:    pxor %xmm2, %xmm0
679; SSE41-NEXT:    movdqa %xmm0, %xmm4
680; SSE41-NEXT:    pcmpgtd %xmm3, %xmm4
681; SSE41-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
682; SSE41-NEXT:    pcmpeqd %xmm3, %xmm0
683; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
684; SSE41-NEXT:    pand %xmm5, %xmm0
685; SSE41-NEXT:    por %xmm4, %xmm0
686; SSE41-NEXT:    psubq %xmm1, %xmm2
687; SSE41-NEXT:    pxor %xmm1, %xmm1
688; SSE41-NEXT:    blendvpd %xmm0, %xmm2, %xmm1
689; SSE41-NEXT:    psrlq $32, %xmm1
690; SSE41-NEXT:    movdqa %xmm1, %xmm0
691; SSE41-NEXT:    retq
692;
693; AVX1-LABEL: v2i32:
694; AVX1:       # %bb.0:
695; AVX1-NEXT:    vpsllq $32, %xmm1, %xmm1
696; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
697; AVX1-NEXT:    vpxor %xmm2, %xmm1, %xmm3
698; AVX1-NEXT:    vpsllq $32, %xmm0, %xmm0
699; AVX1-NEXT:    vpxor %xmm2, %xmm0, %xmm2
700; AVX1-NEXT:    vpcmpgtq %xmm3, %xmm2, %xmm2
701; AVX1-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
702; AVX1-NEXT:    vpand %xmm0, %xmm2, %xmm0
703; AVX1-NEXT:    vpsrlq $32, %xmm0, %xmm0
704; AVX1-NEXT:    retq
705;
706; AVX2-LABEL: v2i32:
707; AVX2:       # %bb.0:
708; AVX2-NEXT:    vpsllq $32, %xmm1, %xmm1
709; AVX2-NEXT:    vmovdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
710; AVX2-NEXT:    vpxor %xmm2, %xmm1, %xmm3
711; AVX2-NEXT:    vpsllq $32, %xmm0, %xmm0
712; AVX2-NEXT:    vpxor %xmm2, %xmm0, %xmm2
713; AVX2-NEXT:    vpcmpgtq %xmm3, %xmm2, %xmm2
714; AVX2-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
715; AVX2-NEXT:    vpand %xmm0, %xmm2, %xmm0
716; AVX2-NEXT:    vpsrlq $32, %xmm0, %xmm0
717; AVX2-NEXT:    retq
718;
719; AVX512-LABEL: v2i32:
720; AVX512:       # %bb.0:
721; AVX512-NEXT:    vpsllq $32, %xmm1, %xmm1
722; AVX512-NEXT:    vpsllq $32, %xmm0, %xmm0
723; AVX512-NEXT:    vpmaxuq %xmm1, %xmm0, %xmm0
724; AVX512-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
725; AVX512-NEXT:    vpsrlq $32, %xmm0, %xmm0
726; AVX512-NEXT:    retq
727  %z = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %x, <2 x i32> %y)
728  ret <2 x i32> %z
729}
730
731define <4 x i32> @v4i32(<4 x i32> %x, <4 x i32> %y) nounwind {
732; SSE2-LABEL: v4i32:
733; SSE2:       # %bb.0:
734; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
735; SSE2-NEXT:    movdqa %xmm1, %xmm3
736; SSE2-NEXT:    pxor %xmm2, %xmm3
737; SSE2-NEXT:    pxor %xmm0, %xmm2
738; SSE2-NEXT:    pcmpgtd %xmm3, %xmm2
739; SSE2-NEXT:    psubd %xmm1, %xmm0
740; SSE2-NEXT:    pand %xmm2, %xmm0
741; SSE2-NEXT:    retq
742;
743; SSSE3-LABEL: v4i32:
744; SSSE3:       # %bb.0:
745; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
746; SSSE3-NEXT:    movdqa %xmm1, %xmm3
747; SSSE3-NEXT:    pxor %xmm2, %xmm3
748; SSSE3-NEXT:    pxor %xmm0, %xmm2
749; SSSE3-NEXT:    pcmpgtd %xmm3, %xmm2
750; SSSE3-NEXT:    psubd %xmm1, %xmm0
751; SSSE3-NEXT:    pand %xmm2, %xmm0
752; SSSE3-NEXT:    retq
753;
754; SSE41-LABEL: v4i32:
755; SSE41:       # %bb.0:
756; SSE41-NEXT:    pmaxud %xmm1, %xmm0
757; SSE41-NEXT:    psubd %xmm1, %xmm0
758; SSE41-NEXT:    retq
759;
760; AVX-LABEL: v4i32:
761; AVX:       # %bb.0:
762; AVX-NEXT:    vpmaxud %xmm1, %xmm0, %xmm0
763; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
764; AVX-NEXT:    retq
765  %z = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %x, <4 x i32> %y)
766  ret <4 x i32> %z
767}
768
769define <8 x i32> @v8i32(<8 x i32> %x, <8 x i32> %y) nounwind {
770; SSE2-LABEL: v8i32:
771; SSE2:       # %bb.0:
772; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [2147483648,2147483648,2147483648,2147483648]
773; SSE2-NEXT:    movdqa %xmm0, %xmm5
774; SSE2-NEXT:    psubd %xmm2, %xmm0
775; SSE2-NEXT:    pxor %xmm4, %xmm2
776; SSE2-NEXT:    pxor %xmm4, %xmm5
777; SSE2-NEXT:    pcmpgtd %xmm2, %xmm5
778; SSE2-NEXT:    pand %xmm5, %xmm0
779; SSE2-NEXT:    movdqa %xmm3, %xmm2
780; SSE2-NEXT:    pxor %xmm4, %xmm2
781; SSE2-NEXT:    pxor %xmm1, %xmm4
782; SSE2-NEXT:    pcmpgtd %xmm2, %xmm4
783; SSE2-NEXT:    psubd %xmm3, %xmm1
784; SSE2-NEXT:    pand %xmm4, %xmm1
785; SSE2-NEXT:    retq
786;
787; SSSE3-LABEL: v8i32:
788; SSSE3:       # %bb.0:
789; SSSE3-NEXT:    movdqa {{.*#+}} xmm4 = [2147483648,2147483648,2147483648,2147483648]
790; SSSE3-NEXT:    movdqa %xmm0, %xmm5
791; SSSE3-NEXT:    psubd %xmm2, %xmm0
792; SSSE3-NEXT:    pxor %xmm4, %xmm2
793; SSSE3-NEXT:    pxor %xmm4, %xmm5
794; SSSE3-NEXT:    pcmpgtd %xmm2, %xmm5
795; SSSE3-NEXT:    pand %xmm5, %xmm0
796; SSSE3-NEXT:    movdqa %xmm3, %xmm2
797; SSSE3-NEXT:    pxor %xmm4, %xmm2
798; SSSE3-NEXT:    pxor %xmm1, %xmm4
799; SSSE3-NEXT:    pcmpgtd %xmm2, %xmm4
800; SSSE3-NEXT:    psubd %xmm3, %xmm1
801; SSSE3-NEXT:    pand %xmm4, %xmm1
802; SSSE3-NEXT:    retq
803;
804; SSE41-LABEL: v8i32:
805; SSE41:       # %bb.0:
806; SSE41-NEXT:    pmaxud %xmm2, %xmm0
807; SSE41-NEXT:    psubd %xmm2, %xmm0
808; SSE41-NEXT:    pmaxud %xmm3, %xmm1
809; SSE41-NEXT:    psubd %xmm3, %xmm1
810; SSE41-NEXT:    retq
811;
812; AVX1-LABEL: v8i32:
813; AVX1:       # %bb.0:
814; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
815; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
816; AVX1-NEXT:    vpmaxud %xmm2, %xmm3, %xmm3
817; AVX1-NEXT:    vpsubd %xmm2, %xmm3, %xmm2
818; AVX1-NEXT:    vpmaxud %xmm1, %xmm0, %xmm0
819; AVX1-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
820; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
821; AVX1-NEXT:    retq
822;
823; AVX2-LABEL: v8i32:
824; AVX2:       # %bb.0:
825; AVX2-NEXT:    vpmaxud %ymm1, %ymm0, %ymm0
826; AVX2-NEXT:    vpsubd %ymm1, %ymm0, %ymm0
827; AVX2-NEXT:    retq
828;
829; AVX512-LABEL: v8i32:
830; AVX512:       # %bb.0:
831; AVX512-NEXT:    vpmaxud %ymm1, %ymm0, %ymm0
832; AVX512-NEXT:    vpsubd %ymm1, %ymm0, %ymm0
833; AVX512-NEXT:    retq
834  %z = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %x, <8 x i32> %y)
835  ret <8 x i32> %z
836}
837
838define <16 x i32> @v16i32(<16 x i32> %x, <16 x i32> %y) nounwind {
839; SSE2-LABEL: v16i32:
840; SSE2:       # %bb.0:
841; SSE2-NEXT:    movdqa {{.*#+}} xmm8 = [2147483648,2147483648,2147483648,2147483648]
842; SSE2-NEXT:    movdqa %xmm0, %xmm9
843; SSE2-NEXT:    psubd %xmm4, %xmm0
844; SSE2-NEXT:    pxor %xmm8, %xmm4
845; SSE2-NEXT:    pxor %xmm8, %xmm9
846; SSE2-NEXT:    pcmpgtd %xmm4, %xmm9
847; SSE2-NEXT:    pand %xmm9, %xmm0
848; SSE2-NEXT:    movdqa %xmm1, %xmm4
849; SSE2-NEXT:    psubd %xmm5, %xmm1
850; SSE2-NEXT:    pxor %xmm8, %xmm5
851; SSE2-NEXT:    pxor %xmm8, %xmm4
852; SSE2-NEXT:    pcmpgtd %xmm5, %xmm4
853; SSE2-NEXT:    pand %xmm4, %xmm1
854; SSE2-NEXT:    movdqa %xmm2, %xmm4
855; SSE2-NEXT:    psubd %xmm6, %xmm2
856; SSE2-NEXT:    pxor %xmm8, %xmm6
857; SSE2-NEXT:    pxor %xmm8, %xmm4
858; SSE2-NEXT:    pcmpgtd %xmm6, %xmm4
859; SSE2-NEXT:    pand %xmm4, %xmm2
860; SSE2-NEXT:    movdqa %xmm7, %xmm4
861; SSE2-NEXT:    pxor %xmm8, %xmm4
862; SSE2-NEXT:    pxor %xmm3, %xmm8
863; SSE2-NEXT:    pcmpgtd %xmm4, %xmm8
864; SSE2-NEXT:    psubd %xmm7, %xmm3
865; SSE2-NEXT:    pand %xmm8, %xmm3
866; SSE2-NEXT:    retq
867;
868; SSSE3-LABEL: v16i32:
869; SSSE3:       # %bb.0:
870; SSSE3-NEXT:    movdqa {{.*#+}} xmm8 = [2147483648,2147483648,2147483648,2147483648]
871; SSSE3-NEXT:    movdqa %xmm0, %xmm9
872; SSSE3-NEXT:    psubd %xmm4, %xmm0
873; SSSE3-NEXT:    pxor %xmm8, %xmm4
874; SSSE3-NEXT:    pxor %xmm8, %xmm9
875; SSSE3-NEXT:    pcmpgtd %xmm4, %xmm9
876; SSSE3-NEXT:    pand %xmm9, %xmm0
877; SSSE3-NEXT:    movdqa %xmm1, %xmm4
878; SSSE3-NEXT:    psubd %xmm5, %xmm1
879; SSSE3-NEXT:    pxor %xmm8, %xmm5
880; SSSE3-NEXT:    pxor %xmm8, %xmm4
881; SSSE3-NEXT:    pcmpgtd %xmm5, %xmm4
882; SSSE3-NEXT:    pand %xmm4, %xmm1
883; SSSE3-NEXT:    movdqa %xmm2, %xmm4
884; SSSE3-NEXT:    psubd %xmm6, %xmm2
885; SSSE3-NEXT:    pxor %xmm8, %xmm6
886; SSSE3-NEXT:    pxor %xmm8, %xmm4
887; SSSE3-NEXT:    pcmpgtd %xmm6, %xmm4
888; SSSE3-NEXT:    pand %xmm4, %xmm2
889; SSSE3-NEXT:    movdqa %xmm7, %xmm4
890; SSSE3-NEXT:    pxor %xmm8, %xmm4
891; SSSE3-NEXT:    pxor %xmm3, %xmm8
892; SSSE3-NEXT:    pcmpgtd %xmm4, %xmm8
893; SSSE3-NEXT:    psubd %xmm7, %xmm3
894; SSSE3-NEXT:    pand %xmm8, %xmm3
895; SSSE3-NEXT:    retq
896;
897; SSE41-LABEL: v16i32:
898; SSE41:       # %bb.0:
899; SSE41-NEXT:    pmaxud %xmm4, %xmm0
900; SSE41-NEXT:    psubd %xmm4, %xmm0
901; SSE41-NEXT:    pmaxud %xmm5, %xmm1
902; SSE41-NEXT:    psubd %xmm5, %xmm1
903; SSE41-NEXT:    pmaxud %xmm6, %xmm2
904; SSE41-NEXT:    psubd %xmm6, %xmm2
905; SSE41-NEXT:    pmaxud %xmm7, %xmm3
906; SSE41-NEXT:    psubd %xmm7, %xmm3
907; SSE41-NEXT:    retq
908;
909; AVX1-LABEL: v16i32:
910; AVX1:       # %bb.0:
911; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
912; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
913; AVX1-NEXT:    vpmaxud %xmm4, %xmm5, %xmm5
914; AVX1-NEXT:    vpsubd %xmm4, %xmm5, %xmm4
915; AVX1-NEXT:    vpmaxud %xmm2, %xmm0, %xmm0
916; AVX1-NEXT:    vpsubd %xmm2, %xmm0, %xmm0
917; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm0, %ymm0
918; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm2
919; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
920; AVX1-NEXT:    vpmaxud %xmm2, %xmm4, %xmm4
921; AVX1-NEXT:    vpsubd %xmm2, %xmm4, %xmm2
922; AVX1-NEXT:    vpmaxud %xmm3, %xmm1, %xmm1
923; AVX1-NEXT:    vpsubd %xmm3, %xmm1, %xmm1
924; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
925; AVX1-NEXT:    retq
926;
927; AVX2-LABEL: v16i32:
928; AVX2:       # %bb.0:
929; AVX2-NEXT:    vpmaxud %ymm2, %ymm0, %ymm0
930; AVX2-NEXT:    vpsubd %ymm2, %ymm0, %ymm0
931; AVX2-NEXT:    vpmaxud %ymm3, %ymm1, %ymm1
932; AVX2-NEXT:    vpsubd %ymm3, %ymm1, %ymm1
933; AVX2-NEXT:    retq
934;
935; AVX512-LABEL: v16i32:
936; AVX512:       # %bb.0:
937; AVX512-NEXT:    vpmaxud %zmm1, %zmm0, %zmm0
938; AVX512-NEXT:    vpsubd %zmm1, %zmm0, %zmm0
939; AVX512-NEXT:    retq
940  %z = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %x, <16 x i32> %y)
941  ret <16 x i32> %z
942}
943
944define <2 x i64> @v2i64(<2 x i64> %x, <2 x i64> %y) nounwind {
945; SSE2-LABEL: v2i64:
946; SSE2:       # %bb.0:
947; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [9223372039002259456,9223372039002259456]
948; SSE2-NEXT:    movdqa %xmm1, %xmm3
949; SSE2-NEXT:    pxor %xmm2, %xmm3
950; SSE2-NEXT:    pxor %xmm0, %xmm2
951; SSE2-NEXT:    movdqa %xmm2, %xmm4
952; SSE2-NEXT:    pcmpgtd %xmm3, %xmm4
953; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
954; SSE2-NEXT:    pcmpeqd %xmm3, %xmm2
955; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
956; SSE2-NEXT:    pand %xmm5, %xmm2
957; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[1,1,3,3]
958; SSE2-NEXT:    por %xmm2, %xmm3
959; SSE2-NEXT:    psubq %xmm1, %xmm0
960; SSE2-NEXT:    pand %xmm3, %xmm0
961; SSE2-NEXT:    retq
962;
963; SSSE3-LABEL: v2i64:
964; SSSE3:       # %bb.0:
965; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [9223372039002259456,9223372039002259456]
966; SSSE3-NEXT:    movdqa %xmm1, %xmm3
967; SSSE3-NEXT:    pxor %xmm2, %xmm3
968; SSSE3-NEXT:    pxor %xmm0, %xmm2
969; SSSE3-NEXT:    movdqa %xmm2, %xmm4
970; SSSE3-NEXT:    pcmpgtd %xmm3, %xmm4
971; SSSE3-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
972; SSSE3-NEXT:    pcmpeqd %xmm3, %xmm2
973; SSSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
974; SSSE3-NEXT:    pand %xmm5, %xmm2
975; SSSE3-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[1,1,3,3]
976; SSSE3-NEXT:    por %xmm2, %xmm3
977; SSSE3-NEXT:    psubq %xmm1, %xmm0
978; SSSE3-NEXT:    pand %xmm3, %xmm0
979; SSSE3-NEXT:    retq
980;
981; SSE41-LABEL: v2i64:
982; SSE41:       # %bb.0:
983; SSE41-NEXT:    movdqa %xmm0, %xmm2
984; SSE41-NEXT:    movdqa {{.*#+}} xmm0 = [9223372039002259456,9223372039002259456]
985; SSE41-NEXT:    movdqa %xmm1, %xmm3
986; SSE41-NEXT:    pxor %xmm0, %xmm3
987; SSE41-NEXT:    pxor %xmm2, %xmm0
988; SSE41-NEXT:    movdqa %xmm0, %xmm4
989; SSE41-NEXT:    pcmpgtd %xmm3, %xmm4
990; SSE41-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
991; SSE41-NEXT:    pcmpeqd %xmm3, %xmm0
992; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
993; SSE41-NEXT:    pand %xmm5, %xmm0
994; SSE41-NEXT:    por %xmm4, %xmm0
995; SSE41-NEXT:    psubq %xmm1, %xmm2
996; SSE41-NEXT:    pxor %xmm1, %xmm1
997; SSE41-NEXT:    blendvpd %xmm0, %xmm2, %xmm1
998; SSE41-NEXT:    movapd %xmm1, %xmm0
999; SSE41-NEXT:    retq
1000;
1001; AVX1-LABEL: v2i64:
1002; AVX1:       # %bb.0:
1003; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
1004; AVX1-NEXT:    vpxor %xmm2, %xmm1, %xmm3
1005; AVX1-NEXT:    vpxor %xmm2, %xmm0, %xmm2
1006; AVX1-NEXT:    vpcmpgtq %xmm3, %xmm2, %xmm2
1007; AVX1-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
1008; AVX1-NEXT:    vpand %xmm0, %xmm2, %xmm0
1009; AVX1-NEXT:    retq
1010;
1011; AVX2-LABEL: v2i64:
1012; AVX2:       # %bb.0:
1013; AVX2-NEXT:    vmovdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
1014; AVX2-NEXT:    vpxor %xmm2, %xmm1, %xmm3
1015; AVX2-NEXT:    vpxor %xmm2, %xmm0, %xmm2
1016; AVX2-NEXT:    vpcmpgtq %xmm3, %xmm2, %xmm2
1017; AVX2-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
1018; AVX2-NEXT:    vpand %xmm0, %xmm2, %xmm0
1019; AVX2-NEXT:    retq
1020;
1021; AVX512-LABEL: v2i64:
1022; AVX512:       # %bb.0:
1023; AVX512-NEXT:    vpmaxuq %xmm1, %xmm0, %xmm0
1024; AVX512-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
1025; AVX512-NEXT:    retq
1026  %z = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %x, <2 x i64> %y)
1027  ret <2 x i64> %z
1028}
1029
1030define <4 x i64> @v4i64(<4 x i64> %x, <4 x i64> %y) nounwind {
1031; SSE2-LABEL: v4i64:
1032; SSE2:       # %bb.0:
1033; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [9223372039002259456,9223372039002259456]
1034; SSE2-NEXT:    movdqa %xmm0, %xmm5
1035; SSE2-NEXT:    psubq %xmm2, %xmm0
1036; SSE2-NEXT:    pxor %xmm4, %xmm2
1037; SSE2-NEXT:    pxor %xmm4, %xmm5
1038; SSE2-NEXT:    movdqa %xmm5, %xmm6
1039; SSE2-NEXT:    pcmpgtd %xmm2, %xmm6
1040; SSE2-NEXT:    pshufd {{.*#+}} xmm7 = xmm6[0,0,2,2]
1041; SSE2-NEXT:    pcmpeqd %xmm2, %xmm5
1042; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm5[1,1,3,3]
1043; SSE2-NEXT:    pand %xmm7, %xmm2
1044; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm6[1,1,3,3]
1045; SSE2-NEXT:    por %xmm2, %xmm5
1046; SSE2-NEXT:    pand %xmm5, %xmm0
1047; SSE2-NEXT:    movdqa %xmm3, %xmm2
1048; SSE2-NEXT:    pxor %xmm4, %xmm2
1049; SSE2-NEXT:    pxor %xmm1, %xmm4
1050; SSE2-NEXT:    movdqa %xmm4, %xmm5
1051; SSE2-NEXT:    pcmpgtd %xmm2, %xmm5
1052; SSE2-NEXT:    pshufd {{.*#+}} xmm6 = xmm5[0,0,2,2]
1053; SSE2-NEXT:    pcmpeqd %xmm2, %xmm4
1054; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm4[1,1,3,3]
1055; SSE2-NEXT:    pand %xmm6, %xmm2
1056; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm5[1,1,3,3]
1057; SSE2-NEXT:    por %xmm2, %xmm4
1058; SSE2-NEXT:    psubq %xmm3, %xmm1
1059; SSE2-NEXT:    pand %xmm4, %xmm1
1060; SSE2-NEXT:    retq
1061;
1062; SSSE3-LABEL: v4i64:
1063; SSSE3:       # %bb.0:
1064; SSSE3-NEXT:    movdqa {{.*#+}} xmm4 = [9223372039002259456,9223372039002259456]
1065; SSSE3-NEXT:    movdqa %xmm0, %xmm5
1066; SSSE3-NEXT:    psubq %xmm2, %xmm0
1067; SSSE3-NEXT:    pxor %xmm4, %xmm2
1068; SSSE3-NEXT:    pxor %xmm4, %xmm5
1069; SSSE3-NEXT:    movdqa %xmm5, %xmm6
1070; SSSE3-NEXT:    pcmpgtd %xmm2, %xmm6
1071; SSSE3-NEXT:    pshufd {{.*#+}} xmm7 = xmm6[0,0,2,2]
1072; SSSE3-NEXT:    pcmpeqd %xmm2, %xmm5
1073; SSSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm5[1,1,3,3]
1074; SSSE3-NEXT:    pand %xmm7, %xmm2
1075; SSSE3-NEXT:    pshufd {{.*#+}} xmm5 = xmm6[1,1,3,3]
1076; SSSE3-NEXT:    por %xmm2, %xmm5
1077; SSSE3-NEXT:    pand %xmm5, %xmm0
1078; SSSE3-NEXT:    movdqa %xmm3, %xmm2
1079; SSSE3-NEXT:    pxor %xmm4, %xmm2
1080; SSSE3-NEXT:    pxor %xmm1, %xmm4
1081; SSSE3-NEXT:    movdqa %xmm4, %xmm5
1082; SSSE3-NEXT:    pcmpgtd %xmm2, %xmm5
1083; SSSE3-NEXT:    pshufd {{.*#+}} xmm6 = xmm5[0,0,2,2]
1084; SSSE3-NEXT:    pcmpeqd %xmm2, %xmm4
1085; SSSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm4[1,1,3,3]
1086; SSSE3-NEXT:    pand %xmm6, %xmm2
1087; SSSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm5[1,1,3,3]
1088; SSSE3-NEXT:    por %xmm2, %xmm4
1089; SSSE3-NEXT:    psubq %xmm3, %xmm1
1090; SSSE3-NEXT:    pand %xmm4, %xmm1
1091; SSSE3-NEXT:    retq
1092;
1093; SSE41-LABEL: v4i64:
1094; SSE41:       # %bb.0:
1095; SSE41-NEXT:    movdqa %xmm0, %xmm4
1096; SSE41-NEXT:    movdqa {{.*#+}} xmm6 = [9223372039002259456,9223372039002259456]
1097; SSE41-NEXT:    movdqa %xmm0, %xmm5
1098; SSE41-NEXT:    psubq %xmm2, %xmm4
1099; SSE41-NEXT:    pxor %xmm6, %xmm2
1100; SSE41-NEXT:    pxor %xmm6, %xmm5
1101; SSE41-NEXT:    movdqa %xmm5, %xmm0
1102; SSE41-NEXT:    pcmpgtd %xmm2, %xmm0
1103; SSE41-NEXT:    pshufd {{.*#+}} xmm7 = xmm0[0,0,2,2]
1104; SSE41-NEXT:    pcmpeqd %xmm2, %xmm5
1105; SSE41-NEXT:    pshufd {{.*#+}} xmm2 = xmm5[1,1,3,3]
1106; SSE41-NEXT:    pand %xmm7, %xmm2
1107; SSE41-NEXT:    por %xmm2, %xmm0
1108; SSE41-NEXT:    pxor %xmm2, %xmm2
1109; SSE41-NEXT:    pxor %xmm5, %xmm5
1110; SSE41-NEXT:    blendvpd %xmm0, %xmm4, %xmm5
1111; SSE41-NEXT:    movdqa %xmm3, %xmm0
1112; SSE41-NEXT:    pxor %xmm6, %xmm0
1113; SSE41-NEXT:    pxor %xmm1, %xmm6
1114; SSE41-NEXT:    movdqa %xmm6, %xmm4
1115; SSE41-NEXT:    pcmpgtd %xmm0, %xmm4
1116; SSE41-NEXT:    pshufd {{.*#+}} xmm7 = xmm4[0,0,2,2]
1117; SSE41-NEXT:    pcmpeqd %xmm0, %xmm6
1118; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm6[1,1,3,3]
1119; SSE41-NEXT:    pand %xmm7, %xmm0
1120; SSE41-NEXT:    por %xmm4, %xmm0
1121; SSE41-NEXT:    psubq %xmm3, %xmm1
1122; SSE41-NEXT:    blendvpd %xmm0, %xmm1, %xmm2
1123; SSE41-NEXT:    movapd %xmm5, %xmm0
1124; SSE41-NEXT:    movapd %xmm2, %xmm1
1125; SSE41-NEXT:    retq
1126;
1127; AVX1-LABEL: v4i64:
1128; AVX1:       # %bb.0:
1129; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1130; AVX1-NEXT:    vmovdqa {{.*#+}} xmm3 = [9223372036854775808,9223372036854775808]
1131; AVX1-NEXT:    vpxor %xmm3, %xmm2, %xmm4
1132; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
1133; AVX1-NEXT:    vpxor %xmm3, %xmm5, %xmm5
1134; AVX1-NEXT:    vpcmpgtq %xmm4, %xmm5, %xmm4
1135; AVX1-NEXT:    vpxor %xmm3, %xmm1, %xmm5
1136; AVX1-NEXT:    vpxor %xmm3, %xmm0, %xmm3
1137; AVX1-NEXT:    vpcmpgtq %xmm5, %xmm3, %xmm3
1138; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm3, %ymm3
1139; AVX1-NEXT:    vblendvpd %ymm3, %ymm0, %ymm1, %ymm0
1140; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
1141; AVX1-NEXT:    vpsubq %xmm2, %xmm3, %xmm2
1142; AVX1-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
1143; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
1144; AVX1-NEXT:    retq
1145;
1146; AVX2-LABEL: v4i64:
1147; AVX2:       # %bb.0:
1148; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm2 = [9223372036854775808,9223372036854775808,9223372036854775808,9223372036854775808]
1149; AVX2-NEXT:    vpxor %ymm2, %ymm1, %ymm3
1150; AVX2-NEXT:    vpxor %ymm2, %ymm0, %ymm2
1151; AVX2-NEXT:    vpcmpgtq %ymm3, %ymm2, %ymm2
1152; AVX2-NEXT:    vblendvpd %ymm2, %ymm0, %ymm1, %ymm0
1153; AVX2-NEXT:    vpsubq %ymm1, %ymm0, %ymm0
1154; AVX2-NEXT:    retq
1155;
1156; AVX512-LABEL: v4i64:
1157; AVX512:       # %bb.0:
1158; AVX512-NEXT:    vpmaxuq %ymm1, %ymm0, %ymm0
1159; AVX512-NEXT:    vpsubq %ymm1, %ymm0, %ymm0
1160; AVX512-NEXT:    retq
1161  %z = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %x, <4 x i64> %y)
1162  ret <4 x i64> %z
1163}
1164
1165define <8 x i64> @v8i64(<8 x i64> %x, <8 x i64> %y) nounwind {
1166; SSE2-LABEL: v8i64:
1167; SSE2:       # %bb.0:
1168; SSE2-NEXT:    movdqa {{.*#+}} xmm8 = [9223372039002259456,9223372039002259456]
1169; SSE2-NEXT:    movdqa %xmm0, %xmm9
1170; SSE2-NEXT:    psubq %xmm4, %xmm0
1171; SSE2-NEXT:    pxor %xmm8, %xmm4
1172; SSE2-NEXT:    pxor %xmm8, %xmm9
1173; SSE2-NEXT:    movdqa %xmm9, %xmm10
1174; SSE2-NEXT:    pcmpgtd %xmm4, %xmm10
1175; SSE2-NEXT:    pshufd {{.*#+}} xmm11 = xmm10[0,0,2,2]
1176; SSE2-NEXT:    pcmpeqd %xmm4, %xmm9
1177; SSE2-NEXT:    pshufd {{.*#+}} xmm9 = xmm9[1,1,3,3]
1178; SSE2-NEXT:    pand %xmm11, %xmm9
1179; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm10[1,1,3,3]
1180; SSE2-NEXT:    por %xmm9, %xmm4
1181; SSE2-NEXT:    pand %xmm4, %xmm0
1182; SSE2-NEXT:    movdqa %xmm1, %xmm9
1183; SSE2-NEXT:    psubq %xmm5, %xmm1
1184; SSE2-NEXT:    pxor %xmm8, %xmm5
1185; SSE2-NEXT:    pxor %xmm8, %xmm9
1186; SSE2-NEXT:    movdqa %xmm9, %xmm4
1187; SSE2-NEXT:    pcmpgtd %xmm5, %xmm4
1188; SSE2-NEXT:    pshufd {{.*#+}} xmm10 = xmm4[0,0,2,2]
1189; SSE2-NEXT:    pcmpeqd %xmm5, %xmm9
1190; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm9[1,1,3,3]
1191; SSE2-NEXT:    pand %xmm10, %xmm5
1192; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
1193; SSE2-NEXT:    por %xmm5, %xmm4
1194; SSE2-NEXT:    pand %xmm4, %xmm1
1195; SSE2-NEXT:    movdqa %xmm2, %xmm4
1196; SSE2-NEXT:    psubq %xmm6, %xmm2
1197; SSE2-NEXT:    pxor %xmm8, %xmm6
1198; SSE2-NEXT:    pxor %xmm8, %xmm4
1199; SSE2-NEXT:    movdqa %xmm4, %xmm5
1200; SSE2-NEXT:    pcmpgtd %xmm6, %xmm5
1201; SSE2-NEXT:    pshufd {{.*#+}} xmm9 = xmm5[0,0,2,2]
1202; SSE2-NEXT:    pcmpeqd %xmm6, %xmm4
1203; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
1204; SSE2-NEXT:    pand %xmm9, %xmm4
1205; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3]
1206; SSE2-NEXT:    por %xmm4, %xmm5
1207; SSE2-NEXT:    pand %xmm5, %xmm2
1208; SSE2-NEXT:    movdqa %xmm7, %xmm4
1209; SSE2-NEXT:    pxor %xmm8, %xmm4
1210; SSE2-NEXT:    pxor %xmm3, %xmm8
1211; SSE2-NEXT:    movdqa %xmm8, %xmm5
1212; SSE2-NEXT:    pcmpgtd %xmm4, %xmm5
1213; SSE2-NEXT:    pshufd {{.*#+}} xmm6 = xmm5[0,0,2,2]
1214; SSE2-NEXT:    pcmpeqd %xmm4, %xmm8
1215; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm8[1,1,3,3]
1216; SSE2-NEXT:    pand %xmm6, %xmm4
1217; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3]
1218; SSE2-NEXT:    por %xmm4, %xmm5
1219; SSE2-NEXT:    psubq %xmm7, %xmm3
1220; SSE2-NEXT:    pand %xmm5, %xmm3
1221; SSE2-NEXT:    retq
1222;
1223; SSSE3-LABEL: v8i64:
1224; SSSE3:       # %bb.0:
1225; SSSE3-NEXT:    movdqa {{.*#+}} xmm8 = [9223372039002259456,9223372039002259456]
1226; SSSE3-NEXT:    movdqa %xmm0, %xmm9
1227; SSSE3-NEXT:    psubq %xmm4, %xmm0
1228; SSSE3-NEXT:    pxor %xmm8, %xmm4
1229; SSSE3-NEXT:    pxor %xmm8, %xmm9
1230; SSSE3-NEXT:    movdqa %xmm9, %xmm10
1231; SSSE3-NEXT:    pcmpgtd %xmm4, %xmm10
1232; SSSE3-NEXT:    pshufd {{.*#+}} xmm11 = xmm10[0,0,2,2]
1233; SSSE3-NEXT:    pcmpeqd %xmm4, %xmm9
1234; SSSE3-NEXT:    pshufd {{.*#+}} xmm9 = xmm9[1,1,3,3]
1235; SSSE3-NEXT:    pand %xmm11, %xmm9
1236; SSSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm10[1,1,3,3]
1237; SSSE3-NEXT:    por %xmm9, %xmm4
1238; SSSE3-NEXT:    pand %xmm4, %xmm0
1239; SSSE3-NEXT:    movdqa %xmm1, %xmm9
1240; SSSE3-NEXT:    psubq %xmm5, %xmm1
1241; SSSE3-NEXT:    pxor %xmm8, %xmm5
1242; SSSE3-NEXT:    pxor %xmm8, %xmm9
1243; SSSE3-NEXT:    movdqa %xmm9, %xmm4
1244; SSSE3-NEXT:    pcmpgtd %xmm5, %xmm4
1245; SSSE3-NEXT:    pshufd {{.*#+}} xmm10 = xmm4[0,0,2,2]
1246; SSSE3-NEXT:    pcmpeqd %xmm5, %xmm9
1247; SSSE3-NEXT:    pshufd {{.*#+}} xmm5 = xmm9[1,1,3,3]
1248; SSSE3-NEXT:    pand %xmm10, %xmm5
1249; SSSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
1250; SSSE3-NEXT:    por %xmm5, %xmm4
1251; SSSE3-NEXT:    pand %xmm4, %xmm1
1252; SSSE3-NEXT:    movdqa %xmm2, %xmm4
1253; SSSE3-NEXT:    psubq %xmm6, %xmm2
1254; SSSE3-NEXT:    pxor %xmm8, %xmm6
1255; SSSE3-NEXT:    pxor %xmm8, %xmm4
1256; SSSE3-NEXT:    movdqa %xmm4, %xmm5
1257; SSSE3-NEXT:    pcmpgtd %xmm6, %xmm5
1258; SSSE3-NEXT:    pshufd {{.*#+}} xmm9 = xmm5[0,0,2,2]
1259; SSSE3-NEXT:    pcmpeqd %xmm6, %xmm4
1260; SSSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
1261; SSSE3-NEXT:    pand %xmm9, %xmm4
1262; SSSE3-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3]
1263; SSSE3-NEXT:    por %xmm4, %xmm5
1264; SSSE3-NEXT:    pand %xmm5, %xmm2
1265; SSSE3-NEXT:    movdqa %xmm7, %xmm4
1266; SSSE3-NEXT:    pxor %xmm8, %xmm4
1267; SSSE3-NEXT:    pxor %xmm3, %xmm8
1268; SSSE3-NEXT:    movdqa %xmm8, %xmm5
1269; SSSE3-NEXT:    pcmpgtd %xmm4, %xmm5
1270; SSSE3-NEXT:    pshufd {{.*#+}} xmm6 = xmm5[0,0,2,2]
1271; SSSE3-NEXT:    pcmpeqd %xmm4, %xmm8
1272; SSSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm8[1,1,3,3]
1273; SSSE3-NEXT:    pand %xmm6, %xmm4
1274; SSSE3-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3]
1275; SSSE3-NEXT:    por %xmm4, %xmm5
1276; SSSE3-NEXT:    psubq %xmm7, %xmm3
1277; SSSE3-NEXT:    pand %xmm5, %xmm3
1278; SSSE3-NEXT:    retq
1279;
1280; SSE41-LABEL: v8i64:
1281; SSE41:       # %bb.0:
1282; SSE41-NEXT:    movdqa %xmm0, %xmm9
1283; SSE41-NEXT:    movdqa {{.*#+}} xmm10 = [9223372039002259456,9223372039002259456]
1284; SSE41-NEXT:    movdqa %xmm0, %xmm8
1285; SSE41-NEXT:    psubq %xmm4, %xmm9
1286; SSE41-NEXT:    pxor %xmm10, %xmm4
1287; SSE41-NEXT:    pxor %xmm10, %xmm8
1288; SSE41-NEXT:    movdqa %xmm8, %xmm0
1289; SSE41-NEXT:    pcmpgtd %xmm4, %xmm0
1290; SSE41-NEXT:    pshufd {{.*#+}} xmm11 = xmm0[0,0,2,2]
1291; SSE41-NEXT:    pcmpeqd %xmm4, %xmm8
1292; SSE41-NEXT:    pshufd {{.*#+}} xmm4 = xmm8[1,1,3,3]
1293; SSE41-NEXT:    pand %xmm11, %xmm4
1294; SSE41-NEXT:    por %xmm4, %xmm0
1295; SSE41-NEXT:    pxor %xmm8, %xmm8
1296; SSE41-NEXT:    pxor %xmm11, %xmm11
1297; SSE41-NEXT:    blendvpd %xmm0, %xmm9, %xmm11
1298; SSE41-NEXT:    movdqa %xmm1, %xmm0
1299; SSE41-NEXT:    psubq %xmm5, %xmm1
1300; SSE41-NEXT:    pxor %xmm10, %xmm5
1301; SSE41-NEXT:    pxor %xmm10, %xmm0
1302; SSE41-NEXT:    movdqa %xmm0, %xmm4
1303; SSE41-NEXT:    pcmpgtd %xmm5, %xmm4
1304; SSE41-NEXT:    pshufd {{.*#+}} xmm9 = xmm4[0,0,2,2]
1305; SSE41-NEXT:    pcmpeqd %xmm5, %xmm0
1306; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
1307; SSE41-NEXT:    pand %xmm9, %xmm0
1308; SSE41-NEXT:    por %xmm4, %xmm0
1309; SSE41-NEXT:    pxor %xmm5, %xmm5
1310; SSE41-NEXT:    blendvpd %xmm0, %xmm1, %xmm5
1311; SSE41-NEXT:    movdqa %xmm2, %xmm0
1312; SSE41-NEXT:    psubq %xmm6, %xmm2
1313; SSE41-NEXT:    pxor %xmm10, %xmm6
1314; SSE41-NEXT:    pxor %xmm10, %xmm0
1315; SSE41-NEXT:    movdqa %xmm0, %xmm1
1316; SSE41-NEXT:    pcmpgtd %xmm6, %xmm1
1317; SSE41-NEXT:    pshufd {{.*#+}} xmm4 = xmm1[0,0,2,2]
1318; SSE41-NEXT:    pcmpeqd %xmm6, %xmm0
1319; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
1320; SSE41-NEXT:    pand %xmm4, %xmm0
1321; SSE41-NEXT:    por %xmm1, %xmm0
1322; SSE41-NEXT:    pxor %xmm6, %xmm6
1323; SSE41-NEXT:    blendvpd %xmm0, %xmm2, %xmm6
1324; SSE41-NEXT:    movdqa %xmm7, %xmm0
1325; SSE41-NEXT:    pxor %xmm10, %xmm0
1326; SSE41-NEXT:    pxor %xmm3, %xmm10
1327; SSE41-NEXT:    movdqa %xmm10, %xmm1
1328; SSE41-NEXT:    pcmpgtd %xmm0, %xmm1
1329; SSE41-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[0,0,2,2]
1330; SSE41-NEXT:    pcmpeqd %xmm0, %xmm10
1331; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm10[1,1,3,3]
1332; SSE41-NEXT:    pand %xmm2, %xmm0
1333; SSE41-NEXT:    por %xmm1, %xmm0
1334; SSE41-NEXT:    psubq %xmm7, %xmm3
1335; SSE41-NEXT:    blendvpd %xmm0, %xmm3, %xmm8
1336; SSE41-NEXT:    movapd %xmm11, %xmm0
1337; SSE41-NEXT:    movapd %xmm5, %xmm1
1338; SSE41-NEXT:    movapd %xmm6, %xmm2
1339; SSE41-NEXT:    movapd %xmm8, %xmm3
1340; SSE41-NEXT:    retq
1341;
1342; AVX1-LABEL: v8i64:
1343; AVX1:       # %bb.0:
1344; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
1345; AVX1-NEXT:    vmovdqa {{.*#+}} xmm5 = [9223372036854775808,9223372036854775808]
1346; AVX1-NEXT:    vpxor %xmm5, %xmm4, %xmm6
1347; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm7
1348; AVX1-NEXT:    vpxor %xmm5, %xmm7, %xmm7
1349; AVX1-NEXT:    vpcmpgtq %xmm6, %xmm7, %xmm8
1350; AVX1-NEXT:    vpxor %xmm5, %xmm2, %xmm7
1351; AVX1-NEXT:    vpxor %xmm5, %xmm0, %xmm6
1352; AVX1-NEXT:    vpcmpgtq %xmm7, %xmm6, %xmm6
1353; AVX1-NEXT:    vinsertf128 $1, %xmm8, %ymm6, %ymm6
1354; AVX1-NEXT:    vblendvpd %ymm6, %ymm0, %ymm2, %ymm0
1355; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm6
1356; AVX1-NEXT:    vpsubq %xmm4, %xmm6, %xmm4
1357; AVX1-NEXT:    vpsubq %xmm2, %xmm0, %xmm0
1358; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm0, %ymm0
1359; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm2
1360; AVX1-NEXT:    vpxor %xmm5, %xmm2, %xmm4
1361; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm6
1362; AVX1-NEXT:    vpxor %xmm5, %xmm6, %xmm6
1363; AVX1-NEXT:    vpcmpgtq %xmm4, %xmm6, %xmm4
1364; AVX1-NEXT:    vpxor %xmm5, %xmm3, %xmm6
1365; AVX1-NEXT:    vpxor %xmm5, %xmm1, %xmm5
1366; AVX1-NEXT:    vpcmpgtq %xmm6, %xmm5, %xmm5
1367; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm5, %ymm4
1368; AVX1-NEXT:    vblendvpd %ymm4, %ymm1, %ymm3, %ymm1
1369; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
1370; AVX1-NEXT:    vpsubq %xmm2, %xmm4, %xmm2
1371; AVX1-NEXT:    vpsubq %xmm3, %xmm1, %xmm1
1372; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
1373; AVX1-NEXT:    retq
1374;
1375; AVX2-LABEL: v8i64:
1376; AVX2:       # %bb.0:
1377; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [9223372036854775808,9223372036854775808,9223372036854775808,9223372036854775808]
1378; AVX2-NEXT:    vpxor %ymm4, %ymm2, %ymm5
1379; AVX2-NEXT:    vpxor %ymm4, %ymm0, %ymm6
1380; AVX2-NEXT:    vpcmpgtq %ymm5, %ymm6, %ymm5
1381; AVX2-NEXT:    vblendvpd %ymm5, %ymm0, %ymm2, %ymm0
1382; AVX2-NEXT:    vpsubq %ymm2, %ymm0, %ymm0
1383; AVX2-NEXT:    vpxor %ymm4, %ymm3, %ymm2
1384; AVX2-NEXT:    vpxor %ymm4, %ymm1, %ymm4
1385; AVX2-NEXT:    vpcmpgtq %ymm2, %ymm4, %ymm2
1386; AVX2-NEXT:    vblendvpd %ymm2, %ymm1, %ymm3, %ymm1
1387; AVX2-NEXT:    vpsubq %ymm3, %ymm1, %ymm1
1388; AVX2-NEXT:    retq
1389;
1390; AVX512-LABEL: v8i64:
1391; AVX512:       # %bb.0:
1392; AVX512-NEXT:    vpmaxuq %zmm1, %zmm0, %zmm0
1393; AVX512-NEXT:    vpsubq %zmm1, %zmm0, %zmm0
1394; AVX512-NEXT:    retq
1395  %z = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %x, <8 x i64> %y)
1396  ret <8 x i64> %z
1397}
1398
1399define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind {
1400; SSE-LABEL: v2i128:
1401; SSE:       # %bb.0:
1402; SSE-NEXT:    movq %rdi, %rax
1403; SSE-NEXT:    xorl %edi, %edi
1404; SSE-NEXT:    subq %r9, %rsi
1405; SSE-NEXT:    sbbq {{[0-9]+}}(%rsp), %rdx
1406; SSE-NEXT:    cmovbq %rdi, %rsi
1407; SSE-NEXT:    cmovbq %rdi, %rdx
1408; SSE-NEXT:    subq {{[0-9]+}}(%rsp), %rcx
1409; SSE-NEXT:    sbbq {{[0-9]+}}(%rsp), %r8
1410; SSE-NEXT:    cmovbq %rdi, %r8
1411; SSE-NEXT:    cmovbq %rdi, %rcx
1412; SSE-NEXT:    movq %r8, 24(%rax)
1413; SSE-NEXT:    movq %rcx, 16(%rax)
1414; SSE-NEXT:    movq %rdx, 8(%rax)
1415; SSE-NEXT:    movq %rsi, (%rax)
1416; SSE-NEXT:    retq
1417;
1418; AVX-LABEL: v2i128:
1419; AVX:       # %bb.0:
1420; AVX-NEXT:    movq %rdi, %rax
1421; AVX-NEXT:    xorl %edi, %edi
1422; AVX-NEXT:    subq %r9, %rsi
1423; AVX-NEXT:    sbbq {{[0-9]+}}(%rsp), %rdx
1424; AVX-NEXT:    cmovbq %rdi, %rsi
1425; AVX-NEXT:    cmovbq %rdi, %rdx
1426; AVX-NEXT:    subq {{[0-9]+}}(%rsp), %rcx
1427; AVX-NEXT:    sbbq {{[0-9]+}}(%rsp), %r8
1428; AVX-NEXT:    cmovbq %rdi, %r8
1429; AVX-NEXT:    cmovbq %rdi, %rcx
1430; AVX-NEXT:    movq %r8, 24(%rax)
1431; AVX-NEXT:    movq %rcx, 16(%rax)
1432; AVX-NEXT:    movq %rdx, 8(%rax)
1433; AVX-NEXT:    movq %rsi, (%rax)
1434; AVX-NEXT:    retq
1435  %z = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %x, <2 x i128> %y)
1436  ret <2 x i128> %z
1437}
1438