[mlir][scf]: Add value bound between scf for loop yield and result (#123200)
[llvm-project.git] / llvm / test / Transforms / InstCombine / 2004-11-27-SetCCForCastLargerAndConstant.ll
blob7689fc9f6824143a14515968c4592bdeb499b118
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; This tests the InstructionCombining optimization that reduces things like:
5 ;   %Y = sext i8 %X to i32
6 ;   %C = icmp ult i32 %Y, 1024
7 ; to
8 ;   %C = i1 true
9 ; It includes test cases for different constant values, signedness of the
10 ; cast operands, and types of setCC operators. In all cases, the cast should
11 ; be eliminated. In many cases the setCC is also eliminated based on the
12 ; constant value and the range of the casted value.
15 define i1 @lt_signed_to_large_unsigned(i8 %SB) {
16 ; CHECK-LABEL: @lt_signed_to_large_unsigned(
17 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[SB:%.*]], -1
18 ; CHECK-NEXT:    ret i1 [[C]]
20   %Y = sext i8 %SB to i32
21   %C = icmp ult i32 %Y, 1024
22   ret i1 %C
25 ; PR28011 - https://llvm.org/bugs/show_bug.cgi?id=28011
26 ; The above transform only applies to scalar integers; it shouldn't be attempted for constant expressions or vectors.
28 @a = common global ptr null
29 @b = common global [1 x i32] zeroinitializer
31 define i1 @PR28011(i16 %a) {
32 ; CHECK-LABEL: @PR28011(
33 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i16 [[A:%.*]], 1
34 ; CHECK-NEXT:    ret i1 [[CMP]]
36   %conv = sext i16 %a to i32
37   %cmp2 = icmp ne ptr @b, @a
38   %ext = zext i1 %cmp2 to i32
39   %or = or i32 %ext, 1
40   %cmp = icmp ne i32 %conv, %or
41   ret i1 %cmp
44 define <2 x i1> @lt_signed_to_large_unsigned_vec(<2 x i8> %SB) {
45 ; CHECK-LABEL: @lt_signed_to_large_unsigned_vec(
46 ; CHECK-NEXT:    [[Y:%.*]] = sext <2 x i8> [[SB:%.*]] to <2 x i32>
47 ; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> [[Y]], <i32 1024, i32 2>
48 ; CHECK-NEXT:    ret <2 x i1> [[C]]
50   %Y = sext <2 x i8> %SB to <2 x i32>
51   %C = icmp ult <2 x i32> %Y, <i32 1024, i32 2>
52   ret <2 x i1> %C
55 define i1 @lt_signed_to_large_signed(i8 %SB) {
56 ; CHECK-LABEL: @lt_signed_to_large_signed(
57 ; CHECK-NEXT:    ret i1 true
59   %Y = sext i8 %SB to i32
60   %C = icmp slt i32 %Y, 1024
61   ret i1 %C
64 define i1 @lt_signed_to_large_negative(i8 %SB) {
65 ; CHECK-LABEL: @lt_signed_to_large_negative(
66 ; CHECK-NEXT:    ret i1 false
68   %Y = sext i8 %SB to i32
69   %C = icmp slt i32 %Y, -1024
70   ret i1 %C
73 define i1 @lt_signed_to_small_unsigned(i8 %SB) {
74 ; CHECK-LABEL: @lt_signed_to_small_unsigned(
75 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[SB:%.*]], 17
76 ; CHECK-NEXT:    ret i1 [[C]]
78   %Y = sext i8 %SB to i32
79   %C = icmp ult i32 %Y, 17
80   ret i1 %C
83 define i1 @lt_signed_to_small_signed(i8 %SB) {
84 ; CHECK-LABEL: @lt_signed_to_small_signed(
85 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[SB:%.*]], 17
86 ; CHECK-NEXT:    ret i1 [[C]]
88   %Y = sext i8 %SB to i32
89   %C = icmp slt i32 %Y, 17
90   ret i1 %C
92 define i1 @lt_signed_to_small_negative(i8 %SB) {
93 ; CHECK-LABEL: @lt_signed_to_small_negative(
94 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[SB:%.*]], -17
95 ; CHECK-NEXT:    ret i1 [[C]]
97   %Y = sext i8 %SB to i32
98   %C = icmp slt i32 %Y, -17
99   ret i1 %C
102 define i1 @lt_unsigned_to_large_unsigned(i8 %SB) {
103 ; CHECK-LABEL: @lt_unsigned_to_large_unsigned(
104 ; CHECK-NEXT:    ret i1 true
106   %Y = zext i8 %SB to i32
107   %C = icmp ult i32 %Y, 1024
108   ret i1 %C
111 define i1 @lt_unsigned_to_large_signed(i8 %SB) {
112 ; CHECK-LABEL: @lt_unsigned_to_large_signed(
113 ; CHECK-NEXT:    ret i1 true
115   %Y = zext i8 %SB to i32
116   %C = icmp slt i32 %Y, 1024
117   ret i1 %C
120 define i1 @lt_unsigned_to_large_negative(i8 %SB) {
121 ; CHECK-LABEL: @lt_unsigned_to_large_negative(
122 ; CHECK-NEXT:    ret i1 false
124   %Y = zext i8 %SB to i32
125   %C = icmp slt i32 %Y, -1024
126   ret i1 %C
129 define i1 @lt_unsigned_to_small_unsigned(i8 %SB) {
130 ; CHECK-LABEL: @lt_unsigned_to_small_unsigned(
131 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[SB:%.*]], 17
132 ; CHECK-NEXT:    ret i1 [[C]]
134   %Y = zext i8 %SB to i32
135   %C = icmp ult i32 %Y, 17
136   ret i1 %C
139 define i1 @lt_unsigned_to_small_signed(i8 %SB) {
140 ; CHECK-LABEL: @lt_unsigned_to_small_signed(
141 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[SB:%.*]], 17
142 ; CHECK-NEXT:    ret i1 [[C]]
144   %Y = zext i8 %SB to i32
145   %C = icmp slt i32 %Y, 17
146   ret i1 %C
149 define i1 @lt_unsigned_to_small_negative(i8 %SB) {
150 ; CHECK-LABEL: @lt_unsigned_to_small_negative(
151 ; CHECK-NEXT:    ret i1 false
153   %Y = zext i8 %SB to i32
154   %C = icmp slt i32 %Y, -17
155   ret i1 %C
158 define i1 @gt_signed_to_large_unsigned(i8 %SB) {
159 ; CHECK-LABEL: @gt_signed_to_large_unsigned(
160 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[SB:%.*]], 0
161 ; CHECK-NEXT:    ret i1 [[C]]
163   %Y = sext i8 %SB to i32
164   %C = icmp ugt i32 %Y, 1024
165   ret i1 %C
168 define i1 @gt_signed_to_large_signed(i8 %SB) {
169 ; CHECK-LABEL: @gt_signed_to_large_signed(
170 ; CHECK-NEXT:    ret i1 false
172   %Y = sext i8 %SB to i32
173   %C = icmp sgt i32 %Y, 1024
174   ret i1 %C
177 define i1 @gt_signed_to_large_negative(i8 %SB) {
178 ; CHECK-LABEL: @gt_signed_to_large_negative(
179 ; CHECK-NEXT:    ret i1 true
181   %Y = sext i8 %SB to i32
182   %C = icmp sgt i32 %Y, -1024
183   ret i1 %C
186 define i1 @gt_signed_to_small_unsigned(i8 %SB) {
187 ; CHECK-LABEL: @gt_signed_to_small_unsigned(
188 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[SB:%.*]], 17
189 ; CHECK-NEXT:    ret i1 [[C]]
191   %Y = sext i8 %SB to i32
192   %C = icmp ugt i32 %Y, 17
193   ret i1 %C
196 define i1 @gt_signed_to_small_signed(i8 %SB) {
197 ; CHECK-LABEL: @gt_signed_to_small_signed(
198 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[SB:%.*]], 17
199 ; CHECK-NEXT:    ret i1 [[C]]
201   %Y = sext i8 %SB to i32
202   %C = icmp sgt i32 %Y, 17
203   ret i1 %C
206 define i1 @gt_signed_to_small_negative(i8 %SB) {
207 ; CHECK-LABEL: @gt_signed_to_small_negative(
208 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[SB:%.*]], -17
209 ; CHECK-NEXT:    ret i1 [[C]]
211   %Y = sext i8 %SB to i32
212   %C = icmp sgt i32 %Y, -17
213   ret i1 %C
216 define i1 @gt_unsigned_to_large_unsigned(i8 %SB) {
217 ; CHECK-LABEL: @gt_unsigned_to_large_unsigned(
218 ; CHECK-NEXT:    ret i1 false
220   %Y = zext i8 %SB to i32
221   %C = icmp ugt i32 %Y, 1024
222   ret i1 %C
225 define i1 @gt_unsigned_to_large_signed(i8 %SB) {
226 ; CHECK-LABEL: @gt_unsigned_to_large_signed(
227 ; CHECK-NEXT:    ret i1 false
229   %Y = zext i8 %SB to i32
230   %C = icmp sgt i32 %Y, 1024
231   ret i1 %C
234 define i1 @gt_unsigned_to_large_negative(i8 %SB) {
235 ; CHECK-LABEL: @gt_unsigned_to_large_negative(
236 ; CHECK-NEXT:    ret i1 true
238   %Y = zext i8 %SB to i32
239   %C = icmp sgt i32 %Y, -1024
240   ret i1 %C
243 define i1 @gt_unsigned_to_small_unsigned(i8 %SB) {
244 ; CHECK-LABEL: @gt_unsigned_to_small_unsigned(
245 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[SB:%.*]], 17
246 ; CHECK-NEXT:    ret i1 [[C]]
248   %Y = zext i8 %SB to i32
249   %C = icmp ugt i32 %Y, 17
250   ret i1 %C
253 define i1 @gt_unsigned_to_small_signed(i8 %SB) {
254 ; CHECK-LABEL: @gt_unsigned_to_small_signed(
255 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[SB:%.*]], 17
256 ; CHECK-NEXT:    ret i1 [[C]]
258   %Y = zext i8 %SB to i32
259   %C = icmp sgt i32 %Y, 17
260   ret i1 %C
263 define i1 @gt_unsigned_to_small_negative(i8 %SB) {
264 ; CHECK-LABEL: @gt_unsigned_to_small_negative(
265 ; CHECK-NEXT:    ret i1 true
267   %Y = zext i8 %SB to i32
268   %C = icmp sgt i32 %Y, -17
269   ret i1 %C
272 define i1 @different_size_zext_zext_ugt(i7 %x, i4 %y) {
273 ; CHECK-LABEL: @different_size_zext_zext_ugt(
274 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[Y:%.*]] to i7
275 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i7 [[X:%.*]], [[TMP1]]
276 ; CHECK-NEXT:    ret i1 [[R]]
278   %zx = zext i7 %x to i25
279   %zy = zext i4 %y to i25
280   %r = icmp ugt i25 %zx, %zy
281   ret i1 %r
284 define <2 x i1> @different_size_zext_zext_ugt_commute(<2 x i4> %x, <2 x i7> %y) {
285 ; CHECK-LABEL: @different_size_zext_zext_ugt_commute(
286 ; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i4> [[X:%.*]] to <2 x i7>
287 ; CHECK-NEXT:    [[R:%.*]] = icmp ult <2 x i7> [[Y:%.*]], [[TMP1]]
288 ; CHECK-NEXT:    ret <2 x i1> [[R]]
290   %zx = zext <2 x i4> %x to <2 x i25>
291   %zy = zext <2 x i7> %y to <2 x i25>
292   %r = icmp ugt <2 x i25> %zx, %zy
293   ret <2 x i1> %r
296 define i1 @different_size_zext_zext_ult(i4 %x, i7 %y) {
297 ; CHECK-LABEL: @different_size_zext_zext_ult(
298 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[X:%.*]] to i7
299 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i7 [[Y:%.*]], [[TMP1]]
300 ; CHECK-NEXT:    ret i1 [[R]]
302   %zx = zext i4 %x to i25
303   %zy = zext i7 %y to i25
304   %r = icmp ult i25 %zx, %zy
305   ret i1 %r
308 define i1 @different_size_zext_zext_eq(i4 %x, i7 %y) {
309 ; CHECK-LABEL: @different_size_zext_zext_eq(
310 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[X:%.*]] to i7
311 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i7 [[Y:%.*]], [[TMP1]]
312 ; CHECK-NEXT:    ret i1 [[R]]
314   %zx = zext i4 %x to i25
315   %zy = zext i7 %y to i25
316   %r = icmp eq i25 %zx, %zy
317   ret i1 %r
320 define i1 @different_size_zext_zext_ne_commute(i7 %x, i4 %y) {
321 ; CHECK-LABEL: @different_size_zext_zext_ne_commute(
322 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[Y:%.*]] to i7
323 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i7 [[X:%.*]], [[TMP1]]
324 ; CHECK-NEXT:    ret i1 [[R]]
326   %zx = zext i7 %x to i25
327   %zy = zext i4 %y to i25
328   %r = icmp ne i25 %zx, %zy
329   ret i1 %r
332 define i1 @different_size_zext_zext_slt(i7 %x, i4 %y) {
333 ; CHECK-LABEL: @different_size_zext_zext_slt(
334 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[Y:%.*]] to i7
335 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i7 [[X:%.*]], [[TMP1]]
336 ; CHECK-NEXT:    ret i1 [[R]]
338   %zx = zext i7 %x to i25
339   %zy = zext i4 %y to i25
340   %r = icmp slt i25 %zx, %zy
341   ret i1 %r
344 define i1 @different_size_zext_zext_sgt(i7 %x, i4 %y) {
345 ; CHECK-LABEL: @different_size_zext_zext_sgt(
346 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[Y:%.*]] to i7
347 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i7 [[X:%.*]], [[TMP1]]
348 ; CHECK-NEXT:    ret i1 [[R]]
350   %zx = zext i7 %x to i25
351   %zy = zext i4 %y to i25
352   %r = icmp sgt i25 %zx, %zy
353   ret i1 %r
356 define i1 @different_size_sext_sext_sgt(i7 %x, i4 %y) {
357 ; CHECK-LABEL: @different_size_sext_sext_sgt(
358 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7
359 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i7 [[X:%.*]], [[TMP1]]
360 ; CHECK-NEXT:    ret i1 [[R]]
362   %sx = sext i7 %x to i25
363   %sy = sext i4 %y to i25
364   %r = icmp sgt i25 %sx, %sy
365   ret i1 %r
368 define i1 @different_size_sext_sext_sle(i7 %x, i4 %y) {
369 ; CHECK-LABEL: @different_size_sext_sext_sle(
370 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7
371 ; CHECK-NEXT:    [[R:%.*]] = icmp sle i7 [[X:%.*]], [[TMP1]]
372 ; CHECK-NEXT:    ret i1 [[R]]
374   %sx = sext i7 %x to i25
375   %sy = sext i4 %y to i25
376   %r = icmp sle i25 %sx, %sy
377   ret i1 %r
380 define i1 @different_size_sext_sext_eq(i7 %x, i4 %y) {
381 ; CHECK-LABEL: @different_size_sext_sext_eq(
382 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7
383 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i7 [[X:%.*]], [[TMP1]]
384 ; CHECK-NEXT:    ret i1 [[R]]
386   %sx = sext i7 %x to i25
387   %sy = sext i4 %y to i25
388   %r = icmp eq i25 %sx, %sy
389   ret i1 %r
392 define i1 @different_size_sext_sext_ule(i7 %x, i4 %y) {
393 ; CHECK-LABEL: @different_size_sext_sext_ule(
394 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7
395 ; CHECK-NEXT:    [[R:%.*]] = icmp ule i7 [[X:%.*]], [[TMP1]]
396 ; CHECK-NEXT:    ret i1 [[R]]
398   %sx = sext i7 %x to i25
399   %sy = sext i4 %y to i25
400   %r = icmp ule i25 %sx, %sy
401   ret i1 %r
404 ; TODO: This can be reduced.
406 define i1 @different_size_sext_zext_ne(i7 %x, i4 %y) {
407 ; CHECK-LABEL: @different_size_sext_zext_ne(
408 ; CHECK-NEXT:    [[SX:%.*]] = sext i7 [[X:%.*]] to i25
409 ; CHECK-NEXT:    [[ZY:%.*]] = zext i4 [[Y:%.*]] to i25
410 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i25 [[SX]], [[ZY]]
411 ; CHECK-NEXT:    ret i1 [[R]]
413   %sx = sext i7 %x to i25
414   %zy = zext i4 %y to i25
415   %r = icmp ne i25 %sx, %zy
416   ret i1 %r
419 declare void @use(i25)
421 define i1 @different_size_sext_sext_ule_extra_use1(i7 %x, i4 %y) {
422 ; CHECK-LABEL: @different_size_sext_sext_ule_extra_use1(
423 ; CHECK-NEXT:    [[SY:%.*]] = sext i4 [[Y:%.*]] to i25
424 ; CHECK-NEXT:    call void @use(i25 [[SY]])
425 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y]] to i7
426 ; CHECK-NEXT:    [[R:%.*]] = icmp ule i7 [[X:%.*]], [[TMP1]]
427 ; CHECK-NEXT:    ret i1 [[R]]
429   %sx = sext i7 %x to i25
430   %sy = sext i4 %y to i25
431   call void @use(i25 %sy)
432   %r = icmp ule i25 %sx, %sy
433   ret i1 %r
436 define i1 @different_size_sext_sext_ule_extra_use2(i7 %x, i4 %y) {
437 ; CHECK-LABEL: @different_size_sext_sext_ule_extra_use2(
438 ; CHECK-NEXT:    [[SX:%.*]] = sext i7 [[X:%.*]] to i25
439 ; CHECK-NEXT:    call void @use(i25 [[SX]])
440 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7
441 ; CHECK-NEXT:    [[R:%.*]] = icmp ule i7 [[X]], [[TMP1]]
442 ; CHECK-NEXT:    ret i1 [[R]]
444   %sx = sext i7 %x to i25
445   call void @use(i25 %sx)
446   %sy = sext i4 %y to i25
447   %r = icmp ule i25 %sx, %sy
448   ret i1 %r
451 ; Negative test - extra uses on both casts is too much.
453 define i1 @different_size_sext_sext_ule_extra_use3(i7 %x, i4 %y) {
454 ; CHECK-LABEL: @different_size_sext_sext_ule_extra_use3(
455 ; CHECK-NEXT:    [[SX:%.*]] = sext i7 [[X:%.*]] to i25
456 ; CHECK-NEXT:    call void @use(i25 [[SX]])
457 ; CHECK-NEXT:    [[SY:%.*]] = sext i4 [[Y:%.*]] to i25
458 ; CHECK-NEXT:    call void @use(i25 [[SY]])
459 ; CHECK-NEXT:    [[R:%.*]] = icmp ule i25 [[SX]], [[SY]]
460 ; CHECK-NEXT:    ret i1 [[R]]
462   %sx = sext i7 %x to i25
463   call void @use(i25 %sx)
464   %sy = sext i4 %y to i25
465   call void @use(i25 %sy)
466   %r = icmp ule i25 %sx, %sy
467   ret i1 %r