1 ; RUN: opt < %s -instsimplify -S | FileCheck %s
3 define i32 @sdiv_sext_big_divisor(i8 %x) {
4 ; CHECK-LABEL: @sdiv_sext_big_divisor(
5 ; CHECK-NEXT: ret i32 0
7 %conv = sext i8 %x to i32
8 %div = sdiv i32 %conv, 129
12 define 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]]
18 %conv = sext i8 %x to i32
19 %div = sdiv i32 %conv, 128
23 define i32 @sdiv_sext_small_divisor(i8 %x) {
24 ; CHECK-LABEL: @sdiv_sext_small_divisor(
25 ; CHECK-NEXT: ret i32 0
27 %conv = sext i8 %x to i32
28 %div = sdiv i32 %conv, -129
32 define 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]]
38 %conv = sext i8 %x to i32
39 %div = sdiv i32 %conv, -128
43 define i32 @sdiv_zext_big_divisor(i8 %x) {
44 ; CHECK-LABEL: @sdiv_zext_big_divisor(
45 ; CHECK-NEXT: ret i32 0
47 %conv = zext i8 %x to i32
48 %div = sdiv i32 %conv, 256
52 define 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]]
58 %conv = zext i8 %x to i32
59 %div = sdiv i32 %conv, 255
63 define i32 @sdiv_zext_small_divisor(i8 %x) {
64 ; CHECK-LABEL: @sdiv_zext_small_divisor(
65 ; CHECK-NEXT: ret i32 0
67 %conv = zext i8 %x to i32
68 %div = sdiv i32 %conv, -256
72 define 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]]
78 %conv = zext i8 %x to i32
79 %div = sdiv i32 %conv, -255
83 define 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
87 %and = and i32 %x, 253
88 %div = sdiv i32 %and, 254
92 define 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]]
98 %and = and i32 %x, 253
99 %div = sdiv i32 %and, 253
103 define 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
107 %and = and i32 %x, 253
108 %div = sdiv i32 %and, -254
112 define 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]]
118 %and = and i32 %x, 253
119 %div = sdiv i32 %and, -253
123 define 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
127 %or = or i32 %x, -253
128 %div = sdiv i32 %or, 254
132 define 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]]
138 %or = or i32 %x, -253
139 %div = sdiv i32 %or, 253
143 define 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
147 %or = or i32 %x, -253
148 %div = sdiv i32 %or, -254
152 define 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]]
158 %or = or i32 %x, -253
159 %div = sdiv i32 %or, -253
163 define 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]]
168 %conv = sext i8 %x to i32
169 %rem = srem i32 %conv, 129
173 define 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]]
179 %conv = sext i8 %x to i32
180 %rem = srem i32 %conv, 128
184 define 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]]
189 %conv = sext i8 %x to i32
190 %rem = srem i32 %conv, -129
194 define 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]]
200 %conv = sext i8 %x to i32
201 %rem = srem i32 %conv, -128
205 define 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]]
210 %conv = zext i8 %x to i32
211 %rem = srem i32 %conv, 256
215 define 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]]
221 %conv = zext i8 %x to i32
222 %rem = srem i32 %conv, 255
226 define 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]]
231 %conv = zext i8 %x to i32
232 %rem = srem i32 %conv, -256
236 define 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]]
242 %conv = zext i8 %x to i32
243 %rem = srem i32 %conv, -255
247 define 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]]
252 %and = and i32 %x, 253
253 %rem = srem i32 %and, 254
257 define 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]]
263 %and = and i32 %x, 253
264 %rem = srem i32 %and, 253
268 define 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]]
273 %and = and i32 %x, 253
274 %rem = srem i32 %and, -254
278 define 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]]
284 %and = and i32 %x, 253
285 %rem = srem i32 %and, -253
289 define 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]]
294 %or = or i32 %x, -253
295 %rem = srem i32 %or, 254
299 define 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]]
305 %or = or i32 %x, -253
306 %rem = srem i32 %or, 253
310 define 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]]
315 %or = or i32 %x, -253
316 %rem = srem i32 %or, -254
320 define 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]]
326 %or = or i32 %x, -253
327 %rem = srem i32 %or, -253
331 ; Make sure that we're handling the minimum signed constant correctly - can't fold this.
333 define 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]]
339 %z = zext i8 %x to i16
340 %d = sdiv i16 -32768, %z
344 ; If the quotient is known to not be -32768, then this can fold.
346 define i16 @sdiv_min_divisor(i8 %x) {
347 ; CHECK-LABEL: @sdiv_min_divisor(
348 ; CHECK-NEXT: ret i16 0
350 %z = zext i8 %x to i16
351 %d = sdiv i16 %z, -32768