[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / InstSimplify / signed-div-rem.ll
blob5e8388ae3ba5b7cebf09b2cd7ca65062c9ac935e
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
9   ret i32 %div
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
20   ret i32 %div
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
29   ret i32 %div
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
40   ret i32 %div
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
49   ret i32 %div
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
60   ret i32 %div
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
69   ret i32 %div
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
80   ret i32 %div
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
89   ret i32 %div
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
100   ret i32 %div
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
109   ret i32 %div
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
120   ret i32 %div
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
129   ret i32 %div
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
140   ret i32 %div
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
149   ret i32 %div
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
160   ret i32 %div
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
170   ret i32 %rem
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
181   ret i32 %rem
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
191   ret i32 %rem
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
202   ret i32 %rem
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
212   ret i32 %rem
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
223   ret i32 %rem
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
233   ret i32 %rem
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
244   ret i32 %rem
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
254   ret i32 %rem
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
265   ret i32 %rem
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
275   ret i32 %rem
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
286   ret i32 %rem
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
296   ret i32 %rem
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
307   ret i32 %rem
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
317   ret i32 %rem
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
328   ret i32 %rem
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
341   ret i16 %d
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
352   ret i16 %d