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