• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx  | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX1
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX2
5
6; fold (srem x, 1) -> 0
7define i32 @combine_srem_by_one(i32 %x) {
8; CHECK-LABEL: combine_srem_by_one:
9; CHECK:       # %bb.0:
10; CHECK-NEXT:    xorl %eax, %eax
11; CHECK-NEXT:    retq
12  %1 = srem i32 %x, 1
13  ret i32 %1
14}
15
16define <4 x i32> @combine_vec_srem_by_one(<4 x i32> %x) {
17; SSE-LABEL: combine_vec_srem_by_one:
18; SSE:       # %bb.0:
19; SSE-NEXT:    xorps %xmm0, %xmm0
20; SSE-NEXT:    retq
21;
22; AVX-LABEL: combine_vec_srem_by_one:
23; AVX:       # %bb.0:
24; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
25; AVX-NEXT:    retq
26  %1 = srem <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1>
27  ret <4 x i32> %1
28}
29
30; fold (srem x, -1) -> 0
31define i32 @combine_srem_by_negone(i32 %x) {
32; CHECK-LABEL: combine_srem_by_negone:
33; CHECK:       # %bb.0:
34; CHECK-NEXT:    xorl %eax, %eax
35; CHECK-NEXT:    retq
36  %1 = srem i32 %x, -1
37  ret i32 %1
38}
39
40define <4 x i32> @combine_vec_srem_by_negone(<4 x i32> %x) {
41; SSE-LABEL: combine_vec_srem_by_negone:
42; SSE:       # %bb.0:
43; SSE-NEXT:    xorps %xmm0, %xmm0
44; SSE-NEXT:    retq
45;
46; AVX-LABEL: combine_vec_srem_by_negone:
47; AVX:       # %bb.0:
48; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
49; AVX-NEXT:    retq
50  %1 = srem <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
51  ret <4 x i32> %1
52}
53
54; TODO fold (srem x, INT_MIN)
55define i32 @combine_srem_by_minsigned(i32 %x) {
56; CHECK-LABEL: combine_srem_by_minsigned:
57; CHECK:       # %bb.0:
58; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
59; CHECK-NEXT:    leal 2147483647(%rdi), %eax
60; CHECK-NEXT:    testl %edi, %edi
61; CHECK-NEXT:    cmovnsl %edi, %eax
62; CHECK-NEXT:    andl $-2147483648, %eax # imm = 0x80000000
63; CHECK-NEXT:    addl %edi, %eax
64; CHECK-NEXT:    retq
65  %1 = srem i32 %x, -2147483648
66  ret i32 %1
67}
68
69define <4 x i32> @combine_vec_srem_by_minsigned(<4 x i32> %x) {
70; SSE-LABEL: combine_vec_srem_by_minsigned:
71; SSE:       # %bb.0:
72; SSE-NEXT:    movdqa %xmm0, %xmm1
73; SSE-NEXT:    psrad $31, %xmm1
74; SSE-NEXT:    psrld $1, %xmm1
75; SSE-NEXT:    paddd %xmm0, %xmm1
76; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
77; SSE-NEXT:    psubd %xmm1, %xmm0
78; SSE-NEXT:    retq
79;
80; AVX1-LABEL: combine_vec_srem_by_minsigned:
81; AVX1:       # %bb.0:
82; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm1
83; AVX1-NEXT:    vpsrld $1, %xmm1, %xmm1
84; AVX1-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
85; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
86; AVX1-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
87; AVX1-NEXT:    retq
88;
89; AVX2-LABEL: combine_vec_srem_by_minsigned:
90; AVX2:       # %bb.0:
91; AVX2-NEXT:    vpsrad $31, %xmm0, %xmm1
92; AVX2-NEXT:    vpsrld $1, %xmm1, %xmm1
93; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
94; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
95; AVX2-NEXT:    vpand %xmm2, %xmm1, %xmm1
96; AVX2-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
97; AVX2-NEXT:    retq
98  %1 = srem <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
99  ret <4 x i32> %1
100}
101
102; fold (srem 0, x) -> 0
103define i32 @combine_srem_zero(i32 %x) {
104; CHECK-LABEL: combine_srem_zero:
105; CHECK:       # %bb.0:
106; CHECK-NEXT:    xorl %eax, %eax
107; CHECK-NEXT:    retq
108  %1 = srem i32 0, %x
109  ret i32 %1
110}
111
112define <4 x i32> @combine_vec_srem_zero(<4 x i32> %x) {
113; SSE-LABEL: combine_vec_srem_zero:
114; SSE:       # %bb.0:
115; SSE-NEXT:    xorps %xmm0, %xmm0
116; SSE-NEXT:    retq
117;
118; AVX-LABEL: combine_vec_srem_zero:
119; AVX:       # %bb.0:
120; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
121; AVX-NEXT:    retq
122  %1 = srem <4 x i32> zeroinitializer, %x
123  ret <4 x i32> %1
124}
125
126; fold (srem x, x) -> 0
127define i32 @combine_srem_dupe(i32 %x) {
128; CHECK-LABEL: combine_srem_dupe:
129; CHECK:       # %bb.0:
130; CHECK-NEXT:    xorl %eax, %eax
131; CHECK-NEXT:    retq
132  %1 = srem i32 %x, %x
133  ret i32 %1
134}
135
136define <4 x i32> @combine_vec_srem_dupe(<4 x i32> %x) {
137; SSE-LABEL: combine_vec_srem_dupe:
138; SSE:       # %bb.0:
139; SSE-NEXT:    xorps %xmm0, %xmm0
140; SSE-NEXT:    retq
141;
142; AVX-LABEL: combine_vec_srem_dupe:
143; AVX:       # %bb.0:
144; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
145; AVX-NEXT:    retq
146  %1 = srem <4 x i32> %x, %x
147  ret <4 x i32> %1
148}
149
150; fold (srem x, y) -> (urem x, y) iff x and y are positive
151define <4 x i32> @combine_vec_srem_by_pos0(<4 x i32> %x) {
152; SSE-LABEL: combine_vec_srem_by_pos0:
153; SSE:       # %bb.0:
154; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
155; SSE-NEXT:    retq
156;
157; AVX1-LABEL: combine_vec_srem_by_pos0:
158; AVX1:       # %bb.0:
159; AVX1-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
160; AVX1-NEXT:    retq
161;
162; AVX2-LABEL: combine_vec_srem_by_pos0:
163; AVX2:       # %bb.0:
164; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [3,3,3,3]
165; AVX2-NEXT:    vandps %xmm1, %xmm0, %xmm0
166; AVX2-NEXT:    retq
167  %1 = and <4 x i32> %x, <i32 255, i32 255, i32 255, i32 255>
168  %2 = srem <4 x i32> %1, <i32 4, i32 4, i32 4, i32 4>
169  ret <4 x i32> %2
170}
171
172define <4 x i32> @combine_vec_srem_by_pos1(<4 x i32> %x) {
173; SSE-LABEL: combine_vec_srem_by_pos1:
174; SSE:       # %bb.0:
175; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
176; SSE-NEXT:    retq
177;
178; AVX-LABEL: combine_vec_srem_by_pos1:
179; AVX:       # %bb.0:
180; AVX-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
181; AVX-NEXT:    retq
182  %1 = and <4 x i32> %x, <i32 255, i32 255, i32 255, i32 255>
183  %2 = srem <4 x i32> %1, <i32 1, i32 4, i32 8, i32 16>
184  ret <4 x i32> %2
185}
186
187; fold (srem x, (1 << c)) -> x - (x / (1 << c)) * (1 << c).
188define <4 x i32> @combine_vec_srem_by_pow2a(<4 x i32> %x) {
189; SSE-LABEL: combine_vec_srem_by_pow2a:
190; SSE:       # %bb.0:
191; SSE-NEXT:    movdqa %xmm0, %xmm1
192; SSE-NEXT:    psrad $31, %xmm1
193; SSE-NEXT:    psrld $30, %xmm1
194; SSE-NEXT:    paddd %xmm0, %xmm1
195; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
196; SSE-NEXT:    psubd %xmm1, %xmm0
197; SSE-NEXT:    retq
198;
199; AVX1-LABEL: combine_vec_srem_by_pow2a:
200; AVX1:       # %bb.0:
201; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm1
202; AVX1-NEXT:    vpsrld $30, %xmm1, %xmm1
203; AVX1-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
204; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
205; AVX1-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
206; AVX1-NEXT:    retq
207;
208; AVX2-LABEL: combine_vec_srem_by_pow2a:
209; AVX2:       # %bb.0:
210; AVX2-NEXT:    vpsrad $31, %xmm0, %xmm1
211; AVX2-NEXT:    vpsrld $30, %xmm1, %xmm1
212; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
213; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [4294967292,4294967292,4294967292,4294967292]
214; AVX2-NEXT:    vpand %xmm2, %xmm1, %xmm1
215; AVX2-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
216; AVX2-NEXT:    retq
217  %1 = srem <4 x i32> %x, <i32 4, i32 4, i32 4, i32 4>
218  ret <4 x i32> %1
219}
220
221define <4 x i32> @combine_vec_srem_by_pow2a_neg(<4 x i32> %x) {
222; SSE-LABEL: combine_vec_srem_by_pow2a_neg:
223; SSE:       # %bb.0:
224; SSE-NEXT:    movdqa %xmm0, %xmm1
225; SSE-NEXT:    psrad $31, %xmm1
226; SSE-NEXT:    psrld $30, %xmm1
227; SSE-NEXT:    paddd %xmm0, %xmm1
228; SSE-NEXT:    psrld $2, %xmm1
229; SSE-NEXT:    pxor %xmm2, %xmm2
230; SSE-NEXT:    psubd %xmm1, %xmm2
231; SSE-NEXT:    pslld $2, %xmm2
232; SSE-NEXT:    paddd %xmm2, %xmm0
233; SSE-NEXT:    retq
234;
235; AVX-LABEL: combine_vec_srem_by_pow2a_neg:
236; AVX:       # %bb.0:
237; AVX-NEXT:    vpsrad $31, %xmm0, %xmm1
238; AVX-NEXT:    vpsrld $30, %xmm1, %xmm1
239; AVX-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
240; AVX-NEXT:    vpsrld $2, %xmm1, %xmm1
241; AVX-NEXT:    vpxor %xmm2, %xmm2, %xmm2
242; AVX-NEXT:    vpsubd %xmm1, %xmm2, %xmm1
243; AVX-NEXT:    vpslld $2, %xmm1, %xmm1
244; AVX-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
245; AVX-NEXT:    retq
246  %1 = srem <4 x i32> %x, <i32 -4, i32 -4, i32 -4, i32 -4>
247  ret <4 x i32> %1
248}
249
250define <4 x i32> @combine_vec_srem_by_pow2b(<4 x i32> %x) {
251; SSE-LABEL: combine_vec_srem_by_pow2b:
252; SSE:       # %bb.0:
253; SSE-NEXT:    movdqa %xmm0, %xmm1
254; SSE-NEXT:    psrad $31, %xmm1
255; SSE-NEXT:    movdqa %xmm1, %xmm2
256; SSE-NEXT:    psrld $29, %xmm2
257; SSE-NEXT:    movdqa %xmm1, %xmm3
258; SSE-NEXT:    psrld $31, %xmm3
259; SSE-NEXT:    pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7]
260; SSE-NEXT:    psrld $30, %xmm1
261; SSE-NEXT:    pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7]
262; SSE-NEXT:    paddd %xmm0, %xmm1
263; SSE-NEXT:    movdqa %xmm1, %xmm2
264; SSE-NEXT:    psrad $3, %xmm2
265; SSE-NEXT:    movdqa %xmm1, %xmm3
266; SSE-NEXT:    psrad $1, %xmm3
267; SSE-NEXT:    pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7]
268; SSE-NEXT:    psrad $2, %xmm1
269; SSE-NEXT:    pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7]
270; SSE-NEXT:    pblendw {{.*#+}} xmm1 = xmm0[0,1],xmm1[2,3,4,5,6,7]
271; SSE-NEXT:    pmulld {{.*}}(%rip), %xmm1
272; SSE-NEXT:    psubd %xmm1, %xmm0
273; SSE-NEXT:    retq
274;
275; AVX1-LABEL: combine_vec_srem_by_pow2b:
276; AVX1:       # %bb.0:
277; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm1
278; AVX1-NEXT:    vpsrld $29, %xmm1, %xmm2
279; AVX1-NEXT:    vpsrld $31, %xmm1, %xmm3
280; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
281; AVX1-NEXT:    vpsrld $30, %xmm1, %xmm1
282; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7]
283; AVX1-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
284; AVX1-NEXT:    vpsrad $3, %xmm1, %xmm2
285; AVX1-NEXT:    vpsrad $1, %xmm1, %xmm3
286; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
287; AVX1-NEXT:    vpsrad $2, %xmm1, %xmm1
288; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7]
289; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm0[0,1],xmm1[2,3,4,5,6,7]
290; AVX1-NEXT:    vpmulld {{.*}}(%rip), %xmm1, %xmm1
291; AVX1-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
292; AVX1-NEXT:    retq
293;
294; AVX2-LABEL: combine_vec_srem_by_pow2b:
295; AVX2:       # %bb.0:
296; AVX2-NEXT:    vpsrad $31, %xmm0, %xmm1
297; AVX2-NEXT:    vpsrlvd {{.*}}(%rip), %xmm1, %xmm1
298; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
299; AVX2-NEXT:    vmovdqa {{.*#+}} xmm2 = [0,1,2,3]
300; AVX2-NEXT:    vpsravd %xmm2, %xmm1, %xmm1
301; AVX2-NEXT:    vpblendd {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]
302; AVX2-NEXT:    vpsllvd %xmm2, %xmm1, %xmm1
303; AVX2-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
304; AVX2-NEXT:    retq
305  %1 = srem <4 x i32> %x, <i32 1, i32 2, i32 4, i32 8>
306  ret <4 x i32> %1
307}
308
309define <4 x i32> @combine_vec_srem_by_pow2b_neg(<4 x i32> %x) {
310; SSE-LABEL: combine_vec_srem_by_pow2b_neg:
311; SSE:       # %bb.0:
312; SSE-NEXT:    movdqa %xmm0, %xmm1
313; SSE-NEXT:    psrad $31, %xmm1
314; SSE-NEXT:    movdqa %xmm1, %xmm2
315; SSE-NEXT:    psrld $28, %xmm2
316; SSE-NEXT:    movdqa %xmm1, %xmm3
317; SSE-NEXT:    psrld $30, %xmm3
318; SSE-NEXT:    pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7]
319; SSE-NEXT:    movdqa %xmm1, %xmm2
320; SSE-NEXT:    psrld $29, %xmm2
321; SSE-NEXT:    psrld $31, %xmm1
322; SSE-NEXT:    pblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm2[4,5,6,7]
323; SSE-NEXT:    pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7]
324; SSE-NEXT:    paddd %xmm0, %xmm1
325; SSE-NEXT:    movdqa %xmm1, %xmm2
326; SSE-NEXT:    psrad $4, %xmm2
327; SSE-NEXT:    movdqa %xmm1, %xmm3
328; SSE-NEXT:    psrad $2, %xmm3
329; SSE-NEXT:    pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7]
330; SSE-NEXT:    movdqa %xmm1, %xmm2
331; SSE-NEXT:    psrad $3, %xmm2
332; SSE-NEXT:    psrad $1, %xmm1
333; SSE-NEXT:    pblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm2[4,5,6,7]
334; SSE-NEXT:    pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7]
335; SSE-NEXT:    pmulld {{.*}}(%rip), %xmm1
336; SSE-NEXT:    paddd %xmm0, %xmm1
337; SSE-NEXT:    movdqa %xmm1, %xmm0
338; SSE-NEXT:    retq
339;
340; AVX1-LABEL: combine_vec_srem_by_pow2b_neg:
341; AVX1:       # %bb.0:
342; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm1
343; AVX1-NEXT:    vpsrld $28, %xmm1, %xmm2
344; AVX1-NEXT:    vpsrld $30, %xmm1, %xmm3
345; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
346; AVX1-NEXT:    vpsrld $29, %xmm1, %xmm3
347; AVX1-NEXT:    vpsrld $31, %xmm1, %xmm1
348; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm3[4,5,6,7]
349; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7]
350; AVX1-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
351; AVX1-NEXT:    vpsrad $4, %xmm1, %xmm2
352; AVX1-NEXT:    vpsrad $2, %xmm1, %xmm3
353; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
354; AVX1-NEXT:    vpsrad $3, %xmm1, %xmm3
355; AVX1-NEXT:    vpsrad $1, %xmm1, %xmm1
356; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm3[4,5,6,7]
357; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7]
358; AVX1-NEXT:    vpmulld {{.*}}(%rip), %xmm1, %xmm1
359; AVX1-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
360; AVX1-NEXT:    retq
361;
362; AVX2-LABEL: combine_vec_srem_by_pow2b_neg:
363; AVX2:       # %bb.0:
364; AVX2-NEXT:    vpsrad $31, %xmm0, %xmm1
365; AVX2-NEXT:    vpsrlvd {{.*}}(%rip), %xmm1, %xmm1
366; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm1
367; AVX2-NEXT:    vpsravd {{.*}}(%rip), %xmm1, %xmm1
368; AVX2-NEXT:    vpmulld {{.*}}(%rip), %xmm1, %xmm1
369; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
370; AVX2-NEXT:    retq
371  %1 = srem <4 x i32> %x, <i32 -2, i32 -4, i32 -8, i32 -16>
372  ret <4 x i32> %1
373}
374
375; OSS-Fuzz #6883
376; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6883
377define i32 @ossfuzz6883() {
378; CHECK-LABEL: ossfuzz6883:
379; CHECK:       # %bb.0:
380; CHECK-NEXT:    movl (%rax), %ecx
381; CHECK-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
382; CHECK-NEXT:    xorl %edx, %edx
383; CHECK-NEXT:    idivl %ecx
384; CHECK-NEXT:    movl %eax, %esi
385; CHECK-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
386; CHECK-NEXT:    xorl %edx, %edx
387; CHECK-NEXT:    divl %ecx
388; CHECK-NEXT:    movl %eax, %edi
389; CHECK-NEXT:    movl %esi, %eax
390; CHECK-NEXT:    cltd
391; CHECK-NEXT:    idivl %edi
392; CHECK-NEXT:    movl %edx, %esi
393; CHECK-NEXT:    movl %ecx, %eax
394; CHECK-NEXT:    cltd
395; CHECK-NEXT:    idivl %esi
396; CHECK-NEXT:    movl %edx, %edi
397; CHECK-NEXT:    movl %ecx, %eax
398; CHECK-NEXT:    xorl %edx, %edx
399; CHECK-NEXT:    divl %esi
400; CHECK-NEXT:    andl %edi, %eax
401; CHECK-NEXT:    retq
402  %B17 = or i32 0, 2147483647
403  %L6 = load i32, i32* undef
404  %B11 = sdiv i32 %B17, %L6
405  %B13 = udiv i32 %B17, %L6
406  %B14 = srem i32 %B11, %B13
407  %B16 = srem i32 %L6, %B14
408  %B10 = udiv i32 %L6, %B14
409  %B6 = and i32 %B16, %B10
410  ret i32 %B6
411}
412
413define i1 @bool_srem(i1 %x, i1 %y) {
414; CHECK-LABEL: bool_srem:
415; CHECK:       # %bb.0:
416; CHECK-NEXT:    xorl %eax, %eax
417; CHECK-NEXT:    retq
418  %r = srem i1 %x, %y
419  ret i1 %r
420}
421define <4 x i1> @boolvec_srem(<4 x i1> %x, <4 x i1> %y) {
422; SSE-LABEL: boolvec_srem:
423; SSE:       # %bb.0:
424; SSE-NEXT:    xorps %xmm0, %xmm0
425; SSE-NEXT:    retq
426;
427; AVX-LABEL: boolvec_srem:
428; AVX:       # %bb.0:
429; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
430; AVX-NEXT:    retq
431  %r = srem <4 x i1> %x, %y
432  ret <4 x i1> %r
433}
434
435define i32 @combine_srem_two(i32 %x) {
436; CHECK-LABEL: combine_srem_two:
437; CHECK:       # %bb.0:
438; CHECK-NEXT:    movl %edi, %eax
439; CHECK-NEXT:    movl %edi, %ecx
440; CHECK-NEXT:    shrl $31, %ecx
441; CHECK-NEXT:    addl %edi, %ecx
442; CHECK-NEXT:    andl $-2, %ecx
443; CHECK-NEXT:    subl %ecx, %eax
444; CHECK-NEXT:    retq
445  %1 = srem i32 %x, 2
446  ret i32 %1
447}
448
449define i32 @combine_srem_negtwo(i32 %x) {
450; CHECK-LABEL: combine_srem_negtwo:
451; CHECK:       # %bb.0:
452; CHECK-NEXT:    movl %edi, %eax
453; CHECK-NEXT:    movl %edi, %ecx
454; CHECK-NEXT:    shrl $31, %ecx
455; CHECK-NEXT:    addl %edi, %ecx
456; CHECK-NEXT:    andl $-2, %ecx
457; CHECK-NEXT:    subl %ecx, %eax
458; CHECK-NEXT:    retq
459  %1 = srem i32 %x, -2
460  ret i32 %1
461}
462
463define i8 @combine_i8_srem_negpow2(i8 %x) {
464; CHECK-LABEL: combine_i8_srem_negpow2:
465; CHECK:       # %bb.0:
466; CHECK-NEXT:    movl %edi, %eax
467; CHECK-NEXT:    movl %eax, %ecx
468; CHECK-NEXT:    sarb $7, %cl
469; CHECK-NEXT:    shrb $2, %cl
470; CHECK-NEXT:    addb %al, %cl
471; CHECK-NEXT:    andb $-64, %cl
472; CHECK-NEXT:    subb %cl, %al
473; CHECK-NEXT:    # kill: def $al killed $al killed $eax
474; CHECK-NEXT:    retq
475  %1 = srem i8 %x, -64
476  ret i8 %1
477}
478
479define i16 @combine_i16_srem_pow2(i16 %x) {
480; CHECK-LABEL: combine_i16_srem_pow2:
481; CHECK:       # %bb.0:
482; CHECK-NEXT:    movl %edi, %eax
483; CHECK-NEXT:    leal 15(%rax), %ecx
484; CHECK-NEXT:    testw %ax, %ax
485; CHECK-NEXT:    cmovnsl %edi, %ecx
486; CHECK-NEXT:    andl $-16, %ecx
487; CHECK-NEXT:    subl %ecx, %eax
488; CHECK-NEXT:    # kill: def $ax killed $ax killed $rax
489; CHECK-NEXT:    retq
490  %1 = srem i16 %x, 16
491  ret i16 %1
492}
493
494define i16 @combine_i16_srem_negpow2(i16 %x) {
495; CHECK-LABEL: combine_i16_srem_negpow2:
496; CHECK:       # %bb.0:
497; CHECK-NEXT:    movl %edi, %eax
498; CHECK-NEXT:    leal 255(%rax), %ecx
499; CHECK-NEXT:    testw %ax, %ax
500; CHECK-NEXT:    cmovnsl %edi, %ecx
501; CHECK-NEXT:    andl $-256, %ecx
502; CHECK-NEXT:    subl %ecx, %eax
503; CHECK-NEXT:    # kill: def $ax killed $ax killed $rax
504; CHECK-NEXT:    retq
505  %1 = srem i16 %x, -256
506  ret i16 %1
507}
508
509define i32 @combine_srem_pow2(i32 %x) {
510; CHECK-LABEL: combine_srem_pow2:
511; CHECK:       # %bb.0:
512; CHECK-NEXT:    movl %edi, %eax
513; CHECK-NEXT:    leal 15(%rax), %ecx
514; CHECK-NEXT:    testl %edi, %edi
515; CHECK-NEXT:    cmovnsl %edi, %ecx
516; CHECK-NEXT:    andl $-16, %ecx
517; CHECK-NEXT:    subl %ecx, %eax
518; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
519; CHECK-NEXT:    retq
520  %1 = srem i32 %x, 16
521  ret i32 %1
522}
523
524define i32 @combine_srem_negpow2(i32 %x) {
525; CHECK-LABEL: combine_srem_negpow2:
526; CHECK:       # %bb.0:
527; CHECK-NEXT:    movl %edi, %eax
528; CHECK-NEXT:    leal 255(%rax), %ecx
529; CHECK-NEXT:    testl %edi, %edi
530; CHECK-NEXT:    cmovnsl %edi, %ecx
531; CHECK-NEXT:    andl $-256, %ecx
532; CHECK-NEXT:    subl %ecx, %eax
533; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
534; CHECK-NEXT:    retq
535  %1 = srem i32 %x, -256
536  ret i32 %1
537}
538
539define i64 @combine_i64_srem_pow2(i64 %x) {
540; CHECK-LABEL: combine_i64_srem_pow2:
541; CHECK:       # %bb.0:
542; CHECK-NEXT:    movq %rdi, %rax
543; CHECK-NEXT:    leaq 15(%rdi), %rcx
544; CHECK-NEXT:    testq %rdi, %rdi
545; CHECK-NEXT:    cmovnsq %rdi, %rcx
546; CHECK-NEXT:    andq $-16, %rcx
547; CHECK-NEXT:    subq %rcx, %rax
548; CHECK-NEXT:    retq
549  %1 = srem i64 %x, 16
550  ret i64 %1
551}
552
553define i64 @combine_i64_srem_negpow2(i64 %x) {
554; CHECK-LABEL: combine_i64_srem_negpow2:
555; CHECK:       # %bb.0:
556; CHECK-NEXT:    movq %rdi, %rax
557; CHECK-NEXT:    leaq 255(%rdi), %rcx
558; CHECK-NEXT:    testq %rdi, %rdi
559; CHECK-NEXT:    cmovnsq %rdi, %rcx
560; CHECK-NEXT:    andq $-256, %rcx
561; CHECK-NEXT:    subq %rcx, %rax
562; CHECK-NEXT:    retq
563  %1 = srem i64 %x, -256
564  ret i64 %1
565}
566