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