Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / InstSimplify / signed-div-rem.ll
blobb2316e846b08dbd8b8b963e31e0deb19a05fe997
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
10   ret i32 %div
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
21   ret i32 %div
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
30   ret i32 %div
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
41   ret i32 %div
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
50   ret i32 %div
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
61   ret i32 %div
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
70   ret i32 %div
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
81   ret i32 %div
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
90   ret i32 %div
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
101   ret i32 %div
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
110   ret i32 %div
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
121   ret i32 %div
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
130   ret i32 %div
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
141   ret i32 %div
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
150   ret i32 %div
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
161   ret i32 %div
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
171   ret i32 %rem
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
182   ret i32 %rem
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
192   ret i32 %rem
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
203   ret i32 %rem
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
213   ret i32 %rem
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
224   ret i32 %rem
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
234   ret i32 %rem
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
245   ret i32 %rem
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
255   ret i32 %rem
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
266   ret i32 %rem
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
276   ret i32 %rem
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
287   ret i32 %rem
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
297   ret i32 %rem
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
308   ret i32 %rem
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
318   ret i32 %rem
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
329   ret i32 %rem
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
342   ret i16 %d
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
353   ret i16 %d