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