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