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=+avx512f,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX,AVX512,AVX512F
8; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+avx512vl,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX,AVX512,AVX512BW
9
10declare <1 x i8> @llvm.usub.sat.v1i8(<1 x i8>, <1 x i8>)
11declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>)
12declare <4 x i8> @llvm.usub.sat.v4i8(<4 x i8>, <4 x i8>)
13declare <8 x i8> @llvm.usub.sat.v8i8(<8 x i8>, <8 x i8>)
14declare <12 x i8> @llvm.usub.sat.v12i8(<12 x i8>, <12 x i8>)
15declare <16 x i8> @llvm.usub.sat.v16i8(<16 x i8>, <16 x i8>)
16declare <32 x i8> @llvm.usub.sat.v32i8(<32 x i8>, <32 x i8>)
17declare <64 x i8> @llvm.usub.sat.v64i8(<64 x i8>, <64 x i8>)
18
19declare <1 x i16> @llvm.usub.sat.v1i16(<1 x i16>, <1 x i16>)
20declare <2 x i16> @llvm.usub.sat.v2i16(<2 x i16>, <2 x i16>)
21declare <4 x i16> @llvm.usub.sat.v4i16(<4 x i16>, <4 x i16>)
22declare <8 x i16> @llvm.usub.sat.v8i16(<8 x i16>, <8 x i16>)
23declare <12 x i16> @llvm.usub.sat.v12i16(<12 x i16>, <12 x i16>)
24declare <16 x i16> @llvm.usub.sat.v16i16(<16 x i16>, <16 x i16>)
25declare <32 x i16> @llvm.usub.sat.v32i16(<32 x i16>, <32 x i16>)
26
27declare <16 x i1> @llvm.usub.sat.v16i1(<16 x i1>, <16 x i1>)
28declare <16 x i4> @llvm.usub.sat.v16i4(<16 x i4>, <16 x i4>)
29
30declare <2 x i32> @llvm.usub.sat.v2i32(<2 x i32>, <2 x i32>)
31declare <4 x i32> @llvm.usub.sat.v4i32(<4 x i32>, <4 x i32>)
32declare <8 x i32> @llvm.usub.sat.v8i32(<8 x i32>, <8 x i32>)
33declare <16 x i32> @llvm.usub.sat.v16i32(<16 x i32>, <16 x i32>)
34declare <2 x i64> @llvm.usub.sat.v2i64(<2 x i64>, <2 x i64>)
35declare <4 x i64> @llvm.usub.sat.v4i64(<4 x i64>, <4 x i64>)
36declare <8 x i64> @llvm.usub.sat.v8i64(<8 x i64>, <8 x i64>)
37
38declare <4 x i24> @llvm.usub.sat.v4i24(<4 x i24>, <4 x i24>)
39declare <2 x i128> @llvm.usub.sat.v2i128(<2 x i128>, <2 x i128>)
40
41; Legal types, depending on architecture.
42
43define <16 x i8> @v16i8(<16 x i8> %x, <16 x i8> %y) nounwind {
44; SSE-LABEL: v16i8:
45; SSE:       # %bb.0:
46; SSE-NEXT:    psubusb %xmm1, %xmm0
47; SSE-NEXT:    retq
48;
49; AVX-LABEL: v16i8:
50; AVX:       # %bb.0:
51; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
52; AVX-NEXT:    retq
53  %z = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %x, <16 x i8> %y)
54  ret <16 x i8> %z
55}
56
57define <32 x i8> @v32i8(<32 x i8> %x, <32 x i8> %y) nounwind {
58; SSE-LABEL: v32i8:
59; SSE:       # %bb.0:
60; SSE-NEXT:    psubusb %xmm2, %xmm0
61; SSE-NEXT:    psubusb %xmm3, %xmm1
62; SSE-NEXT:    retq
63;
64; AVX1-LABEL: v32i8:
65; AVX1:       # %bb.0:
66; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
67; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
68; AVX1-NEXT:    vpsubusb %xmm2, %xmm3, %xmm2
69; AVX1-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
70; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
71; AVX1-NEXT:    retq
72;
73; AVX2-LABEL: v32i8:
74; AVX2:       # %bb.0:
75; AVX2-NEXT:    vpsubusb %ymm1, %ymm0, %ymm0
76; AVX2-NEXT:    retq
77;
78; AVX512-LABEL: v32i8:
79; AVX512:       # %bb.0:
80; AVX512-NEXT:    vpsubusb %ymm1, %ymm0, %ymm0
81; AVX512-NEXT:    retq
82  %z = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %x, <32 x i8> %y)
83  ret <32 x i8> %z
84}
85
86define <64 x i8> @v64i8(<64 x i8> %x, <64 x i8> %y) nounwind {
87; SSE-LABEL: v64i8:
88; SSE:       # %bb.0:
89; SSE-NEXT:    psubusb %xmm4, %xmm0
90; SSE-NEXT:    psubusb %xmm5, %xmm1
91; SSE-NEXT:    psubusb %xmm6, %xmm2
92; SSE-NEXT:    psubusb %xmm7, %xmm3
93; SSE-NEXT:    retq
94;
95; AVX1-LABEL: v64i8:
96; AVX1:       # %bb.0:
97; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
98; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
99; AVX1-NEXT:    vpsubusb %xmm4, %xmm5, %xmm4
100; AVX1-NEXT:    vpsubusb %xmm2, %xmm0, %xmm0
101; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm0, %ymm0
102; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm2
103; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
104; AVX1-NEXT:    vpsubusb %xmm2, %xmm4, %xmm2
105; AVX1-NEXT:    vpsubusb %xmm3, %xmm1, %xmm1
106; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
107; AVX1-NEXT:    retq
108;
109; AVX2-LABEL: v64i8:
110; AVX2:       # %bb.0:
111; AVX2-NEXT:    vpsubusb %ymm2, %ymm0, %ymm0
112; AVX2-NEXT:    vpsubusb %ymm3, %ymm1, %ymm1
113; AVX2-NEXT:    retq
114;
115; AVX512F-LABEL: v64i8:
116; AVX512F:       # %bb.0:
117; AVX512F-NEXT:    vextracti64x4 $1, %zmm1, %ymm2
118; AVX512F-NEXT:    vextracti64x4 $1, %zmm0, %ymm3
119; AVX512F-NEXT:    vpsubusb %ymm2, %ymm3, %ymm2
120; AVX512F-NEXT:    vpsubusb %ymm1, %ymm0, %ymm0
121; AVX512F-NEXT:    vinserti64x4 $1, %ymm2, %zmm0, %zmm0
122; AVX512F-NEXT:    retq
123;
124; AVX512BW-LABEL: v64i8:
125; AVX512BW:       # %bb.0:
126; AVX512BW-NEXT:    vpsubusb %zmm1, %zmm0, %zmm0
127; AVX512BW-NEXT:    retq
128  %z = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %x, <64 x i8> %y)
129  ret <64 x i8> %z
130}
131
132define <8 x i16> @v8i16(<8 x i16> %x, <8 x i16> %y) nounwind {
133; SSE-LABEL: v8i16:
134; SSE:       # %bb.0:
135; SSE-NEXT:    psubusw %xmm1, %xmm0
136; SSE-NEXT:    retq
137;
138; AVX-LABEL: v8i16:
139; AVX:       # %bb.0:
140; AVX-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
141; AVX-NEXT:    retq
142  %z = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %x, <8 x i16> %y)
143  ret <8 x i16> %z
144}
145
146define <16 x i16> @v16i16(<16 x i16> %x, <16 x i16> %y) nounwind {
147; SSE-LABEL: v16i16:
148; SSE:       # %bb.0:
149; SSE-NEXT:    psubusw %xmm2, %xmm0
150; SSE-NEXT:    psubusw %xmm3, %xmm1
151; SSE-NEXT:    retq
152;
153; AVX1-LABEL: v16i16:
154; AVX1:       # %bb.0:
155; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
156; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
157; AVX1-NEXT:    vpsubusw %xmm2, %xmm3, %xmm2
158; AVX1-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
159; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
160; AVX1-NEXT:    retq
161;
162; AVX2-LABEL: v16i16:
163; AVX2:       # %bb.0:
164; AVX2-NEXT:    vpsubusw %ymm1, %ymm0, %ymm0
165; AVX2-NEXT:    retq
166;
167; AVX512-LABEL: v16i16:
168; AVX512:       # %bb.0:
169; AVX512-NEXT:    vpsubusw %ymm1, %ymm0, %ymm0
170; AVX512-NEXT:    retq
171  %z = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %x, <16 x i16> %y)
172  ret <16 x i16> %z
173}
174
175define <32 x i16> @v32i16(<32 x i16> %x, <32 x i16> %y) nounwind {
176; SSE-LABEL: v32i16:
177; SSE:       # %bb.0:
178; SSE-NEXT:    psubusw %xmm4, %xmm0
179; SSE-NEXT:    psubusw %xmm5, %xmm1
180; SSE-NEXT:    psubusw %xmm6, %xmm2
181; SSE-NEXT:    psubusw %xmm7, %xmm3
182; SSE-NEXT:    retq
183;
184; AVX1-LABEL: v32i16:
185; AVX1:       # %bb.0:
186; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
187; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
188; AVX1-NEXT:    vpsubusw %xmm4, %xmm5, %xmm4
189; AVX1-NEXT:    vpsubusw %xmm2, %xmm0, %xmm0
190; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm0, %ymm0
191; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm2
192; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
193; AVX1-NEXT:    vpsubusw %xmm2, %xmm4, %xmm2
194; AVX1-NEXT:    vpsubusw %xmm3, %xmm1, %xmm1
195; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
196; AVX1-NEXT:    retq
197;
198; AVX2-LABEL: v32i16:
199; AVX2:       # %bb.0:
200; AVX2-NEXT:    vpsubusw %ymm2, %ymm0, %ymm0
201; AVX2-NEXT:    vpsubusw %ymm3, %ymm1, %ymm1
202; AVX2-NEXT:    retq
203;
204; AVX512F-LABEL: v32i16:
205; AVX512F:       # %bb.0:
206; AVX512F-NEXT:    vextracti64x4 $1, %zmm1, %ymm2
207; AVX512F-NEXT:    vextracti64x4 $1, %zmm0, %ymm3
208; AVX512F-NEXT:    vpsubusw %ymm2, %ymm3, %ymm2
209; AVX512F-NEXT:    vpsubusw %ymm1, %ymm0, %ymm0
210; AVX512F-NEXT:    vinserti64x4 $1, %ymm2, %zmm0, %zmm0
211; AVX512F-NEXT:    retq
212;
213; AVX512BW-LABEL: v32i16:
214; AVX512BW:       # %bb.0:
215; AVX512BW-NEXT:    vpsubusw %zmm1, %zmm0, %zmm0
216; AVX512BW-NEXT:    retq
217  %z = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %x, <32 x i16> %y)
218  ret <32 x i16> %z
219}
220
221; Too narrow vectors, legalized by widening.
222
223define void @v8i8(<8 x i8>* %px, <8 x i8>* %py, <8 x i8>* %pz) nounwind {
224; SSE-LABEL: v8i8:
225; SSE:       # %bb.0:
226; SSE-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero
227; SSE-NEXT:    movq {{.*#+}} xmm1 = mem[0],zero
228; SSE-NEXT:    psubusb %xmm1, %xmm0
229; SSE-NEXT:    movq %xmm0, (%rdx)
230; SSE-NEXT:    retq
231;
232; AVX-LABEL: v8i8:
233; AVX:       # %bb.0:
234; AVX-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
235; AVX-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
236; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
237; AVX-NEXT:    vmovq %xmm0, (%rdx)
238; AVX-NEXT:    retq
239  %x = load <8 x i8>, <8 x i8>* %px
240  %y = load <8 x i8>, <8 x i8>* %py
241  %z = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %x, <8 x i8> %y)
242  store <8 x i8> %z, <8 x i8>* %pz
243  ret void
244}
245
246define void @v4i8(<4 x i8>* %px, <4 x i8>* %py, <4 x i8>* %pz) nounwind {
247; SSE-LABEL: v4i8:
248; SSE:       # %bb.0:
249; SSE-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
250; SSE-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
251; SSE-NEXT:    psubusb %xmm1, %xmm0
252; SSE-NEXT:    movd %xmm0, (%rdx)
253; SSE-NEXT:    retq
254;
255; AVX-LABEL: v4i8:
256; AVX:       # %bb.0:
257; AVX-NEXT:    vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
258; AVX-NEXT:    vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero
259; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
260; AVX-NEXT:    vmovd %xmm0, (%rdx)
261; AVX-NEXT:    retq
262  %x = load <4 x i8>, <4 x i8>* %px
263  %y = load <4 x i8>, <4 x i8>* %py
264  %z = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %x, <4 x i8> %y)
265  store <4 x i8> %z, <4 x i8>* %pz
266  ret void
267}
268
269define void @v2i8(<2 x i8>* %px, <2 x i8>* %py, <2 x i8>* %pz) nounwind {
270; SSE2-LABEL: v2i8:
271; SSE2:       # %bb.0:
272; SSE2-NEXT:    movzwl (%rdi), %eax
273; SSE2-NEXT:    movd %eax, %xmm0
274; SSE2-NEXT:    movzwl (%rsi), %eax
275; SSE2-NEXT:    movd %eax, %xmm1
276; SSE2-NEXT:    psubusb %xmm1, %xmm0
277; SSE2-NEXT:    movd %xmm0, %eax
278; SSE2-NEXT:    movw %ax, (%rdx)
279; SSE2-NEXT:    retq
280;
281; SSSE3-LABEL: v2i8:
282; SSSE3:       # %bb.0:
283; SSSE3-NEXT:    movzwl (%rdi), %eax
284; SSSE3-NEXT:    movd %eax, %xmm0
285; SSSE3-NEXT:    movzwl (%rsi), %eax
286; SSSE3-NEXT:    movd %eax, %xmm1
287; SSSE3-NEXT:    psubusb %xmm1, %xmm0
288; SSSE3-NEXT:    movd %xmm0, %eax
289; SSSE3-NEXT:    movw %ax, (%rdx)
290; SSSE3-NEXT:    retq
291;
292; SSE41-LABEL: v2i8:
293; SSE41:       # %bb.0:
294; SSE41-NEXT:    movzwl (%rdi), %eax
295; SSE41-NEXT:    movd %eax, %xmm0
296; SSE41-NEXT:    movzwl (%rsi), %eax
297; SSE41-NEXT:    movd %eax, %xmm1
298; SSE41-NEXT:    psubusb %xmm1, %xmm0
299; SSE41-NEXT:    pextrw $0, %xmm0, (%rdx)
300; SSE41-NEXT:    retq
301;
302; AVX-LABEL: v2i8:
303; AVX:       # %bb.0:
304; AVX-NEXT:    movzwl (%rdi), %eax
305; AVX-NEXT:    vmovd %eax, %xmm0
306; AVX-NEXT:    movzwl (%rsi), %eax
307; AVX-NEXT:    vmovd %eax, %xmm1
308; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
309; AVX-NEXT:    vpextrw $0, %xmm0, (%rdx)
310; AVX-NEXT:    retq
311  %x = load <2 x i8>, <2 x i8>* %px
312  %y = load <2 x i8>, <2 x i8>* %py
313  %z = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %x, <2 x i8> %y)
314  store <2 x i8> %z, <2 x i8>* %pz
315  ret void
316}
317
318define void @v4i16(<4 x i16>* %px, <4 x i16>* %py, <4 x i16>* %pz) nounwind {
319; SSE-LABEL: v4i16:
320; SSE:       # %bb.0:
321; SSE-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero
322; SSE-NEXT:    movq {{.*#+}} xmm1 = mem[0],zero
323; SSE-NEXT:    psubusw %xmm1, %xmm0
324; SSE-NEXT:    movq %xmm0, (%rdx)
325; SSE-NEXT:    retq
326;
327; AVX-LABEL: v4i16:
328; AVX:       # %bb.0:
329; AVX-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
330; AVX-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
331; AVX-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
332; AVX-NEXT:    vmovq %xmm0, (%rdx)
333; AVX-NEXT:    retq
334  %x = load <4 x i16>, <4 x i16>* %px
335  %y = load <4 x i16>, <4 x i16>* %py
336  %z = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %x, <4 x i16> %y)
337  store <4 x i16> %z, <4 x i16>* %pz
338  ret void
339}
340
341define void @v2i16(<2 x i16>* %px, <2 x i16>* %py, <2 x i16>* %pz) nounwind {
342; SSE-LABEL: v2i16:
343; SSE:       # %bb.0:
344; SSE-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
345; SSE-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
346; SSE-NEXT:    psubusw %xmm1, %xmm0
347; SSE-NEXT:    movd %xmm0, (%rdx)
348; SSE-NEXT:    retq
349;
350; AVX-LABEL: v2i16:
351; AVX:       # %bb.0:
352; AVX-NEXT:    vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
353; AVX-NEXT:    vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero
354; AVX-NEXT:    vpsubusw %xmm1, %xmm0, %xmm0
355; AVX-NEXT:    vmovd %xmm0, (%rdx)
356; AVX-NEXT:    retq
357  %x = load <2 x i16>, <2 x i16>* %px
358  %y = load <2 x i16>, <2 x i16>* %py
359  %z = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %x, <2 x i16> %y)
360  store <2 x i16> %z, <2 x i16>* %pz
361  ret void
362}
363
364define <12 x i8> @v12i8(<12 x i8> %x, <12 x i8> %y) nounwind {
365; SSE-LABEL: v12i8:
366; SSE:       # %bb.0:
367; SSE-NEXT:    psubusb %xmm1, %xmm0
368; SSE-NEXT:    retq
369;
370; AVX-LABEL: v12i8:
371; AVX:       # %bb.0:
372; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
373; AVX-NEXT:    retq
374  %z = call <12 x i8> @llvm.usub.sat.v12i8(<12 x i8> %x, <12 x i8> %y)
375  ret <12 x i8> %z
376}
377
378define void @v12i16(<12 x i16>* %px, <12 x i16>* %py, <12 x i16>* %pz) nounwind {
379; SSE-LABEL: v12i16:
380; SSE:       # %bb.0:
381; SSE-NEXT:    movdqa (%rdi), %xmm0
382; SSE-NEXT:    movdqa 16(%rdi), %xmm1
383; SSE-NEXT:    psubusw 16(%rsi), %xmm1
384; SSE-NEXT:    psubusw (%rsi), %xmm0
385; SSE-NEXT:    movdqa %xmm0, (%rdx)
386; SSE-NEXT:    movq %xmm1, 16(%rdx)
387; SSE-NEXT:    retq
388;
389; AVX1-LABEL: v12i16:
390; AVX1:       # %bb.0:
391; AVX1-NEXT:    vmovdqa (%rdi), %xmm0
392; AVX1-NEXT:    vmovdqa 16(%rdi), %xmm1
393; AVX1-NEXT:    vpsubusw 16(%rsi), %xmm1, %xmm1
394; AVX1-NEXT:    vpsubusw (%rsi), %xmm0, %xmm0
395; AVX1-NEXT:    vmovdqa %xmm0, (%rdx)
396; AVX1-NEXT:    vmovq %xmm1, 16(%rdx)
397; AVX1-NEXT:    retq
398;
399; AVX2-LABEL: v12i16:
400; AVX2:       # %bb.0:
401; AVX2-NEXT:    vmovdqa (%rdi), %ymm0
402; AVX2-NEXT:    vpsubusw (%rsi), %ymm0, %ymm0
403; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
404; AVX2-NEXT:    vmovq %xmm1, 16(%rdx)
405; AVX2-NEXT:    vmovdqa %xmm0, (%rdx)
406; AVX2-NEXT:    vzeroupper
407; AVX2-NEXT:    retq
408;
409; AVX512-LABEL: v12i16:
410; AVX512:       # %bb.0:
411; AVX512-NEXT:    vmovdqa (%rdi), %ymm0
412; AVX512-NEXT:    vpsubusw (%rsi), %ymm0, %ymm0
413; AVX512-NEXT:    vextracti128 $1, %ymm0, %xmm1
414; AVX512-NEXT:    vmovq %xmm1, 16(%rdx)
415; AVX512-NEXT:    vmovdqa %xmm0, (%rdx)
416; AVX512-NEXT:    vzeroupper
417; AVX512-NEXT:    retq
418  %x = load <12 x i16>, <12 x i16>* %px
419  %y = load <12 x i16>, <12 x i16>* %py
420  %z = call <12 x i16> @llvm.usub.sat.v12i16(<12 x i16> %x, <12 x i16> %y)
421  store <12 x i16> %z, <12 x i16>* %pz
422  ret void
423}
424
425; Scalarization
426
427define void @v1i8(<1 x i8>* %px, <1 x i8>* %py, <1 x i8>* %pz) nounwind {
428; SSE-LABEL: v1i8:
429; SSE:       # %bb.0:
430; SSE-NEXT:    movb (%rdi), %al
431; SSE-NEXT:    xorl %ecx, %ecx
432; SSE-NEXT:    subb (%rsi), %al
433; SSE-NEXT:    movzbl %al, %eax
434; SSE-NEXT:    cmovbl %ecx, %eax
435; SSE-NEXT:    movb %al, (%rdx)
436; SSE-NEXT:    retq
437;
438; AVX-LABEL: v1i8:
439; AVX:       # %bb.0:
440; AVX-NEXT:    movb (%rdi), %al
441; AVX-NEXT:    xorl %ecx, %ecx
442; AVX-NEXT:    subb (%rsi), %al
443; AVX-NEXT:    movzbl %al, %eax
444; AVX-NEXT:    cmovbl %ecx, %eax
445; AVX-NEXT:    movb %al, (%rdx)
446; AVX-NEXT:    retq
447  %x = load <1 x i8>, <1 x i8>* %px
448  %y = load <1 x i8>, <1 x i8>* %py
449  %z = call <1 x i8> @llvm.usub.sat.v1i8(<1 x i8> %x, <1 x i8> %y)
450  store <1 x i8> %z, <1 x i8>* %pz
451  ret void
452}
453
454define void @v1i16(<1 x i16>* %px, <1 x i16>* %py, <1 x i16>* %pz) nounwind {
455; SSE-LABEL: v1i16:
456; SSE:       # %bb.0:
457; SSE-NEXT:    movzwl (%rdi), %eax
458; SSE-NEXT:    xorl %ecx, %ecx
459; SSE-NEXT:    subw (%rsi), %ax
460; SSE-NEXT:    cmovbl %ecx, %eax
461; SSE-NEXT:    movw %ax, (%rdx)
462; SSE-NEXT:    retq
463;
464; AVX-LABEL: v1i16:
465; AVX:       # %bb.0:
466; AVX-NEXT:    movzwl (%rdi), %eax
467; AVX-NEXT:    xorl %ecx, %ecx
468; AVX-NEXT:    subw (%rsi), %ax
469; AVX-NEXT:    cmovbl %ecx, %eax
470; AVX-NEXT:    movw %ax, (%rdx)
471; AVX-NEXT:    retq
472  %x = load <1 x i16>, <1 x i16>* %px
473  %y = load <1 x i16>, <1 x i16>* %py
474  %z = call <1 x i16> @llvm.usub.sat.v1i16(<1 x i16> %x, <1 x i16> %y)
475  store <1 x i16> %z, <1 x i16>* %pz
476  ret void
477}
478
479; Promotion
480
481define <16 x i4> @v16i4(<16 x i4> %x, <16 x i4> %y) nounwind {
482; SSE-LABEL: v16i4:
483; SSE:       # %bb.0:
484; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
485; SSE-NEXT:    pand %xmm2, %xmm1
486; SSE-NEXT:    pand %xmm2, %xmm0
487; SSE-NEXT:    psubusb %xmm1, %xmm0
488; SSE-NEXT:    retq
489;
490; AVX-LABEL: v16i4:
491; AVX:       # %bb.0:
492; AVX-NEXT:    vmovdqa {{.*#+}} xmm2 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
493; AVX-NEXT:    vpand %xmm2, %xmm1, %xmm1
494; AVX-NEXT:    vpand %xmm2, %xmm0, %xmm0
495; AVX-NEXT:    vpsubusb %xmm1, %xmm0, %xmm0
496; AVX-NEXT:    retq
497  %z = call <16 x i4> @llvm.usub.sat.v16i4(<16 x i4> %x, <16 x i4> %y)
498  ret <16 x i4> %z
499}
500
501define <16 x i1> @v16i1(<16 x i1> %x, <16 x i1> %y) nounwind {
502; SSE-LABEL: v16i1:
503; SSE:       # %bb.0:
504; SSE-NEXT:    xorps {{.*}}(%rip), %xmm1
505; SSE-NEXT:    andps %xmm1, %xmm0
506; SSE-NEXT:    retq
507;
508; AVX1-LABEL: v16i1:
509; AVX1:       # %bb.0:
510; AVX1-NEXT:    vxorps {{.*}}(%rip), %xmm1, %xmm1
511; AVX1-NEXT:    vandps %xmm1, %xmm0, %xmm0
512; AVX1-NEXT:    retq
513;
514; AVX2-LABEL: v16i1:
515; AVX2:       # %bb.0:
516; AVX2-NEXT:    vxorps {{.*}}(%rip), %xmm1, %xmm1
517; AVX2-NEXT:    vandps %xmm1, %xmm0, %xmm0
518; AVX2-NEXT:    retq
519;
520; AVX512F-LABEL: v16i1:
521; AVX512F:       # %bb.0:
522; AVX512F-NEXT:    vxorps {{.*}}(%rip), %xmm1, %xmm1
523; AVX512F-NEXT:    vandps %xmm1, %xmm0, %xmm0
524; AVX512F-NEXT:    retq
525;
526; AVX512BW-LABEL: v16i1:
527; AVX512BW:       # %bb.0:
528; AVX512BW-NEXT:    vpternlogq $96, {{.*}}(%rip), %xmm1, %xmm0
529; AVX512BW-NEXT:    retq
530  %z = call <16 x i1> @llvm.usub.sat.v16i1(<16 x i1> %x, <16 x i1> %y)
531  ret <16 x i1> %z
532}
533
534; Expanded
535
536define <2 x i32> @v2i32(<2 x i32> %x, <2 x i32> %y) nounwind {
537; SSE2-LABEL: v2i32:
538; SSE2:       # %bb.0:
539; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
540; SSE2-NEXT:    movdqa %xmm1, %xmm3
541; SSE2-NEXT:    pxor %xmm2, %xmm3
542; SSE2-NEXT:    pxor %xmm0, %xmm2
543; SSE2-NEXT:    pcmpgtd %xmm3, %xmm2
544; SSE2-NEXT:    psubd %xmm1, %xmm0
545; SSE2-NEXT:    pand %xmm2, %xmm0
546; SSE2-NEXT:    retq
547;
548; SSSE3-LABEL: v2i32:
549; SSSE3:       # %bb.0:
550; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
551; SSSE3-NEXT:    movdqa %xmm1, %xmm3
552; SSSE3-NEXT:    pxor %xmm2, %xmm3
553; SSSE3-NEXT:    pxor %xmm0, %xmm2
554; SSSE3-NEXT:    pcmpgtd %xmm3, %xmm2
555; SSSE3-NEXT:    psubd %xmm1, %xmm0
556; SSSE3-NEXT:    pand %xmm2, %xmm0
557; SSSE3-NEXT:    retq
558;
559; SSE41-LABEL: v2i32:
560; SSE41:       # %bb.0:
561; SSE41-NEXT:    pmaxud %xmm1, %xmm0
562; SSE41-NEXT:    psubd %xmm1, %xmm0
563; SSE41-NEXT:    retq
564;
565; AVX-LABEL: v2i32:
566; AVX:       # %bb.0:
567; AVX-NEXT:    vpmaxud %xmm1, %xmm0, %xmm0
568; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
569; AVX-NEXT:    retq
570  %z = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %x, <2 x i32> %y)
571  ret <2 x i32> %z
572}
573
574define <4 x i32> @v4i32(<4 x i32> %x, <4 x i32> %y) nounwind {
575; SSE2-LABEL: v4i32:
576; SSE2:       # %bb.0:
577; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
578; SSE2-NEXT:    movdqa %xmm1, %xmm3
579; SSE2-NEXT:    pxor %xmm2, %xmm3
580; SSE2-NEXT:    pxor %xmm0, %xmm2
581; SSE2-NEXT:    pcmpgtd %xmm3, %xmm2
582; SSE2-NEXT:    psubd %xmm1, %xmm0
583; SSE2-NEXT:    pand %xmm2, %xmm0
584; SSE2-NEXT:    retq
585;
586; SSSE3-LABEL: v4i32:
587; SSSE3:       # %bb.0:
588; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
589; SSSE3-NEXT:    movdqa %xmm1, %xmm3
590; SSSE3-NEXT:    pxor %xmm2, %xmm3
591; SSSE3-NEXT:    pxor %xmm0, %xmm2
592; SSSE3-NEXT:    pcmpgtd %xmm3, %xmm2
593; SSSE3-NEXT:    psubd %xmm1, %xmm0
594; SSSE3-NEXT:    pand %xmm2, %xmm0
595; SSSE3-NEXT:    retq
596;
597; SSE41-LABEL: v4i32:
598; SSE41:       # %bb.0:
599; SSE41-NEXT:    pmaxud %xmm1, %xmm0
600; SSE41-NEXT:    psubd %xmm1, %xmm0
601; SSE41-NEXT:    retq
602;
603; AVX-LABEL: v4i32:
604; AVX:       # %bb.0:
605; AVX-NEXT:    vpmaxud %xmm1, %xmm0, %xmm0
606; AVX-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
607; AVX-NEXT:    retq
608  %z = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %x, <4 x i32> %y)
609  ret <4 x i32> %z
610}
611
612define <8 x i32> @v8i32(<8 x i32> %x, <8 x i32> %y) nounwind {
613; SSE2-LABEL: v8i32:
614; SSE2:       # %bb.0:
615; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [2147483648,2147483648,2147483648,2147483648]
616; SSE2-NEXT:    movdqa %xmm0, %xmm5
617; SSE2-NEXT:    psubd %xmm2, %xmm0
618; SSE2-NEXT:    pxor %xmm4, %xmm2
619; SSE2-NEXT:    pxor %xmm4, %xmm5
620; SSE2-NEXT:    pcmpgtd %xmm2, %xmm5
621; SSE2-NEXT:    pand %xmm5, %xmm0
622; SSE2-NEXT:    movdqa %xmm3, %xmm2
623; SSE2-NEXT:    pxor %xmm4, %xmm2
624; SSE2-NEXT:    pxor %xmm1, %xmm4
625; SSE2-NEXT:    pcmpgtd %xmm2, %xmm4
626; SSE2-NEXT:    psubd %xmm3, %xmm1
627; SSE2-NEXT:    pand %xmm4, %xmm1
628; SSE2-NEXT:    retq
629;
630; SSSE3-LABEL: v8i32:
631; SSSE3:       # %bb.0:
632; SSSE3-NEXT:    movdqa {{.*#+}} xmm4 = [2147483648,2147483648,2147483648,2147483648]
633; SSSE3-NEXT:    movdqa %xmm0, %xmm5
634; SSSE3-NEXT:    psubd %xmm2, %xmm0
635; SSSE3-NEXT:    pxor %xmm4, %xmm2
636; SSSE3-NEXT:    pxor %xmm4, %xmm5
637; SSSE3-NEXT:    pcmpgtd %xmm2, %xmm5
638; SSSE3-NEXT:    pand %xmm5, %xmm0
639; SSSE3-NEXT:    movdqa %xmm3, %xmm2
640; SSSE3-NEXT:    pxor %xmm4, %xmm2
641; SSSE3-NEXT:    pxor %xmm1, %xmm4
642; SSSE3-NEXT:    pcmpgtd %xmm2, %xmm4
643; SSSE3-NEXT:    psubd %xmm3, %xmm1
644; SSSE3-NEXT:    pand %xmm4, %xmm1
645; SSSE3-NEXT:    retq
646;
647; SSE41-LABEL: v8i32:
648; SSE41:       # %bb.0:
649; SSE41-NEXT:    pmaxud %xmm2, %xmm0
650; SSE41-NEXT:    psubd %xmm2, %xmm0
651; SSE41-NEXT:    pmaxud %xmm3, %xmm1
652; SSE41-NEXT:    psubd %xmm3, %xmm1
653; SSE41-NEXT:    retq
654;
655; AVX1-LABEL: v8i32:
656; AVX1:       # %bb.0:
657; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
658; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
659; AVX1-NEXT:    vpmaxud %xmm2, %xmm3, %xmm3
660; AVX1-NEXT:    vpsubd %xmm2, %xmm3, %xmm2
661; AVX1-NEXT:    vpmaxud %xmm1, %xmm0, %xmm0
662; AVX1-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
663; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
664; AVX1-NEXT:    retq
665;
666; AVX2-LABEL: v8i32:
667; AVX2:       # %bb.0:
668; AVX2-NEXT:    vpmaxud %ymm1, %ymm0, %ymm0
669; AVX2-NEXT:    vpsubd %ymm1, %ymm0, %ymm0
670; AVX2-NEXT:    retq
671;
672; AVX512-LABEL: v8i32:
673; AVX512:       # %bb.0:
674; AVX512-NEXT:    vpmaxud %ymm1, %ymm0, %ymm0
675; AVX512-NEXT:    vpsubd %ymm1, %ymm0, %ymm0
676; AVX512-NEXT:    retq
677  %z = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %x, <8 x i32> %y)
678  ret <8 x i32> %z
679}
680
681define <16 x i32> @v16i32(<16 x i32> %x, <16 x i32> %y) nounwind {
682; SSE2-LABEL: v16i32:
683; SSE2:       # %bb.0:
684; SSE2-NEXT:    movdqa {{.*#+}} xmm8 = [2147483648,2147483648,2147483648,2147483648]
685; SSE2-NEXT:    movdqa %xmm0, %xmm9
686; SSE2-NEXT:    psubd %xmm4, %xmm0
687; SSE2-NEXT:    pxor %xmm8, %xmm4
688; SSE2-NEXT:    pxor %xmm8, %xmm9
689; SSE2-NEXT:    pcmpgtd %xmm4, %xmm9
690; SSE2-NEXT:    pand %xmm9, %xmm0
691; SSE2-NEXT:    movdqa %xmm1, %xmm4
692; SSE2-NEXT:    psubd %xmm5, %xmm1
693; SSE2-NEXT:    pxor %xmm8, %xmm5
694; SSE2-NEXT:    pxor %xmm8, %xmm4
695; SSE2-NEXT:    pcmpgtd %xmm5, %xmm4
696; SSE2-NEXT:    pand %xmm4, %xmm1
697; SSE2-NEXT:    movdqa %xmm2, %xmm4
698; SSE2-NEXT:    psubd %xmm6, %xmm2
699; SSE2-NEXT:    pxor %xmm8, %xmm6
700; SSE2-NEXT:    pxor %xmm8, %xmm4
701; SSE2-NEXT:    pcmpgtd %xmm6, %xmm4
702; SSE2-NEXT:    pand %xmm4, %xmm2
703; SSE2-NEXT:    movdqa %xmm7, %xmm4
704; SSE2-NEXT:    pxor %xmm8, %xmm4
705; SSE2-NEXT:    pxor %xmm3, %xmm8
706; SSE2-NEXT:    pcmpgtd %xmm4, %xmm8
707; SSE2-NEXT:    psubd %xmm7, %xmm3
708; SSE2-NEXT:    pand %xmm8, %xmm3
709; SSE2-NEXT:    retq
710;
711; SSSE3-LABEL: v16i32:
712; SSSE3:       # %bb.0:
713; SSSE3-NEXT:    movdqa {{.*#+}} xmm8 = [2147483648,2147483648,2147483648,2147483648]
714; SSSE3-NEXT:    movdqa %xmm0, %xmm9
715; SSSE3-NEXT:    psubd %xmm4, %xmm0
716; SSSE3-NEXT:    pxor %xmm8, %xmm4
717; SSSE3-NEXT:    pxor %xmm8, %xmm9
718; SSSE3-NEXT:    pcmpgtd %xmm4, %xmm9
719; SSSE3-NEXT:    pand %xmm9, %xmm0
720; SSSE3-NEXT:    movdqa %xmm1, %xmm4
721; SSSE3-NEXT:    psubd %xmm5, %xmm1
722; SSSE3-NEXT:    pxor %xmm8, %xmm5
723; SSSE3-NEXT:    pxor %xmm8, %xmm4
724; SSSE3-NEXT:    pcmpgtd %xmm5, %xmm4
725; SSSE3-NEXT:    pand %xmm4, %xmm1
726; SSSE3-NEXT:    movdqa %xmm2, %xmm4
727; SSSE3-NEXT:    psubd %xmm6, %xmm2
728; SSSE3-NEXT:    pxor %xmm8, %xmm6
729; SSSE3-NEXT:    pxor %xmm8, %xmm4
730; SSSE3-NEXT:    pcmpgtd %xmm6, %xmm4
731; SSSE3-NEXT:    pand %xmm4, %xmm2
732; SSSE3-NEXT:    movdqa %xmm7, %xmm4
733; SSSE3-NEXT:    pxor %xmm8, %xmm4
734; SSSE3-NEXT:    pxor %xmm3, %xmm8
735; SSSE3-NEXT:    pcmpgtd %xmm4, %xmm8
736; SSSE3-NEXT:    psubd %xmm7, %xmm3
737; SSSE3-NEXT:    pand %xmm8, %xmm3
738; SSSE3-NEXT:    retq
739;
740; SSE41-LABEL: v16i32:
741; SSE41:       # %bb.0:
742; SSE41-NEXT:    pmaxud %xmm4, %xmm0
743; SSE41-NEXT:    psubd %xmm4, %xmm0
744; SSE41-NEXT:    pmaxud %xmm5, %xmm1
745; SSE41-NEXT:    psubd %xmm5, %xmm1
746; SSE41-NEXT:    pmaxud %xmm6, %xmm2
747; SSE41-NEXT:    psubd %xmm6, %xmm2
748; SSE41-NEXT:    pmaxud %xmm7, %xmm3
749; SSE41-NEXT:    psubd %xmm7, %xmm3
750; SSE41-NEXT:    retq
751;
752; AVX1-LABEL: v16i32:
753; AVX1:       # %bb.0:
754; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
755; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
756; AVX1-NEXT:    vpmaxud %xmm4, %xmm5, %xmm5
757; AVX1-NEXT:    vpsubd %xmm4, %xmm5, %xmm4
758; AVX1-NEXT:    vpmaxud %xmm2, %xmm0, %xmm0
759; AVX1-NEXT:    vpsubd %xmm2, %xmm0, %xmm0
760; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm0, %ymm0
761; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm2
762; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm4
763; AVX1-NEXT:    vpmaxud %xmm2, %xmm4, %xmm4
764; AVX1-NEXT:    vpsubd %xmm2, %xmm4, %xmm2
765; AVX1-NEXT:    vpmaxud %xmm3, %xmm1, %xmm1
766; AVX1-NEXT:    vpsubd %xmm3, %xmm1, %xmm1
767; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
768; AVX1-NEXT:    retq
769;
770; AVX2-LABEL: v16i32:
771; AVX2:       # %bb.0:
772; AVX2-NEXT:    vpmaxud %ymm2, %ymm0, %ymm0
773; AVX2-NEXT:    vpsubd %ymm2, %ymm0, %ymm0
774; AVX2-NEXT:    vpmaxud %ymm3, %ymm1, %ymm1
775; AVX2-NEXT:    vpsubd %ymm3, %ymm1, %ymm1
776; AVX2-NEXT:    retq
777;
778; AVX512-LABEL: v16i32:
779; AVX512:       # %bb.0:
780; AVX512-NEXT:    vpmaxud %zmm1, %zmm0, %zmm0
781; AVX512-NEXT:    vpsubd %zmm1, %zmm0, %zmm0
782; AVX512-NEXT:    retq
783  %z = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %x, <16 x i32> %y)
784  ret <16 x i32> %z
785}
786
787define <2 x i64> @v2i64(<2 x i64> %x, <2 x i64> %y) nounwind {
788; SSE-LABEL: v2i64:
789; SSE:       # %bb.0:
790; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [9223372039002259456,9223372039002259456]
791; SSE-NEXT:    movdqa %xmm1, %xmm3
792; SSE-NEXT:    pxor %xmm2, %xmm3
793; SSE-NEXT:    pxor %xmm0, %xmm2
794; SSE-NEXT:    movdqa %xmm2, %xmm4
795; SSE-NEXT:    pcmpgtd %xmm3, %xmm4
796; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
797; SSE-NEXT:    pcmpeqd %xmm3, %xmm2
798; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
799; SSE-NEXT:    pand %xmm5, %xmm2
800; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[1,1,3,3]
801; SSE-NEXT:    por %xmm2, %xmm3
802; SSE-NEXT:    psubq %xmm1, %xmm0
803; SSE-NEXT:    pand %xmm3, %xmm0
804; SSE-NEXT:    retq
805;
806; AVX1-LABEL: v2i64:
807; AVX1:       # %bb.0:
808; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
809; AVX1-NEXT:    vpxor %xmm2, %xmm1, %xmm3
810; AVX1-NEXT:    vpxor %xmm2, %xmm0, %xmm2
811; AVX1-NEXT:    vpcmpgtq %xmm3, %xmm2, %xmm2
812; AVX1-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
813; AVX1-NEXT:    vpand %xmm0, %xmm2, %xmm0
814; AVX1-NEXT:    retq
815;
816; AVX2-LABEL: v2i64:
817; AVX2:       # %bb.0:
818; AVX2-NEXT:    vmovdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
819; AVX2-NEXT:    vpxor %xmm2, %xmm1, %xmm3
820; AVX2-NEXT:    vpxor %xmm2, %xmm0, %xmm2
821; AVX2-NEXT:    vpcmpgtq %xmm3, %xmm2, %xmm2
822; AVX2-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
823; AVX2-NEXT:    vpand %xmm0, %xmm2, %xmm0
824; AVX2-NEXT:    retq
825;
826; AVX512F-LABEL: v2i64:
827; AVX512F:       # %bb.0:
828; AVX512F-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
829; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
830; AVX512F-NEXT:    vpmaxuq %zmm1, %zmm0, %zmm0
831; AVX512F-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
832; AVX512F-NEXT:    vzeroupper
833; AVX512F-NEXT:    retq
834;
835; AVX512BW-LABEL: v2i64:
836; AVX512BW:       # %bb.0:
837; AVX512BW-NEXT:    vpmaxuq %xmm1, %xmm0, %xmm0
838; AVX512BW-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
839; AVX512BW-NEXT:    retq
840  %z = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %x, <2 x i64> %y)
841  ret <2 x i64> %z
842}
843
844define <4 x i64> @v4i64(<4 x i64> %x, <4 x i64> %y) nounwind {
845; SSE-LABEL: v4i64:
846; SSE:       # %bb.0:
847; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [9223372039002259456,9223372039002259456]
848; SSE-NEXT:    movdqa %xmm0, %xmm5
849; SSE-NEXT:    psubq %xmm2, %xmm0
850; SSE-NEXT:    pxor %xmm4, %xmm2
851; SSE-NEXT:    pxor %xmm4, %xmm5
852; SSE-NEXT:    movdqa %xmm5, %xmm6
853; SSE-NEXT:    pcmpgtd %xmm2, %xmm6
854; SSE-NEXT:    pshufd {{.*#+}} xmm7 = xmm6[0,0,2,2]
855; SSE-NEXT:    pcmpeqd %xmm2, %xmm5
856; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm5[1,1,3,3]
857; SSE-NEXT:    pand %xmm7, %xmm2
858; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm6[1,1,3,3]
859; SSE-NEXT:    por %xmm2, %xmm5
860; SSE-NEXT:    pand %xmm5, %xmm0
861; SSE-NEXT:    movdqa %xmm3, %xmm2
862; SSE-NEXT:    pxor %xmm4, %xmm2
863; SSE-NEXT:    pxor %xmm1, %xmm4
864; SSE-NEXT:    movdqa %xmm4, %xmm5
865; SSE-NEXT:    pcmpgtd %xmm2, %xmm5
866; SSE-NEXT:    pshufd {{.*#+}} xmm6 = xmm5[0,0,2,2]
867; SSE-NEXT:    pcmpeqd %xmm2, %xmm4
868; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm4[1,1,3,3]
869; SSE-NEXT:    pand %xmm6, %xmm2
870; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm5[1,1,3,3]
871; SSE-NEXT:    por %xmm2, %xmm4
872; SSE-NEXT:    psubq %xmm3, %xmm1
873; SSE-NEXT:    pand %xmm4, %xmm1
874; SSE-NEXT:    retq
875;
876; AVX1-LABEL: v4i64:
877; AVX1:       # %bb.0:
878; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
879; AVX1-NEXT:    vmovdqa {{.*#+}} xmm3 = [9223372036854775808,9223372036854775808]
880; AVX1-NEXT:    vpxor %xmm3, %xmm2, %xmm4
881; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm5
882; AVX1-NEXT:    vpxor %xmm3, %xmm5, %xmm6
883; AVX1-NEXT:    vpcmpgtq %xmm4, %xmm6, %xmm4
884; AVX1-NEXT:    vpsubq %xmm2, %xmm5, %xmm2
885; AVX1-NEXT:    vpand %xmm2, %xmm4, %xmm2
886; AVX1-NEXT:    vpxor %xmm3, %xmm1, %xmm4
887; AVX1-NEXT:    vpxor %xmm3, %xmm0, %xmm3
888; AVX1-NEXT:    vpcmpgtq %xmm4, %xmm3, %xmm3
889; AVX1-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
890; AVX1-NEXT:    vpand %xmm0, %xmm3, %xmm0
891; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
892; AVX1-NEXT:    retq
893;
894; AVX2-LABEL: v4i64:
895; AVX2:       # %bb.0:
896; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm2 = [9223372036854775808,9223372036854775808,9223372036854775808,9223372036854775808]
897; AVX2-NEXT:    vpxor %ymm2, %ymm1, %ymm3
898; AVX2-NEXT:    vpxor %ymm2, %ymm0, %ymm2
899; AVX2-NEXT:    vpcmpgtq %ymm3, %ymm2, %ymm2
900; AVX2-NEXT:    vpsubq %ymm1, %ymm0, %ymm0
901; AVX2-NEXT:    vpand %ymm0, %ymm2, %ymm0
902; AVX2-NEXT:    retq
903;
904; AVX512F-LABEL: v4i64:
905; AVX512F:       # %bb.0:
906; AVX512F-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
907; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
908; AVX512F-NEXT:    vpmaxuq %zmm1, %zmm0, %zmm0
909; AVX512F-NEXT:    vpsubq %ymm1, %ymm0, %ymm0
910; AVX512F-NEXT:    retq
911;
912; AVX512BW-LABEL: v4i64:
913; AVX512BW:       # %bb.0:
914; AVX512BW-NEXT:    vpmaxuq %ymm1, %ymm0, %ymm0
915; AVX512BW-NEXT:    vpsubq %ymm1, %ymm0, %ymm0
916; AVX512BW-NEXT:    retq
917  %z = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %x, <4 x i64> %y)
918  ret <4 x i64> %z
919}
920
921define <8 x i64> @v8i64(<8 x i64> %x, <8 x i64> %y) nounwind {
922; SSE-LABEL: v8i64:
923; SSE:       # %bb.0:
924; SSE-NEXT:    movdqa {{.*#+}} xmm8 = [9223372039002259456,9223372039002259456]
925; SSE-NEXT:    movdqa %xmm0, %xmm9
926; SSE-NEXT:    psubq %xmm4, %xmm0
927; SSE-NEXT:    pxor %xmm8, %xmm4
928; SSE-NEXT:    pxor %xmm8, %xmm9
929; SSE-NEXT:    movdqa %xmm9, %xmm10
930; SSE-NEXT:    pcmpgtd %xmm4, %xmm10
931; SSE-NEXT:    pshufd {{.*#+}} xmm11 = xmm10[0,0,2,2]
932; SSE-NEXT:    pcmpeqd %xmm4, %xmm9
933; SSE-NEXT:    pshufd {{.*#+}} xmm9 = xmm9[1,1,3,3]
934; SSE-NEXT:    pand %xmm11, %xmm9
935; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm10[1,1,3,3]
936; SSE-NEXT:    por %xmm9, %xmm4
937; SSE-NEXT:    pand %xmm4, %xmm0
938; SSE-NEXT:    movdqa %xmm1, %xmm9
939; SSE-NEXT:    psubq %xmm5, %xmm1
940; SSE-NEXT:    pxor %xmm8, %xmm5
941; SSE-NEXT:    pxor %xmm8, %xmm9
942; SSE-NEXT:    movdqa %xmm9, %xmm4
943; SSE-NEXT:    pcmpgtd %xmm5, %xmm4
944; SSE-NEXT:    pshufd {{.*#+}} xmm10 = xmm4[0,0,2,2]
945; SSE-NEXT:    pcmpeqd %xmm5, %xmm9
946; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm9[1,1,3,3]
947; SSE-NEXT:    pand %xmm10, %xmm5
948; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
949; SSE-NEXT:    por %xmm5, %xmm4
950; SSE-NEXT:    pand %xmm4, %xmm1
951; SSE-NEXT:    movdqa %xmm2, %xmm4
952; SSE-NEXT:    psubq %xmm6, %xmm2
953; SSE-NEXT:    pxor %xmm8, %xmm6
954; SSE-NEXT:    pxor %xmm8, %xmm4
955; SSE-NEXT:    movdqa %xmm4, %xmm5
956; SSE-NEXT:    pcmpgtd %xmm6, %xmm5
957; SSE-NEXT:    pshufd {{.*#+}} xmm9 = xmm5[0,0,2,2]
958; SSE-NEXT:    pcmpeqd %xmm6, %xmm4
959; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
960; SSE-NEXT:    pand %xmm9, %xmm4
961; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3]
962; SSE-NEXT:    por %xmm4, %xmm5
963; SSE-NEXT:    pand %xmm5, %xmm2
964; SSE-NEXT:    movdqa %xmm7, %xmm4
965; SSE-NEXT:    pxor %xmm8, %xmm4
966; SSE-NEXT:    pxor %xmm3, %xmm8
967; SSE-NEXT:    movdqa %xmm8, %xmm5
968; SSE-NEXT:    pcmpgtd %xmm4, %xmm5
969; SSE-NEXT:    pshufd {{.*#+}} xmm6 = xmm5[0,0,2,2]
970; SSE-NEXT:    pcmpeqd %xmm4, %xmm8
971; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm8[1,1,3,3]
972; SSE-NEXT:    pand %xmm6, %xmm4
973; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3]
974; SSE-NEXT:    por %xmm4, %xmm5
975; SSE-NEXT:    psubq %xmm7, %xmm3
976; SSE-NEXT:    pand %xmm5, %xmm3
977; SSE-NEXT:    retq
978;
979; AVX1-LABEL: v8i64:
980; AVX1:       # %bb.0:
981; AVX1-NEXT:    vextractf128 $1, %ymm2, %xmm4
982; AVX1-NEXT:    vmovdqa {{.*#+}} xmm5 = [9223372036854775808,9223372036854775808]
983; AVX1-NEXT:    vpxor %xmm5, %xmm4, %xmm8
984; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm7
985; AVX1-NEXT:    vpxor %xmm5, %xmm7, %xmm6
986; AVX1-NEXT:    vpcmpgtq %xmm8, %xmm6, %xmm6
987; AVX1-NEXT:    vpsubq %xmm4, %xmm7, %xmm4
988; AVX1-NEXT:    vpand %xmm4, %xmm6, %xmm4
989; AVX1-NEXT:    vpxor %xmm5, %xmm2, %xmm6
990; AVX1-NEXT:    vpxor %xmm5, %xmm0, %xmm7
991; AVX1-NEXT:    vpcmpgtq %xmm6, %xmm7, %xmm6
992; AVX1-NEXT:    vpsubq %xmm2, %xmm0, %xmm0
993; AVX1-NEXT:    vpand %xmm0, %xmm6, %xmm0
994; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm0, %ymm0
995; AVX1-NEXT:    vextractf128 $1, %ymm3, %xmm2
996; AVX1-NEXT:    vpxor %xmm5, %xmm2, %xmm4
997; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm6
998; AVX1-NEXT:    vpxor %xmm5, %xmm6, %xmm7
999; AVX1-NEXT:    vpcmpgtq %xmm4, %xmm7, %xmm4
1000; AVX1-NEXT:    vpsubq %xmm2, %xmm6, %xmm2
1001; AVX1-NEXT:    vpand %xmm2, %xmm4, %xmm2
1002; AVX1-NEXT:    vpxor %xmm5, %xmm3, %xmm4
1003; AVX1-NEXT:    vpxor %xmm5, %xmm1, %xmm5
1004; AVX1-NEXT:    vpcmpgtq %xmm4, %xmm5, %xmm4
1005; AVX1-NEXT:    vpsubq %xmm3, %xmm1, %xmm1
1006; AVX1-NEXT:    vpand %xmm1, %xmm4, %xmm1
1007; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm1, %ymm1
1008; AVX1-NEXT:    retq
1009;
1010; AVX2-LABEL: v8i64:
1011; AVX2:       # %bb.0:
1012; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [9223372036854775808,9223372036854775808,9223372036854775808,9223372036854775808]
1013; AVX2-NEXT:    vpxor %ymm4, %ymm2, %ymm5
1014; AVX2-NEXT:    vpxor %ymm4, %ymm0, %ymm6
1015; AVX2-NEXT:    vpcmpgtq %ymm5, %ymm6, %ymm5
1016; AVX2-NEXT:    vpsubq %ymm2, %ymm0, %ymm0
1017; AVX2-NEXT:    vpand %ymm0, %ymm5, %ymm0
1018; AVX2-NEXT:    vpxor %ymm4, %ymm3, %ymm2
1019; AVX2-NEXT:    vpxor %ymm4, %ymm1, %ymm4
1020; AVX2-NEXT:    vpcmpgtq %ymm2, %ymm4, %ymm2
1021; AVX2-NEXT:    vpsubq %ymm3, %ymm1, %ymm1
1022; AVX2-NEXT:    vpand %ymm1, %ymm2, %ymm1
1023; AVX2-NEXT:    retq
1024;
1025; AVX512-LABEL: v8i64:
1026; AVX512:       # %bb.0:
1027; AVX512-NEXT:    vpmaxuq %zmm1, %zmm0, %zmm0
1028; AVX512-NEXT:    vpsubq %zmm1, %zmm0, %zmm0
1029; AVX512-NEXT:    retq
1030  %z = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %x, <8 x i64> %y)
1031  ret <8 x i64> %z
1032}
1033
1034define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind {
1035; SSE-LABEL: v2i128:
1036; SSE:       # %bb.0:
1037; SSE-NEXT:    movq %rdi, %rax
1038; SSE-NEXT:    xorl %edi, %edi
1039; SSE-NEXT:    subq %r9, %rsi
1040; SSE-NEXT:    sbbq {{[0-9]+}}(%rsp), %rdx
1041; SSE-NEXT:    cmovbq %rdi, %rsi
1042; SSE-NEXT:    cmovbq %rdi, %rdx
1043; SSE-NEXT:    subq {{[0-9]+}}(%rsp), %rcx
1044; SSE-NEXT:    sbbq {{[0-9]+}}(%rsp), %r8
1045; SSE-NEXT:    cmovbq %rdi, %r8
1046; SSE-NEXT:    cmovbq %rdi, %rcx
1047; SSE-NEXT:    movq %r8, 24(%rax)
1048; SSE-NEXT:    movq %rcx, 16(%rax)
1049; SSE-NEXT:    movq %rdx, 8(%rax)
1050; SSE-NEXT:    movq %rsi, (%rax)
1051; SSE-NEXT:    retq
1052;
1053; AVX-LABEL: v2i128:
1054; AVX:       # %bb.0:
1055; AVX-NEXT:    movq %rdi, %rax
1056; AVX-NEXT:    xorl %edi, %edi
1057; AVX-NEXT:    subq %r9, %rsi
1058; AVX-NEXT:    sbbq {{[0-9]+}}(%rsp), %rdx
1059; AVX-NEXT:    cmovbq %rdi, %rsi
1060; AVX-NEXT:    cmovbq %rdi, %rdx
1061; AVX-NEXT:    subq {{[0-9]+}}(%rsp), %rcx
1062; AVX-NEXT:    sbbq {{[0-9]+}}(%rsp), %r8
1063; AVX-NEXT:    cmovbq %rdi, %r8
1064; AVX-NEXT:    cmovbq %rdi, %rcx
1065; AVX-NEXT:    movq %r8, 24(%rax)
1066; AVX-NEXT:    movq %rcx, 16(%rax)
1067; AVX-NEXT:    movq %rdx, 8(%rax)
1068; AVX-NEXT:    movq %rsi, (%rax)
1069; AVX-NEXT:    retq
1070  %z = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %x, <2 x i128> %y)
1071  ret <2 x i128> %z
1072}
1073
1074define void @PR48223(<32 x i16>* %p0) {
1075; SSE-LABEL: PR48223:
1076; SSE:       # %bb.0:
1077; SSE-NEXT:    movdqa (%rdi), %xmm0
1078; SSE-NEXT:    movdqa 16(%rdi), %xmm1
1079; SSE-NEXT:    movdqa 32(%rdi), %xmm2
1080; SSE-NEXT:    movdqa 48(%rdi), %xmm3
1081; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64]
1082; SSE-NEXT:    psubusw %xmm4, %xmm1
1083; SSE-NEXT:    psubusw %xmm4, %xmm0
1084; SSE-NEXT:    psubusw %xmm4, %xmm3
1085; SSE-NEXT:    psubusw %xmm4, %xmm2
1086; SSE-NEXT:    movdqa %xmm2, 32(%rdi)
1087; SSE-NEXT:    movdqa %xmm3, 48(%rdi)
1088; SSE-NEXT:    movdqa %xmm0, (%rdi)
1089; SSE-NEXT:    movdqa %xmm1, 16(%rdi)
1090; SSE-NEXT:    retq
1091;
1092; AVX1-LABEL: PR48223:
1093; AVX1:       # %bb.0:
1094; AVX1-NEXT:    vmovdqa (%rdi), %xmm0
1095; AVX1-NEXT:    vmovdqa 16(%rdi), %xmm1
1096; AVX1-NEXT:    vmovdqa 32(%rdi), %xmm2
1097; AVX1-NEXT:    vmovdqa 48(%rdi), %xmm3
1098; AVX1-NEXT:    vmovdqa {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64]
1099; AVX1-NEXT:    vpsubusw %xmm4, %xmm3, %xmm3
1100; AVX1-NEXT:    vpsubusw %xmm4, %xmm2, %xmm2
1101; AVX1-NEXT:    vpsubusw %xmm4, %xmm1, %xmm1
1102; AVX1-NEXT:    vpsubusw %xmm4, %xmm0, %xmm0
1103; AVX1-NEXT:    vmovdqa %xmm0, (%rdi)
1104; AVX1-NEXT:    vmovdqa %xmm1, 16(%rdi)
1105; AVX1-NEXT:    vmovdqa %xmm2, 32(%rdi)
1106; AVX1-NEXT:    vmovdqa %xmm3, 48(%rdi)
1107; AVX1-NEXT:    retq
1108;
1109; AVX2-LABEL: PR48223:
1110; AVX2:       # %bb.0:
1111; AVX2-NEXT:    vmovdqa (%rdi), %ymm0
1112; AVX2-NEXT:    vmovdqa 32(%rdi), %ymm1
1113; AVX2-NEXT:    vmovdqa {{.*#+}} ymm2 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
1114; AVX2-NEXT:    vpsubusw %ymm2, %ymm1, %ymm1
1115; AVX2-NEXT:    vpsubusw %ymm2, %ymm0, %ymm0
1116; AVX2-NEXT:    vmovdqa %ymm0, (%rdi)
1117; AVX2-NEXT:    vmovdqa %ymm1, 32(%rdi)
1118; AVX2-NEXT:    vzeroupper
1119; AVX2-NEXT:    retq
1120;
1121; AVX512F-LABEL: PR48223:
1122; AVX512F:       # %bb.0:
1123; AVX512F-NEXT:    vmovdqa (%rdi), %ymm0
1124; AVX512F-NEXT:    vmovdqa 32(%rdi), %ymm1
1125; AVX512F-NEXT:    vmovdqa {{.*#+}} ymm2 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64]
1126; AVX512F-NEXT:    vpsubusw %ymm2, %ymm1, %ymm1
1127; AVX512F-NEXT:    vpsubusw %ymm2, %ymm0, %ymm0
1128; AVX512F-NEXT:    vmovdqa %ymm0, (%rdi)
1129; AVX512F-NEXT:    vmovdqa %ymm1, 32(%rdi)
1130; AVX512F-NEXT:    vzeroupper
1131; AVX512F-NEXT:    retq
1132;
1133; AVX512BW-LABEL: PR48223:
1134; AVX512BW:       # %bb.0:
1135; AVX512BW-NEXT:    vmovdqa64 (%rdi), %zmm0
1136; AVX512BW-NEXT:    vpsubusw {{.*}}(%rip), %zmm0, %zmm0
1137; AVX512BW-NEXT:    vmovdqa64 %zmm0, (%rdi)
1138; AVX512BW-NEXT:    vzeroupper
1139; AVX512BW-NEXT:    retq
1140  %1 = load <32 x i16>, <32 x i16>* %p0, align 64
1141  %2 = icmp ugt <32 x i16> %1, <i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63>
1142  %3 = add <32 x i16> %1, <i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64>
1143  %4 = select <32 x i1> %2, <32 x i16> %3, <32 x i16> zeroinitializer
1144  store <32 x i16> %4, <32 x i16>* %p0, align 64
1145  ret void
1146}
1147