[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / X86 / combine-udiv.ll
blobe7e14f81c5fd90d39a19d5f4860c91e82225da4f
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=+sse4.1 | FileCheck %s --check-prefixes=CHECK,SSE,SSE41
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx  | FileCheck %s --check-prefixes=CHECK,AVX,AVX1
5 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=CHECK,AVX,AVX2
6 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx,+xop | FileCheck %s --check-prefixes=CHECK,XOP
8 ; fold (udiv x, 1) -> x
9 define i32 @combine_udiv_by_one(i32 %x) {
10 ; CHECK-LABEL: combine_udiv_by_one:
11 ; CHECK:       # %bb.0:
12 ; CHECK-NEXT:    movl %edi, %eax
13 ; CHECK-NEXT:    retq
14   %1 = udiv i32 %x, 1
15   ret i32 %1
18 define <4 x i32> @combine_vec_udiv_by_one(<4 x i32> %x) {
19 ; CHECK-LABEL: combine_vec_udiv_by_one:
20 ; CHECK:       # %bb.0:
21 ; CHECK-NEXT:    retq
22   %1 = udiv <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1>
23   ret <4 x i32> %1
26 ; fold (udiv x, -1) -> select((icmp eq x, -1), 1, 0)
27 define i32 @combine_udiv_by_negone(i32 %x) {
28 ; CHECK-LABEL: combine_udiv_by_negone:
29 ; CHECK:       # %bb.0:
30 ; CHECK-NEXT:    xorl %eax, %eax
31 ; CHECK-NEXT:    cmpl $-1, %edi
32 ; CHECK-NEXT:    sete %al
33 ; CHECK-NEXT:    retq
34   %1 = udiv i32 %x, -1
35   ret i32 %1
38 define <4 x i32> @combine_vec_udiv_by_negone(<4 x i32> %x) {
39 ; SSE-LABEL: combine_vec_udiv_by_negone:
40 ; SSE:       # %bb.0:
41 ; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
42 ; SSE-NEXT:    pcmpeqd %xmm1, %xmm0
43 ; SSE-NEXT:    psrld $31, %xmm0
44 ; SSE-NEXT:    retq
46 ; AVX-LABEL: combine_vec_udiv_by_negone:
47 ; AVX:       # %bb.0:
48 ; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
49 ; AVX-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
50 ; AVX-NEXT:    vpsrld $31, %xmm0, %xmm0
51 ; AVX-NEXT:    retq
53 ; XOP-LABEL: combine_vec_udiv_by_negone:
54 ; XOP:       # %bb.0:
55 ; XOP-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
56 ; XOP-NEXT:    vpcomeqd %xmm1, %xmm0, %xmm0
57 ; XOP-NEXT:    vpsrld $31, %xmm0, %xmm0
58 ; XOP-NEXT:    retq
59   %1 = udiv <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
60   ret <4 x i32> %1
63 ; fold (udiv x, INT_MIN) -> (srl x, 31)
64 define i32 @combine_udiv_by_minsigned(i32 %x) {
65 ; CHECK-LABEL: combine_udiv_by_minsigned:
66 ; CHECK:       # %bb.0:
67 ; CHECK-NEXT:    movl %edi, %eax
68 ; CHECK-NEXT:    shrl $31, %eax
69 ; CHECK-NEXT:    retq
70   %1 = udiv i32 %x, -2147483648
71   ret i32 %1
74 define <4 x i32> @combine_vec_udiv_by_minsigned(<4 x i32> %x) {
75 ; SSE-LABEL: combine_vec_udiv_by_minsigned:
76 ; SSE:       # %bb.0:
77 ; SSE-NEXT:    psrld $31, %xmm0
78 ; SSE-NEXT:    retq
80 ; AVX-LABEL: combine_vec_udiv_by_minsigned:
81 ; AVX:       # %bb.0:
82 ; AVX-NEXT:    vpsrld $31, %xmm0, %xmm0
83 ; AVX-NEXT:    retq
85 ; XOP-LABEL: combine_vec_udiv_by_minsigned:
86 ; XOP:       # %bb.0:
87 ; XOP-NEXT:    vpsrld $31, %xmm0, %xmm0
88 ; XOP-NEXT:    retq
89   %1 = udiv <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
90   ret <4 x i32> %1
93 ; fold (udiv 0, x) -> 0
94 define i32 @combine_udiv_zero(i32 %x) {
95 ; CHECK-LABEL: combine_udiv_zero:
96 ; CHECK:       # %bb.0:
97 ; CHECK-NEXT:    xorl %eax, %eax
98 ; CHECK-NEXT:    retq
99   %1 = udiv i32 0, %x
100   ret i32 %1
103 define <4 x i32> @combine_vec_udiv_zero(<4 x i32> %x) {
104 ; SSE-LABEL: combine_vec_udiv_zero:
105 ; SSE:       # %bb.0:
106 ; SSE-NEXT:    xorps %xmm0, %xmm0
107 ; SSE-NEXT:    retq
109 ; AVX-LABEL: combine_vec_udiv_zero:
110 ; AVX:       # %bb.0:
111 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
112 ; AVX-NEXT:    retq
114 ; XOP-LABEL: combine_vec_udiv_zero:
115 ; XOP:       # %bb.0:
116 ; XOP-NEXT:    vxorps %xmm0, %xmm0, %xmm0
117 ; XOP-NEXT:    retq
118   %1 = udiv <4 x i32> zeroinitializer, %x
119   ret <4 x i32> %1
122 ; fold (udiv x, x) -> 1
123 define i32 @combine_udiv_dupe(i32 %x) {
124 ; CHECK-LABEL: combine_udiv_dupe:
125 ; CHECK:       # %bb.0:
126 ; CHECK-NEXT:    movl $1, %eax
127 ; CHECK-NEXT:    retq
128   %1 = udiv i32 %x, %x
129   ret i32 %1
132 define <4 x i32> @combine_vec_udiv_dupe(<4 x i32> %x) {
133 ; SSE-LABEL: combine_vec_udiv_dupe:
134 ; SSE:       # %bb.0:
135 ; SSE-NEXT:    movaps {{.*#+}} xmm0 = [1,1,1,1]
136 ; SSE-NEXT:    retq
138 ; AVX1-LABEL: combine_vec_udiv_dupe:
139 ; AVX1:       # %bb.0:
140 ; AVX1-NEXT:    vmovaps {{.*#+}} xmm0 = [1,1,1,1]
141 ; AVX1-NEXT:    retq
143 ; AVX2-LABEL: combine_vec_udiv_dupe:
144 ; AVX2:       # %bb.0:
145 ; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm0 = [1,1,1,1]
146 ; AVX2-NEXT:    retq
148 ; XOP-LABEL: combine_vec_udiv_dupe:
149 ; XOP:       # %bb.0:
150 ; XOP-NEXT:    vmovaps {{.*#+}} xmm0 = [1,1,1,1]
151 ; XOP-NEXT:    retq
152   %1 = udiv <4 x i32> %x, %x
153   ret <4 x i32> %1
156 ; fold (udiv x, (1 << c)) -> x >>u c
157 define <4 x i32> @combine_vec_udiv_by_pow2a(<4 x i32> %x) {
158 ; SSE-LABEL: combine_vec_udiv_by_pow2a:
159 ; SSE:       # %bb.0:
160 ; SSE-NEXT:    psrld $2, %xmm0
161 ; SSE-NEXT:    retq
163 ; AVX-LABEL: combine_vec_udiv_by_pow2a:
164 ; AVX:       # %bb.0:
165 ; AVX-NEXT:    vpsrld $2, %xmm0, %xmm0
166 ; AVX-NEXT:    retq
168 ; XOP-LABEL: combine_vec_udiv_by_pow2a:
169 ; XOP:       # %bb.0:
170 ; XOP-NEXT:    vpsrld $2, %xmm0, %xmm0
171 ; XOP-NEXT:    retq
172   %1 = udiv <4 x i32> %x, <i32 4, i32 4, i32 4, i32 4>
173   ret <4 x i32> %1
176 define <4 x i32> @combine_vec_udiv_by_pow2b(<4 x i32> %x) {
177 ; SSE2-LABEL: combine_vec_udiv_by_pow2b:
178 ; SSE2:       # %bb.0:
179 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
180 ; SSE2-NEXT:    psrld $4, %xmm1
181 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
182 ; SSE2-NEXT:    psrld $3, %xmm2
183 ; SSE2-NEXT:    punpckhqdq {{.*#+}} xmm2 = xmm2[1],xmm1[1]
184 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
185 ; SSE2-NEXT:    psrld $2, %xmm1
186 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
187 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,3],xmm2[0,3]
188 ; SSE2-NEXT:    retq
190 ; SSE41-LABEL: combine_vec_udiv_by_pow2b:
191 ; SSE41:       # %bb.0:
192 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
193 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
194 ; SSE41-NEXT:    psrld $3, %xmm1
195 ; SSE41-NEXT:    pblendw {{.*#+}} xmm1 = xmm0[0,1,2,3],xmm1[4,5,6,7]
196 ; SSE41-NEXT:    psrld $4, %xmm0
197 ; SSE41-NEXT:    psrld $2, %xmm2
198 ; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm2[0,1,2,3],xmm0[4,5,6,7]
199 ; SSE41-NEXT:    pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7]
200 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
201 ; SSE41-NEXT:    retq
203 ; AVX1-LABEL: combine_vec_udiv_by_pow2b:
204 ; AVX1:       # %bb.0:
205 ; AVX1-NEXT:    vpsrld $4, %xmm0, %xmm1
206 ; AVX1-NEXT:    vpsrld $2, %xmm0, %xmm2
207 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm2[0,1,2,3],xmm1[4,5,6,7]
208 ; AVX1-NEXT:    vpsrld $3, %xmm0, %xmm2
209 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm2[4,5,6,7]
210 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
211 ; AVX1-NEXT:    retq
213 ; AVX2-LABEL: combine_vec_udiv_by_pow2b:
214 ; AVX2:       # %bb.0:
215 ; AVX2-NEXT:    vpsrlvd {{.*}}(%rip), %xmm0, %xmm0
216 ; AVX2-NEXT:    retq
218 ; XOP-LABEL: combine_vec_udiv_by_pow2b:
219 ; XOP:       # %bb.0:
220 ; XOP-NEXT:    vpshld {{.*}}(%rip), %xmm0, %xmm0
221 ; XOP-NEXT:    retq
222   %1 = udiv <4 x i32> %x, <i32 1, i32 4, i32 8, i32 16>
223   ret <4 x i32> %1
226 define <4 x i32> @combine_vec_udiv_by_pow2c(<4 x i32> %x, <4 x i32> %y) {
227 ; SSE2-LABEL: combine_vec_udiv_by_pow2c:
228 ; SSE2:       # %bb.0:
229 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[2,3,3,3,4,5,6,7]
230 ; SSE2-NEXT:    movdqa %xmm0, %xmm3
231 ; SSE2-NEXT:    psrld %xmm2, %xmm3
232 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm4 = xmm1[0,1,1,1,4,5,6,7]
233 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
234 ; SSE2-NEXT:    psrld %xmm4, %xmm2
235 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
236 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
237 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm3 = xmm1[2,3,3,3,4,5,6,7]
238 ; SSE2-NEXT:    movdqa %xmm0, %xmm4
239 ; SSE2-NEXT:    psrld %xmm3, %xmm4
240 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,1,1,4,5,6,7]
241 ; SSE2-NEXT:    psrld %xmm1, %xmm0
242 ; SSE2-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm4[1]
243 ; SSE2-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,3],xmm0[0,3]
244 ; SSE2-NEXT:    movaps %xmm2, %xmm0
245 ; SSE2-NEXT:    retq
247 ; SSE41-LABEL: combine_vec_udiv_by_pow2c:
248 ; SSE41:       # %bb.0:
249 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[2,3,3,3,4,5,6,7]
250 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
251 ; SSE41-NEXT:    psrld %xmm2, %xmm3
252 ; SSE41-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[2,3,0,1]
253 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm4 = xmm2[2,3,3,3,4,5,6,7]
254 ; SSE41-NEXT:    movdqa %xmm0, %xmm5
255 ; SSE41-NEXT:    psrld %xmm4, %xmm5
256 ; SSE41-NEXT:    pblendw {{.*#+}} xmm5 = xmm3[0,1,2,3],xmm5[4,5,6,7]
257 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,1,1,4,5,6,7]
258 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
259 ; SSE41-NEXT:    psrld %xmm1, %xmm3
260 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm1 = xmm2[0,1,1,1,4,5,6,7]
261 ; SSE41-NEXT:    psrld %xmm1, %xmm0
262 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm3[0,1,2,3],xmm0[4,5,6,7]
263 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm5[2,3],xmm0[4,5],xmm5[6,7]
264 ; SSE41-NEXT:    retq
266 ; AVX1-LABEL: combine_vec_udiv_by_pow2c:
267 ; AVX1:       # %bb.0:
268 ; AVX1-NEXT:    vpsrldq {{.*#+}} xmm2 = xmm1[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
269 ; AVX1-NEXT:    vpsrld %xmm2, %xmm0, %xmm2
270 ; AVX1-NEXT:    vpsrlq $32, %xmm1, %xmm3
271 ; AVX1-NEXT:    vpsrld %xmm3, %xmm0, %xmm3
272 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
273 ; AVX1-NEXT:    vpxor %xmm3, %xmm3, %xmm3
274 ; AVX1-NEXT:    vpunpckhdq {{.*#+}} xmm3 = xmm1[2],xmm3[2],xmm1[3],xmm3[3]
275 ; AVX1-NEXT:    vpsrld %xmm3, %xmm0, %xmm3
276 ; AVX1-NEXT:    vpmovzxdq {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero
277 ; AVX1-NEXT:    vpsrld %xmm1, %xmm0, %xmm0
278 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm3[4,5,6,7]
279 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
280 ; AVX1-NEXT:    retq
282 ; AVX2-LABEL: combine_vec_udiv_by_pow2c:
283 ; AVX2:       # %bb.0:
284 ; AVX2-NEXT:    vpsrlvd %xmm1, %xmm0, %xmm0
285 ; AVX2-NEXT:    retq
287 ; XOP-LABEL: combine_vec_udiv_by_pow2c:
288 ; XOP:       # %bb.0:
289 ; XOP-NEXT:    vpxor %xmm2, %xmm2, %xmm2
290 ; XOP-NEXT:    vpsubd %xmm1, %xmm2, %xmm1
291 ; XOP-NEXT:    vpshld %xmm1, %xmm0, %xmm0
292 ; XOP-NEXT:    retq
293   %1 = shl <4 x i32> <i32 1, i32 1, i32 1, i32 1>, %y
294   %2 = udiv <4 x i32> %x, %1
295   ret <4 x i32> %2
298 ; fold (udiv x, (shl c, y)) -> x >>u (log2(c)+y) iff c is power of 2
299 define <4 x i32> @combine_vec_udiv_by_shl_pow2a(<4 x i32> %x, <4 x i32> %y) {
300 ; SSE2-LABEL: combine_vec_udiv_by_shl_pow2a:
301 ; SSE2:       # %bb.0:
302 ; SSE2-NEXT:    paddd {{.*}}(%rip), %xmm1
303 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[2,3,3,3,4,5,6,7]
304 ; SSE2-NEXT:    movdqa %xmm0, %xmm3
305 ; SSE2-NEXT:    psrld %xmm2, %xmm3
306 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm4 = xmm1[0,1,1,1,4,5,6,7]
307 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
308 ; SSE2-NEXT:    psrld %xmm4, %xmm2
309 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
310 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
311 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm3 = xmm1[2,3,3,3,4,5,6,7]
312 ; SSE2-NEXT:    movdqa %xmm0, %xmm4
313 ; SSE2-NEXT:    psrld %xmm3, %xmm4
314 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,1,1,4,5,6,7]
315 ; SSE2-NEXT:    psrld %xmm1, %xmm0
316 ; SSE2-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm4[1]
317 ; SSE2-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,3],xmm0[0,3]
318 ; SSE2-NEXT:    movaps %xmm2, %xmm0
319 ; SSE2-NEXT:    retq
321 ; SSE41-LABEL: combine_vec_udiv_by_shl_pow2a:
322 ; SSE41:       # %bb.0:
323 ; SSE41-NEXT:    paddd {{.*}}(%rip), %xmm1
324 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[2,3,3,3,4,5,6,7]
325 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
326 ; SSE41-NEXT:    psrld %xmm2, %xmm3
327 ; SSE41-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[2,3,0,1]
328 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm4 = xmm2[2,3,3,3,4,5,6,7]
329 ; SSE41-NEXT:    movdqa %xmm0, %xmm5
330 ; SSE41-NEXT:    psrld %xmm4, %xmm5
331 ; SSE41-NEXT:    pblendw {{.*#+}} xmm5 = xmm3[0,1,2,3],xmm5[4,5,6,7]
332 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,1,1,4,5,6,7]
333 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
334 ; SSE41-NEXT:    psrld %xmm1, %xmm3
335 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm1 = xmm2[0,1,1,1,4,5,6,7]
336 ; SSE41-NEXT:    psrld %xmm1, %xmm0
337 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm3[0,1,2,3],xmm0[4,5,6,7]
338 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm5[2,3],xmm0[4,5],xmm5[6,7]
339 ; SSE41-NEXT:    retq
341 ; AVX1-LABEL: combine_vec_udiv_by_shl_pow2a:
342 ; AVX1:       # %bb.0:
343 ; AVX1-NEXT:    vpaddd {{.*}}(%rip), %xmm1, %xmm1
344 ; AVX1-NEXT:    vpsrldq {{.*#+}} xmm2 = xmm1[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
345 ; AVX1-NEXT:    vpsrld %xmm2, %xmm0, %xmm2
346 ; AVX1-NEXT:    vpsrlq $32, %xmm1, %xmm3
347 ; AVX1-NEXT:    vpsrld %xmm3, %xmm0, %xmm3
348 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
349 ; AVX1-NEXT:    vpxor %xmm3, %xmm3, %xmm3
350 ; AVX1-NEXT:    vpunpckhdq {{.*#+}} xmm3 = xmm1[2],xmm3[2],xmm1[3],xmm3[3]
351 ; AVX1-NEXT:    vpsrld %xmm3, %xmm0, %xmm3
352 ; AVX1-NEXT:    vpmovzxdq {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero
353 ; AVX1-NEXT:    vpsrld %xmm1, %xmm0, %xmm0
354 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm3[4,5,6,7]
355 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
356 ; AVX1-NEXT:    retq
358 ; AVX2-LABEL: combine_vec_udiv_by_shl_pow2a:
359 ; AVX2:       # %bb.0:
360 ; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [2,2,2,2]
361 ; AVX2-NEXT:    vpaddd %xmm2, %xmm1, %xmm1
362 ; AVX2-NEXT:    vpsrlvd %xmm1, %xmm0, %xmm0
363 ; AVX2-NEXT:    retq
365 ; XOP-LABEL: combine_vec_udiv_by_shl_pow2a:
366 ; XOP:       # %bb.0:
367 ; XOP-NEXT:    vmovdqa {{.*#+}} xmm2 = [4294967294,4294967294,4294967294,4294967294]
368 ; XOP-NEXT:    vpsubd %xmm1, %xmm2, %xmm1
369 ; XOP-NEXT:    vpshld %xmm1, %xmm0, %xmm0
370 ; XOP-NEXT:    retq
371   %1 = shl <4 x i32> <i32 4, i32 4, i32 4, i32 4>, %y
372   %2 = udiv <4 x i32> %x, %1
373   ret <4 x i32> %2
376 define <4 x i32> @combine_vec_udiv_by_shl_pow2b(<4 x i32> %x, <4 x i32> %y) {
377 ; SSE2-LABEL: combine_vec_udiv_by_shl_pow2b:
378 ; SSE2:       # %bb.0:
379 ; SSE2-NEXT:    paddd {{.*}}(%rip), %xmm1
380 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[2,3,3,3,4,5,6,7]
381 ; SSE2-NEXT:    movdqa %xmm0, %xmm3
382 ; SSE2-NEXT:    psrld %xmm2, %xmm3
383 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm4 = xmm1[0,1,1,1,4,5,6,7]
384 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
385 ; SSE2-NEXT:    psrld %xmm4, %xmm2
386 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
387 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
388 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm3 = xmm1[2,3,3,3,4,5,6,7]
389 ; SSE2-NEXT:    movdqa %xmm0, %xmm4
390 ; SSE2-NEXT:    psrld %xmm3, %xmm4
391 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,1,1,4,5,6,7]
392 ; SSE2-NEXT:    psrld %xmm1, %xmm0
393 ; SSE2-NEXT:    punpckhqdq {{.*#+}} xmm0 = xmm0[1],xmm4[1]
394 ; SSE2-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,3],xmm0[0,3]
395 ; SSE2-NEXT:    movaps %xmm2, %xmm0
396 ; SSE2-NEXT:    retq
398 ; SSE41-LABEL: combine_vec_udiv_by_shl_pow2b:
399 ; SSE41:       # %bb.0:
400 ; SSE41-NEXT:    paddd {{.*}}(%rip), %xmm1
401 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[2,3,3,3,4,5,6,7]
402 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
403 ; SSE41-NEXT:    psrld %xmm2, %xmm3
404 ; SSE41-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[2,3,0,1]
405 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm4 = xmm2[2,3,3,3,4,5,6,7]
406 ; SSE41-NEXT:    movdqa %xmm0, %xmm5
407 ; SSE41-NEXT:    psrld %xmm4, %xmm5
408 ; SSE41-NEXT:    pblendw {{.*#+}} xmm5 = xmm3[0,1,2,3],xmm5[4,5,6,7]
409 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,1,1,4,5,6,7]
410 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
411 ; SSE41-NEXT:    psrld %xmm1, %xmm3
412 ; SSE41-NEXT:    pshuflw {{.*#+}} xmm1 = xmm2[0,1,1,1,4,5,6,7]
413 ; SSE41-NEXT:    psrld %xmm1, %xmm0
414 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm3[0,1,2,3],xmm0[4,5,6,7]
415 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm5[2,3],xmm0[4,5],xmm5[6,7]
416 ; SSE41-NEXT:    retq
418 ; AVX1-LABEL: combine_vec_udiv_by_shl_pow2b:
419 ; AVX1:       # %bb.0:
420 ; AVX1-NEXT:    vpaddd {{.*}}(%rip), %xmm1, %xmm1
421 ; AVX1-NEXT:    vpsrldq {{.*#+}} xmm2 = xmm1[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
422 ; AVX1-NEXT:    vpsrld %xmm2, %xmm0, %xmm2
423 ; AVX1-NEXT:    vpsrlq $32, %xmm1, %xmm3
424 ; AVX1-NEXT:    vpsrld %xmm3, %xmm0, %xmm3
425 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
426 ; AVX1-NEXT:    vpxor %xmm3, %xmm3, %xmm3
427 ; AVX1-NEXT:    vpunpckhdq {{.*#+}} xmm3 = xmm1[2],xmm3[2],xmm1[3],xmm3[3]
428 ; AVX1-NEXT:    vpsrld %xmm3, %xmm0, %xmm3
429 ; AVX1-NEXT:    vpmovzxdq {{.*#+}} xmm1 = xmm1[0],zero,xmm1[1],zero
430 ; AVX1-NEXT:    vpsrld %xmm1, %xmm0, %xmm0
431 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm3[4,5,6,7]
432 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
433 ; AVX1-NEXT:    retq
435 ; AVX2-LABEL: combine_vec_udiv_by_shl_pow2b:
436 ; AVX2:       # %bb.0:
437 ; AVX2-NEXT:    vpaddd {{.*}}(%rip), %xmm1, %xmm1
438 ; AVX2-NEXT:    vpsrlvd %xmm1, %xmm0, %xmm0
439 ; AVX2-NEXT:    retq
441 ; XOP-LABEL: combine_vec_udiv_by_shl_pow2b:
442 ; XOP:       # %bb.0:
443 ; XOP-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,4294967294,4294967293,4294967292]
444 ; XOP-NEXT:    vpsubd %xmm1, %xmm2, %xmm1
445 ; XOP-NEXT:    vpshld %xmm1, %xmm0, %xmm0
446 ; XOP-NEXT:    retq
447   %1 = shl <4 x i32> <i32 1, i32 4, i32 8, i32 16>, %y
448   %2 = udiv <4 x i32> %x, %1
449   ret <4 x i32> %2
452 ; fold (udiv x, c1)
453 define i32 @combine_udiv_uniform(i32 %x) {
454 ; CHECK-LABEL: combine_udiv_uniform:
455 ; CHECK:       # %bb.0:
456 ; CHECK-NEXT:    movl %edi, %ecx
457 ; CHECK-NEXT:    movl $2987803337, %eax # imm = 0xB21642C9
458 ; CHECK-NEXT:    imulq %rcx, %rax
459 ; CHECK-NEXT:    shrq $36, %rax
460 ; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
461 ; CHECK-NEXT:    retq
462   %1 = udiv i32 %x, 23
463   ret i32 %1
466 define <8 x i16> @combine_vec_udiv_uniform(<8 x i16> %x) {
467 ; SSE-LABEL: combine_vec_udiv_uniform:
468 ; SSE:       # %bb.0:
469 ; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [25645,25645,25645,25645,25645,25645,25645,25645]
470 ; SSE-NEXT:    pmulhuw %xmm0, %xmm1
471 ; SSE-NEXT:    psubw %xmm1, %xmm0
472 ; SSE-NEXT:    psrlw $1, %xmm0
473 ; SSE-NEXT:    paddw %xmm1, %xmm0
474 ; SSE-NEXT:    psrlw $4, %xmm0
475 ; SSE-NEXT:    retq
477 ; AVX-LABEL: combine_vec_udiv_uniform:
478 ; AVX:       # %bb.0:
479 ; AVX-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm1
480 ; AVX-NEXT:    vpsubw %xmm1, %xmm0, %xmm0
481 ; AVX-NEXT:    vpsrlw $1, %xmm0, %xmm0
482 ; AVX-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
483 ; AVX-NEXT:    vpsrlw $4, %xmm0, %xmm0
484 ; AVX-NEXT:    retq
486 ; XOP-LABEL: combine_vec_udiv_uniform:
487 ; XOP:       # %bb.0:
488 ; XOP-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm1
489 ; XOP-NEXT:    vpsubw %xmm1, %xmm0, %xmm0
490 ; XOP-NEXT:    vpsrlw $1, %xmm0, %xmm0
491 ; XOP-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
492 ; XOP-NEXT:    vpsrlw $4, %xmm0, %xmm0
493 ; XOP-NEXT:    retq
494   %1 = udiv <8 x i16> %x, <i16 23, i16 23, i16 23, i16 23, i16 23, i16 23, i16 23, i16 23>
495   ret <8 x i16> %1
498 define <8 x i16> @combine_vec_udiv_nonuniform(<8 x i16> %x) {
499 ; SSE2-LABEL: combine_vec_udiv_nonuniform:
500 ; SSE2:       # %bb.0:
501 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [65535,65535,65535,0,65535,65535,65535,65535]
502 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
503 ; SSE2-NEXT:    pand %xmm2, %xmm1
504 ; SSE2-NEXT:    movdqa %xmm0, %xmm3
505 ; SSE2-NEXT:    psrlw $3, %xmm3
506 ; SSE2-NEXT:    pandn %xmm3, %xmm2
507 ; SSE2-NEXT:    por %xmm1, %xmm2
508 ; SSE2-NEXT:    pmulhuw {{.*}}(%rip), %xmm2
509 ; SSE2-NEXT:    psubw %xmm2, %xmm0
510 ; SSE2-NEXT:    movl $32768, %eax # imm = 0x8000
511 ; SSE2-NEXT:    movd %eax, %xmm1
512 ; SSE2-NEXT:    pmulhuw %xmm0, %xmm1
513 ; SSE2-NEXT:    paddw %xmm2, %xmm1
514 ; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [65535,65535,65535,0,0,65535,65535,0]
515 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
516 ; SSE2-NEXT:    pandn %xmm1, %xmm2
517 ; SSE2-NEXT:    pmulhuw {{.*}}(%rip), %xmm1
518 ; SSE2-NEXT:    pand %xmm0, %xmm1
519 ; SSE2-NEXT:    por %xmm2, %xmm1
520 ; SSE2-NEXT:    movdqa %xmm1, %xmm0
521 ; SSE2-NEXT:    retq
523 ; SSE41-LABEL: combine_vec_udiv_nonuniform:
524 ; SSE41:       # %bb.0:
525 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
526 ; SSE41-NEXT:    psrlw $3, %xmm1
527 ; SSE41-NEXT:    pblendw {{.*#+}} xmm1 = xmm0[0,1,2],xmm1[3],xmm0[4,5,6,7]
528 ; SSE41-NEXT:    pmulhuw {{.*}}(%rip), %xmm1
529 ; SSE41-NEXT:    psubw %xmm1, %xmm0
530 ; SSE41-NEXT:    movl $32768, %eax # imm = 0x8000
531 ; SSE41-NEXT:    movd %eax, %xmm2
532 ; SSE41-NEXT:    pmulhuw %xmm0, %xmm2
533 ; SSE41-NEXT:    paddw %xmm1, %xmm2
534 ; SSE41-NEXT:    movdqa {{.*#+}} xmm0 = <4096,2048,8,u,u,2,2,u>
535 ; SSE41-NEXT:    pmulhuw %xmm2, %xmm0
536 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2],xmm2[3,4],xmm0[5,6],xmm2[7]
537 ; SSE41-NEXT:    retq
539 ; AVX-LABEL: combine_vec_udiv_nonuniform:
540 ; AVX:       # %bb.0:
541 ; AVX-NEXT:    vpsrlw $3, %xmm0, %xmm1
542 ; AVX-NEXT:    vpblendw {{.*#+}} xmm1 = xmm0[0,1,2],xmm1[3],xmm0[4,5,6,7]
543 ; AVX-NEXT:    vpmulhuw {{.*}}(%rip), %xmm1, %xmm1
544 ; AVX-NEXT:    vpsubw %xmm1, %xmm0, %xmm0
545 ; AVX-NEXT:    movl $32768, %eax # imm = 0x8000
546 ; AVX-NEXT:    vmovd %eax, %xmm2
547 ; AVX-NEXT:    vpmulhuw %xmm2, %xmm0, %xmm0
548 ; AVX-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
549 ; AVX-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm1
550 ; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[3,4],xmm1[5,6],xmm0[7]
551 ; AVX-NEXT:    retq
553 ; XOP-LABEL: combine_vec_udiv_nonuniform:
554 ; XOP:       # %bb.0:
555 ; XOP-NEXT:    vpshlw {{.*}}(%rip), %xmm0, %xmm1
556 ; XOP-NEXT:    vpmulhuw {{.*}}(%rip), %xmm1, %xmm1
557 ; XOP-NEXT:    vpsubw %xmm1, %xmm0, %xmm0
558 ; XOP-NEXT:    movl $32768, %eax # imm = 0x8000
559 ; XOP-NEXT:    vmovd %eax, %xmm2
560 ; XOP-NEXT:    vpmulhuw %xmm2, %xmm0, %xmm0
561 ; XOP-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
562 ; XOP-NEXT:    vpshlw {{.*}}(%rip), %xmm0, %xmm0
563 ; XOP-NEXT:    retq
564   %1 = udiv <8 x i16> %x, <i16 23, i16 34, i16 -23, i16 56, i16 128, i16 -1, i16 -256, i16 -32768>
565   ret <8 x i16> %1
568 define <8 x i16> @combine_vec_udiv_nonuniform2(<8 x i16> %x) {
569 ; SSE2-LABEL: combine_vec_udiv_nonuniform2:
570 ; SSE2:       # %bb.0:
571 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [0,65535,65535,65535,65535,65535,65535,65535]
572 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
573 ; SSE2-NEXT:    pand %xmm2, %xmm1
574 ; SSE2-NEXT:    psrlw $1, %xmm0
575 ; SSE2-NEXT:    pandn %xmm0, %xmm2
576 ; SSE2-NEXT:    por %xmm2, %xmm1
577 ; SSE2-NEXT:    pmulhuw {{.*}}(%rip), %xmm1
578 ; SSE2-NEXT:    pmulhuw {{.*}}(%rip), %xmm1
579 ; SSE2-NEXT:    movdqa %xmm1, %xmm0
580 ; SSE2-NEXT:    retq
582 ; SSE41-LABEL: combine_vec_udiv_nonuniform2:
583 ; SSE41:       # %bb.0:
584 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
585 ; SSE41-NEXT:    psrlw $1, %xmm1
586 ; SSE41-NEXT:    pblendw {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3,4,5,6,7]
587 ; SSE41-NEXT:    pmulhuw {{.*}}(%rip), %xmm1
588 ; SSE41-NEXT:    pmulhuw {{.*}}(%rip), %xmm1
589 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
590 ; SSE41-NEXT:    retq
592 ; AVX-LABEL: combine_vec_udiv_nonuniform2:
593 ; AVX:       # %bb.0:
594 ; AVX-NEXT:    vpsrlw $1, %xmm0, %xmm1
595 ; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3,4,5,6,7]
596 ; AVX-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm0
597 ; AVX-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm0
598 ; AVX-NEXT:    retq
600 ; XOP-LABEL: combine_vec_udiv_nonuniform2:
601 ; XOP:       # %bb.0:
602 ; XOP-NEXT:    movl $65535, %eax # imm = 0xFFFF
603 ; XOP-NEXT:    vmovd %eax, %xmm1
604 ; XOP-NEXT:    vpshlw %xmm1, %xmm0, %xmm0
605 ; XOP-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm0
606 ; XOP-NEXT:    vpshlw {{.*}}(%rip), %xmm0, %xmm0
607 ; XOP-NEXT:    retq
608   %1 = udiv <8 x i16> %x, <i16 -34, i16 35, i16 36, i16 -37, i16 38, i16 -39, i16 40, i16 -41>
609   ret <8 x i16> %1
612 define <8 x i16> @combine_vec_udiv_nonuniform3(<8 x i16> %x) {
613 ; SSE-LABEL: combine_vec_udiv_nonuniform3:
614 ; SSE:       # %bb.0:
615 ; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [9363,25645,18351,12137,2115,23705,1041,517]
616 ; SSE-NEXT:    pmulhuw %xmm0, %xmm1
617 ; SSE-NEXT:    psubw %xmm1, %xmm0
618 ; SSE-NEXT:    psrlw $1, %xmm0
619 ; SSE-NEXT:    paddw %xmm1, %xmm0
620 ; SSE-NEXT:    pmulhuw {{.*}}(%rip), %xmm0
621 ; SSE-NEXT:    retq
623 ; AVX-LABEL: combine_vec_udiv_nonuniform3:
624 ; AVX:       # %bb.0:
625 ; AVX-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm1
626 ; AVX-NEXT:    vpsubw %xmm1, %xmm0, %xmm0
627 ; AVX-NEXT:    vpsrlw $1, %xmm0, %xmm0
628 ; AVX-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
629 ; AVX-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm0
630 ; AVX-NEXT:    retq
632 ; XOP-LABEL: combine_vec_udiv_nonuniform3:
633 ; XOP:       # %bb.0:
634 ; XOP-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm1
635 ; XOP-NEXT:    vpsubw %xmm1, %xmm0, %xmm0
636 ; XOP-NEXT:    vpsrlw $1, %xmm0, %xmm0
637 ; XOP-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
638 ; XOP-NEXT:    vpshlw {{.*}}(%rip), %xmm0, %xmm0
639 ; XOP-NEXT:    retq
640   %1 = udiv <8 x i16> %x, <i16 7, i16 23, i16 25, i16 27, i16 31, i16 47, i16 63, i16 127>
641   ret <8 x i16> %1
644 define <16 x i8> @combine_vec_udiv_nonuniform4(<16 x i8> %x) {
645 ; SSE2-LABEL: combine_vec_udiv_nonuniform4:
646 ; SSE2:       # %bb.0:
647 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
648 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
649 ; SSE2-NEXT:    pand %xmm2, %xmm1
650 ; SSE2-NEXT:    pxor %xmm3, %xmm3
651 ; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3],xmm0[4],xmm3[4],xmm0[5],xmm3[5],xmm0[6],xmm3[6],xmm0[7],xmm3[7]
652 ; SSE2-NEXT:    movl $171, %eax
653 ; SSE2-NEXT:    movd %eax, %xmm3
654 ; SSE2-NEXT:    pmullw %xmm0, %xmm3
655 ; SSE2-NEXT:    psrlw $8, %xmm3
656 ; SSE2-NEXT:    packuswb %xmm0, %xmm3
657 ; SSE2-NEXT:    psrlw $7, %xmm3
658 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm3
659 ; SSE2-NEXT:    pandn %xmm3, %xmm2
660 ; SSE2-NEXT:    por %xmm2, %xmm1
661 ; SSE2-NEXT:    movdqa %xmm1, %xmm0
662 ; SSE2-NEXT:    retq
664 ; SSE41-LABEL: combine_vec_udiv_nonuniform4:
665 ; SSE41:       # %bb.0:
666 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
667 ; SSE41-NEXT:    movl $171, %eax
668 ; SSE41-NEXT:    movd %eax, %xmm0
669 ; SSE41-NEXT:    pmovzxbw {{.*#+}} xmm2 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero
670 ; SSE41-NEXT:    pmullw %xmm0, %xmm2
671 ; SSE41-NEXT:    psrlw $8, %xmm2
672 ; SSE41-NEXT:    packuswb %xmm0, %xmm2
673 ; SSE41-NEXT:    psrlw $7, %xmm2
674 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm2
675 ; SSE41-NEXT:    movaps {{.*#+}} xmm0 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
676 ; SSE41-NEXT:    pblendvb %xmm0, %xmm1, %xmm2
677 ; SSE41-NEXT:    movdqa %xmm2, %xmm0
678 ; SSE41-NEXT:    retq
680 ; AVX-LABEL: combine_vec_udiv_nonuniform4:
681 ; AVX:       # %bb.0:
682 ; AVX-NEXT:    movl $171, %eax
683 ; AVX-NEXT:    vmovd %eax, %xmm1
684 ; AVX-NEXT:    vpmovzxbw {{.*#+}} xmm2 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
685 ; AVX-NEXT:    vpmullw %xmm1, %xmm2, %xmm1
686 ; AVX-NEXT:    vpsrlw $8, %xmm1, %xmm1
687 ; AVX-NEXT:    vpackuswb %xmm0, %xmm1, %xmm1
688 ; AVX-NEXT:    vpsrlw $7, %xmm1, %xmm1
689 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
690 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
691 ; AVX-NEXT:    vpblendvb %xmm2, %xmm0, %xmm1, %xmm0
692 ; AVX-NEXT:    retq
694 ; XOP-LABEL: combine_vec_udiv_nonuniform4:
695 ; XOP:       # %bb.0:
696 ; XOP-NEXT:    movl $171, %eax
697 ; XOP-NEXT:    vmovd %eax, %xmm1
698 ; XOP-NEXT:    vpmovzxbw {{.*#+}} xmm2 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
699 ; XOP-NEXT:    vpmullw %xmm1, %xmm2, %xmm1
700 ; XOP-NEXT:    vpxor %xmm2, %xmm2, %xmm2
701 ; XOP-NEXT:    vpperm {{.*#+}} xmm1 = xmm1[1,3,5,7,9,11,13,15],xmm2[1,3,5,7,9,11,13,15]
702 ; XOP-NEXT:    movl $249, %eax
703 ; XOP-NEXT:    vmovd %eax, %xmm2
704 ; XOP-NEXT:    vpshlb %xmm2, %xmm1, %xmm1
705 ; XOP-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
706 ; XOP-NEXT:    vpblendvb %xmm2, %xmm0, %xmm1, %xmm0
707 ; XOP-NEXT:    retq
708   %div = udiv <16 x i8> %x, <i8 -64, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
709   ret <16 x i8> %div
712 define <8 x i16> @pr38477(<8 x i16> %a0) {
713 ; SSE2-LABEL: pr38477:
714 ; SSE2:       # %bb.0:
715 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [0,4957,57457,4103,16385,35545,2048,2115]
716 ; SSE2-NEXT:    pmulhuw %xmm0, %xmm2
717 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
718 ; SSE2-NEXT:    psubw %xmm2, %xmm1
719 ; SSE2-NEXT:    pmulhuw {{.*}}(%rip), %xmm1
720 ; SSE2-NEXT:    paddw %xmm2, %xmm1
721 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [65535,65535,65535,65535,65535,65535,0,65535]
722 ; SSE2-NEXT:    movdqa %xmm2, %xmm3
723 ; SSE2-NEXT:    pandn %xmm1, %xmm3
724 ; SSE2-NEXT:    pmulhuw {{.*}}(%rip), %xmm1
725 ; SSE2-NEXT:    pand %xmm2, %xmm1
726 ; SSE2-NEXT:    por %xmm3, %xmm1
727 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [0,65535,65535,65535,65535,65535,65535,65535]
728 ; SSE2-NEXT:    pand %xmm2, %xmm1
729 ; SSE2-NEXT:    pandn %xmm0, %xmm2
730 ; SSE2-NEXT:    por %xmm2, %xmm1
731 ; SSE2-NEXT:    movdqa %xmm1, %xmm0
732 ; SSE2-NEXT:    retq
734 ; SSE41-LABEL: pr38477:
735 ; SSE41:       # %bb.0:
736 ; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = [0,4957,57457,4103,16385,35545,2048,2115]
737 ; SSE41-NEXT:    pmulhuw %xmm0, %xmm2
738 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
739 ; SSE41-NEXT:    psubw %xmm2, %xmm1
740 ; SSE41-NEXT:    pmulhuw {{.*}}(%rip), %xmm1
741 ; SSE41-NEXT:    paddw %xmm2, %xmm1
742 ; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = <u,1024,1024,16,4,1024,u,4096>
743 ; SSE41-NEXT:    pmulhuw %xmm1, %xmm2
744 ; SSE41-NEXT:    pblendw {{.*#+}} xmm1 = xmm2[0,1,2,3,4,5],xmm1[6],xmm2[7]
745 ; SSE41-NEXT:    pblendw {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3,4,5,6,7]
746 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
747 ; SSE41-NEXT:    retq
749 ; AVX-LABEL: pr38477:
750 ; AVX:       # %bb.0:
751 ; AVX-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm1
752 ; AVX-NEXT:    vpsubw %xmm1, %xmm0, %xmm2
753 ; AVX-NEXT:    vpmulhuw {{.*}}(%rip), %xmm2, %xmm2
754 ; AVX-NEXT:    vpaddw %xmm1, %xmm2, %xmm1
755 ; AVX-NEXT:    vpmulhuw {{.*}}(%rip), %xmm1, %xmm2
756 ; AVX-NEXT:    vpblendw {{.*#+}} xmm1 = xmm2[0,1,2,3,4,5],xmm1[6],xmm2[7]
757 ; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3,4,5,6,7]
758 ; AVX-NEXT:    retq
760 ; XOP-LABEL: pr38477:
761 ; XOP:       # %bb.0:
762 ; XOP-NEXT:    vpmulhuw {{.*}}(%rip), %xmm0, %xmm1
763 ; XOP-NEXT:    vpsubw %xmm1, %xmm0, %xmm2
764 ; XOP-NEXT:    vpmulhuw {{.*}}(%rip), %xmm2, %xmm2
765 ; XOP-NEXT:    vpaddw %xmm1, %xmm2, %xmm1
766 ; XOP-NEXT:    vpshlw {{.*}}(%rip), %xmm1, %xmm1
767 ; XOP-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3,4,5,6,7]
768 ; XOP-NEXT:    retq
769   %1 = udiv <8 x i16> %a0, <i16 1, i16 119, i16 73, i16 -111, i16 -3, i16 118, i16 32, i16 31>
770   ret <8 x i16> %1
773 define i1 @bool_udiv(i1 %x, i1 %y) {
774 ; CHECK-LABEL: bool_udiv:
775 ; CHECK:       # %bb.0:
776 ; CHECK-NEXT:    movl %edi, %eax
777 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
778 ; CHECK-NEXT:    retq
779   %r = udiv i1 %x, %y
780   ret i1 %r
783 define <4 x i1> @boolvec_udiv(<4 x i1> %x, <4 x i1> %y) {
784 ; CHECK-LABEL: boolvec_udiv:
785 ; CHECK:       # %bb.0:
786 ; CHECK-NEXT:    retq
787   %r = udiv <4 x i1> %x, %y
788   ret <4 x i1> %r