1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 define i32 @sdiv_sext_big_divisor(i8 %x) {
5 ; CHECK-LABEL: @sdiv_sext_big_divisor(
6 ; CHECK-NEXT: ret i32 0
8 %conv = sext i8 %x to i32
9 %div = sdiv i32 %conv, 129
13 define 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]]
19 %conv = sext i8 %x to i32
20 %div = sdiv i32 %conv, 128
24 define i32 @sdiv_sext_small_divisor(i8 %x) {
25 ; CHECK-LABEL: @sdiv_sext_small_divisor(
26 ; CHECK-NEXT: ret i32 0
28 %conv = sext i8 %x to i32
29 %div = sdiv i32 %conv, -129
33 define 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]]
39 %conv = sext i8 %x to i32
40 %div = sdiv i32 %conv, -128
44 define i32 @sdiv_zext_big_divisor(i8 %x) {
45 ; CHECK-LABEL: @sdiv_zext_big_divisor(
46 ; CHECK-NEXT: ret i32 0
48 %conv = zext i8 %x to i32
49 %div = sdiv i32 %conv, 256
53 define 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]]
59 %conv = zext i8 %x to i32
60 %div = sdiv i32 %conv, 255
64 define i32 @sdiv_zext_small_divisor(i8 %x) {
65 ; CHECK-LABEL: @sdiv_zext_small_divisor(
66 ; CHECK-NEXT: ret i32 0
68 %conv = zext i8 %x to i32
69 %div = sdiv i32 %conv, -256
73 define 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]]
79 %conv = zext i8 %x to i32
80 %div = sdiv i32 %conv, -255
84 define 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
88 %and = and i32 %x, 253
89 %div = sdiv i32 %and, 254
93 define 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]]
99 %and = and i32 %x, 253
100 %div = sdiv i32 %and, 253
104 define 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
108 %and = and i32 %x, 253
109 %div = sdiv i32 %and, -254
113 define 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]]
119 %and = and i32 %x, 253
120 %div = sdiv i32 %and, -253
124 define 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
128 %or = or i32 %x, -253
129 %div = sdiv i32 %or, 254
133 define 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]]
139 %or = or i32 %x, -253
140 %div = sdiv i32 %or, 253
144 define 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
148 %or = or i32 %x, -253
149 %div = sdiv i32 %or, -254
153 define 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]]
159 %or = or i32 %x, -253
160 %div = sdiv i32 %or, -253
164 define 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]]
169 %conv = sext i8 %x to i32
170 %rem = srem i32 %conv, 129
174 define 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]]
180 %conv = sext i8 %x to i32
181 %rem = srem i32 %conv, 128
185 define 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]]
190 %conv = sext i8 %x to i32
191 %rem = srem i32 %conv, -129
195 define 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]]
201 %conv = sext i8 %x to i32
202 %rem = srem i32 %conv, -128
206 define 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]]
211 %conv = zext i8 %x to i32
212 %rem = srem i32 %conv, 256
216 define 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]]
222 %conv = zext i8 %x to i32
223 %rem = srem i32 %conv, 255
227 define 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]]
232 %conv = zext i8 %x to i32
233 %rem = srem i32 %conv, -256
237 define 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]]
243 %conv = zext i8 %x to i32
244 %rem = srem i32 %conv, -255
248 define 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]]
253 %and = and i32 %x, 253
254 %rem = srem i32 %and, 254
258 define 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]]
264 %and = and i32 %x, 253
265 %rem = srem i32 %and, 253
269 define 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]]
274 %and = and i32 %x, 253
275 %rem = srem i32 %and, -254
279 define 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]]
285 %and = and i32 %x, 253
286 %rem = srem i32 %and, -253
290 define 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]]
295 %or = or i32 %x, -253
296 %rem = srem i32 %or, 254
300 define 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]]
306 %or = or i32 %x, -253
307 %rem = srem i32 %or, 253
311 define 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]]
316 %or = or i32 %x, -253
317 %rem = srem i32 %or, -254
321 define 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]]
327 %or = or i32 %x, -253
328 %rem = srem i32 %or, -253
332 ; Make sure that we're handling the minimum signed constant correctly - can't fold this.
334 define 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]]
340 %z = zext i8 %x to i16
341 %d = sdiv i16 -32768, %z
345 ; If the quotient is known to not be -32768, then this can fold.
347 define i16 @sdiv_min_divisor(i8 %x) {
348 ; CHECK-LABEL: @sdiv_min_divisor(
349 ; CHECK-NEXT: ret i16 0
351 %z = zext i8 %x to i16
352 %d = sdiv i16 %z, -32768