1; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
2
3define i32 @sdiv_sext_big_divisor(i8 %x) {
4; CHECK-LABEL: @sdiv_sext_big_divisor(
5; CHECK-NEXT:    ret i32 0
6;
7  %conv = sext i8 %x to i32
8  %div = sdiv i32 %conv, 129
9  ret i32 %div
10}
11
12define i32 @not_sdiv_sext_big_divisor(i8 %x) {
13; CHECK-LABEL: @not_sdiv_sext_big_divisor(
14; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
15; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], 128
16; CHECK-NEXT:    ret i32 [[DIV]]
17;
18  %conv = sext i8 %x to i32
19  %div = sdiv i32 %conv, 128
20  ret i32 %div
21}
22
23define i32 @sdiv_sext_small_divisor(i8 %x) {
24; CHECK-LABEL: @sdiv_sext_small_divisor(
25; CHECK-NEXT:    ret i32 0
26;
27  %conv = sext i8 %x to i32
28  %div = sdiv i32 %conv, -129
29  ret i32 %div
30}
31
32define i32 @not_sdiv_sext_small_divisor(i8 %x) {
33; CHECK-LABEL: @not_sdiv_sext_small_divisor(
34; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
35; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], -128
36; CHECK-NEXT:    ret i32 [[DIV]]
37;
38  %conv = sext i8 %x to i32
39  %div = sdiv i32 %conv, -128
40  ret i32 %div
41}
42
43define i32 @sdiv_zext_big_divisor(i8 %x) {
44; CHECK-LABEL: @sdiv_zext_big_divisor(
45; CHECK-NEXT:    ret i32 0
46;
47  %conv = zext i8 %x to i32
48  %div = sdiv i32 %conv, 256
49  ret i32 %div
50}
51
52define i32 @not_sdiv_zext_big_divisor(i8 %x) {
53; CHECK-LABEL: @not_sdiv_zext_big_divisor(
54; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
55; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], 255
56; CHECK-NEXT:    ret i32 [[DIV]]
57;
58  %conv = zext i8 %x to i32
59  %div = sdiv i32 %conv, 255
60  ret i32 %div
61}
62
63define i32 @sdiv_zext_small_divisor(i8 %x) {
64; CHECK-LABEL: @sdiv_zext_small_divisor(
65; CHECK-NEXT:    ret i32 0
66;
67  %conv = zext i8 %x to i32
68  %div = sdiv i32 %conv, -256
69  ret i32 %div
70}
71
72define i32 @not_sdiv_zext_small_divisor(i8 %x) {
73; CHECK-LABEL: @not_sdiv_zext_small_divisor(
74; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
75; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], -255
76; CHECK-NEXT:    ret i32 [[DIV]]
77;
78  %conv = zext i8 %x to i32
79  %div = sdiv i32 %conv, -255
80  ret i32 %div
81}
82
83define i32 @sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
84; CHECK-LABEL: @sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(
85; CHECK-NEXT:    ret i32 0
86;
87  %and = and i32 %x, 253
88  %div = sdiv i32 %and, 254
89  ret i32 %div
90}
91
92define i32 @not_sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
93; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(
94; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
95; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[AND]], 253
96; CHECK-NEXT:    ret i32 [[DIV]]
97;
98  %and = and i32 %x, 253
99  %div = sdiv i32 %and, 253
100  ret i32 %div
101}
102
103define i32 @sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
104; CHECK-LABEL: @sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(
105; CHECK-NEXT:    ret i32 0
106;
107  %and = and i32 %x, 253
108  %div = sdiv i32 %and, -254
109  ret i32 %div
110}
111
112define i32 @not_sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
113; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(
114; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
115; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[AND]], -253
116; CHECK-NEXT:    ret i32 [[DIV]]
117;
118  %and = and i32 %x, 253
119  %div = sdiv i32 %and, -253
120  ret i32 %div
121}
122
123define i32 @sdiv_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) {
124; CHECK-LABEL: @sdiv_dividend_known_smaller_than_pos_divisor_set_bits(
125; CHECK-NEXT:    ret i32 0
126;
127  %or = or i32 %x, -253
128  %div = sdiv i32 %or, 254
129  ret i32 %div
130}
131
132define i32 @not_sdiv_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) {
133; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_pos_divisor_set_bits(
134; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
135; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[OR]], 253
136; CHECK-NEXT:    ret i32 [[DIV]]
137;
138  %or = or i32 %x, -253
139  %div = sdiv i32 %or, 253
140  ret i32 %div
141}
142
143define i32 @sdiv_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) {
144; CHECK-LABEL: @sdiv_dividend_known_smaller_than_neg_divisor_set_bits(
145; CHECK-NEXT:    ret i32 0
146;
147  %or = or i32 %x, -253
148  %div = sdiv i32 %or, -254
149  ret i32 %div
150}
151
152define i32 @not_sdiv_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) {
153; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_neg_divisor_set_bits(
154; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
155; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[OR]], -253
156; CHECK-NEXT:    ret i32 [[DIV]]
157;
158  %or = or i32 %x, -253
159  %div = sdiv i32 %or, -253
160  ret i32 %div
161}
162
163define i32 @srem_sext_big_divisor(i8 %x) {
164; CHECK-LABEL: @srem_sext_big_divisor(
165; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
166; CHECK-NEXT:    ret i32 [[CONV]]
167;
168  %conv = sext i8 %x to i32
169  %rem = srem i32 %conv, 129
170  ret i32 %rem
171}
172
173define i32 @not_srem_sext_big_divisor(i8 %x) {
174; CHECK-LABEL: @not_srem_sext_big_divisor(
175; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
176; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], 128
177; CHECK-NEXT:    ret i32 [[REM]]
178;
179  %conv = sext i8 %x to i32
180  %rem = srem i32 %conv, 128
181  ret i32 %rem
182}
183
184define i32 @srem_sext_small_divisor(i8 %x) {
185; CHECK-LABEL: @srem_sext_small_divisor(
186; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
187; CHECK-NEXT:    ret i32 [[CONV]]
188;
189  %conv = sext i8 %x to i32
190  %rem = srem i32 %conv, -129
191  ret i32 %rem
192}
193
194define i32 @not_srem_sext_small_divisor(i8 %x) {
195; CHECK-LABEL: @not_srem_sext_small_divisor(
196; CHECK-NEXT:    [[CONV:%.*]] = sext i8 %x to i32
197; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], -128
198; CHECK-NEXT:    ret i32 [[REM]]
199;
200  %conv = sext i8 %x to i32
201  %rem = srem i32 %conv, -128
202  ret i32 %rem
203}
204
205define i32 @srem_zext_big_divisor(i8 %x) {
206; CHECK-LABEL: @srem_zext_big_divisor(
207; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
208; CHECK-NEXT:    ret i32 [[CONV]]
209;
210  %conv = zext i8 %x to i32
211  %rem = srem i32 %conv, 256
212  ret i32 %rem
213}
214
215define i32 @not_srem_zext_big_divisor(i8 %x) {
216; CHECK-LABEL: @not_srem_zext_big_divisor(
217; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
218; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], 255
219; CHECK-NEXT:    ret i32 [[REM]]
220;
221  %conv = zext i8 %x to i32
222  %rem = srem i32 %conv, 255
223  ret i32 %rem
224}
225
226define i32 @srem_zext_small_divisor(i8 %x) {
227; CHECK-LABEL: @srem_zext_small_divisor(
228; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
229; CHECK-NEXT:    ret i32 [[CONV]]
230;
231  %conv = zext i8 %x to i32
232  %rem = srem i32 %conv, -256
233  ret i32 %rem
234}
235
236define i32 @not_srem_zext_small_divisor(i8 %x) {
237; CHECK-LABEL: @not_srem_zext_small_divisor(
238; CHECK-NEXT:    [[CONV:%.*]] = zext i8 %x to i32
239; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[CONV]], -255
240; CHECK-NEXT:    ret i32 [[REM]]
241;
242  %conv = zext i8 %x to i32
243  %rem = srem i32 %conv, -255
244  ret i32 %rem
245}
246
247define i32 @srem_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
248; CHECK-LABEL: @srem_dividend_known_smaller_than_pos_divisor_clear_bits(
249; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
250; CHECK-NEXT:    ret i32 [[AND]]
251;
252  %and = and i32 %x, 253
253  %rem = srem i32 %and, 254
254  ret i32 %rem
255}
256
257define i32 @not_srem_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
258; CHECK-LABEL: @not_srem_dividend_known_smaller_than_pos_divisor_clear_bits(
259; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
260; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[AND]], 253
261; CHECK-NEXT:    ret i32 [[REM]]
262;
263  %and = and i32 %x, 253
264  %rem = srem i32 %and, 253
265  ret i32 %rem
266}
267
268define i32 @srem_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
269; CHECK-LABEL: @srem_dividend_known_smaller_than_neg_divisor_clear_bits(
270; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
271; CHECK-NEXT:    ret i32 [[AND]]
272;
273  %and = and i32 %x, 253
274  %rem = srem i32 %and, -254
275  ret i32 %rem
276}
277
278define i32 @not_srem_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
279; CHECK-LABEL: @not_srem_dividend_known_smaller_than_neg_divisor_clear_bits(
280; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 253
281; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[AND]], -253
282; CHECK-NEXT:    ret i32 [[REM]]
283;
284  %and = and i32 %x, 253
285  %rem = srem i32 %and, -253
286  ret i32 %rem
287}
288
289define i32 @srem_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) {
290; CHECK-LABEL: @srem_dividend_known_smaller_than_pos_divisor_set_bits(
291; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
292; CHECK-NEXT:    ret i32 [[OR]]
293;
294  %or = or i32 %x, -253
295  %rem = srem i32 %or, 254
296  ret i32 %rem
297}
298
299define i32 @not_srem_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) {
300; CHECK-LABEL: @not_srem_dividend_known_smaller_than_pos_divisor_set_bits(
301; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
302; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[OR]], 253
303; CHECK-NEXT:    ret i32 [[REM]]
304;
305  %or = or i32 %x, -253
306  %rem = srem i32 %or, 253
307  ret i32 %rem
308}
309
310define i32 @srem_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) {
311; CHECK-LABEL: @srem_dividend_known_smaller_than_neg_divisor_set_bits(
312; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
313; CHECK-NEXT:    ret i32 [[OR]]
314;
315  %or = or i32 %x, -253
316  %rem = srem i32 %or, -254
317  ret i32 %rem
318}
319
320define i32 @not_srem_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) {
321; CHECK-LABEL: @not_srem_dividend_known_smaller_than_neg_divisor_set_bits(
322; CHECK-NEXT:    [[OR:%.*]] = or i32 %x, -253
323; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[OR]], -253
324; CHECK-NEXT:    ret i32 [[REM]]
325;
326  %or = or i32 %x, -253
327  %rem = srem i32 %or, -253
328  ret i32 %rem
329}
330
331; Make sure that we're handling the minimum signed constant correctly - can't fold this.
332
333define i16 @sdiv_min_dividend(i8 %x) {
334; CHECK-LABEL: @sdiv_min_dividend(
335; CHECK-NEXT:    [[Z:%.*]] = zext i8 %x to i16
336; CHECK-NEXT:    [[D:%.*]] = sdiv i16 -32768, [[Z]]
337; CHECK-NEXT:    ret i16 [[D]]
338;
339  %z = zext i8 %x to i16
340  %d = sdiv i16 -32768, %z
341  ret i16 %d
342}
343
344; If the quotient is known to not be -32768, then this can fold.
345
346define i16 @sdiv_min_divisor(i8 %x) {
347; CHECK-LABEL: @sdiv_min_divisor(
348; CHECK-NEXT:    ret i16 0
349;
350  %z = zext i8 %x to i16
351  %d = sdiv i16 %z, -32768
352  ret i16 %d
353}
354
355