1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
5 declare void @llvm.assume(i1)
7 define void @test.not.uge.ult(i8 %start, i8 %high) {
8 ; CHECK-LABEL: @test.not.uge.ult(
10 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], 3
11 ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]]
12 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
14 ; CHECK-NEXT: ret void
16 ; CHECK-NEXT: [[T_0:%.*]] = icmp ult i8 [[START]], [[HIGH]]
17 ; CHECK-NEXT: call void @use(i1 [[T_0]])
18 ; CHECK-NEXT: [[START_1:%.*]] = add nsw i8 [[START]], 1
19 ; CHECK-NEXT: [[T_1:%.*]] = icmp ult i8 [[START_1]], [[HIGH]]
20 ; CHECK-NEXT: call void @use(i1 [[T_1]])
21 ; CHECK-NEXT: [[START_2:%.*]] = add nsw i8 [[START]], 2
22 ; CHECK-NEXT: [[T_2:%.*]] = icmp ult i8 [[START_2]], [[HIGH]]
23 ; CHECK-NEXT: call void @use(i1 [[T_2]])
24 ; CHECK-NEXT: [[START_3:%.*]] = add nsw i8 [[START]], 3
25 ; CHECK-NEXT: [[T_3:%.*]] = icmp ult i8 [[START_3]], [[HIGH]]
26 ; CHECK-NEXT: call void @use(i1 [[T_3]])
27 ; CHECK-NEXT: [[START_4:%.*]] = add nsw i8 [[START]], 4
28 ; CHECK-NEXT: [[C_4:%.*]] = icmp ult i8 [[START_4]], [[HIGH]]
29 ; CHECK-NEXT: call void @use(i1 [[C_4]])
30 ; CHECK-NEXT: ret void
33 %add.ptr.i = add nsw i8 %start, 3
34 %c.1 = icmp uge i8 %add.ptr.i, %high
35 br i1 %c.1, label %if.then, label %if.end
37 if.then: ; preds = %entry
40 if.end: ; preds = %entry
41 %t.0 = icmp ult i8 %start, %high
42 call void @use(i1 %t.0)
43 %start.1 = add nsw i8 %start, 1
44 %t.1 = icmp ult i8 %start.1, %high
45 call void @use(i1 %t.1)
46 %start.2 = add nsw i8 %start, 2
47 %t.2 = icmp ult i8 %start.2, %high
48 call void @use(i1 %t.2)
49 %start.3 = add nsw i8 %start, 3
50 %t.3 = icmp ult i8 %start.3, %high
51 call void @use(i1 %t.3)
52 %start.4 = add nsw i8 %start, 4
53 %c.4 = icmp ult i8 %start.4, %high
54 call void @use(i1 %c.4)
58 define void @test.not.sge.slt(i8 %start, i8 %high) {
59 ; CHECK-LABEL: @test.not.sge.slt(
61 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], 3
62 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[ADD_PTR_I]], [[HIGH:%.*]]
63 ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
65 ; CHECK-NEXT: ret void
67 ; CHECK-NEXT: call void @use(i1 true)
68 ; CHECK-NEXT: [[START_1:%.*]] = add nsw i8 [[START]], 1
69 ; CHECK-NEXT: call void @use(i1 true)
70 ; CHECK-NEXT: [[START_2:%.*]] = add nsw i8 [[START]], 2
71 ; CHECK-NEXT: call void @use(i1 true)
72 ; CHECK-NEXT: [[START_3:%.*]] = add nsw i8 [[START]], 3
73 ; CHECK-NEXT: call void @use(i1 true)
74 ; CHECK-NEXT: [[START_4:%.*]] = add nsw i8 [[START]], 4
75 ; CHECK-NEXT: [[C_4:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
76 ; CHECK-NEXT: call void @use(i1 [[C_4]])
77 ; CHECK-NEXT: ret void
80 %add.ptr.i = add nsw i8 %start, 3
81 %c.1 = icmp sge i8 %add.ptr.i, %high
82 br i1 %c.1, label %if.then, label %if.end
84 if.then: ; preds = %entry
87 if.end: ; preds = %entry
88 %t.0 = icmp slt i8 %start, %high
89 call void @use(i1 %t.0)
90 %start.1 = add nsw i8 %start, 1
91 %t.1 = icmp slt i8 %start.1, %high
92 call void @use(i1 %t.1)
93 %start.2 = add nsw i8 %start, 2
94 %t.2 = icmp slt i8 %start.2, %high
95 call void @use(i1 %t.2)
96 %start.3 = add nsw i8 %start, 3
97 %t.3 = icmp slt i8 %start.3, %high
98 call void @use(i1 %t.3)
99 %start.4 = add nsw i8 %start, 4
100 %c.4 = icmp slt i8 %start.4, %high
101 call void @use(i1 %c.4)
105 define void @test.decompose.nonconst(i8 %a, i8 %b, i8 %c, i8 %d) {
106 ; CHECK-LABEL: @test.decompose.nonconst(
108 ; CHECK-NEXT: [[C_0:%.*]] = icmp sge i8 [[A:%.*]], [[C:%.*]]
109 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[C]]
110 ; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]]
111 ; CHECK-NEXT: br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
113 ; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[A]], 0
114 ; CHECK-NEXT: [[C_3:%.*]] = icmp sge i8 [[B]], 0
115 ; CHECK-NEXT: [[AND_1:%.*]] = and i1 [[C_2]], [[C_3]]
116 ; CHECK-NEXT: br i1 [[AND_1]], label [[IF_THEN_2:%.*]], label [[IF_END]]
118 ; CHECK-NEXT: [[ADD_0:%.*]] = add nsw i8 [[A]], [[B]]
119 ; CHECK-NEXT: call void @use(i1 true)
120 ; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i8 [[A]], [[A]]
121 ; CHECK-NEXT: call void @use(i1 true)
122 ; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i8 [[A]], [[D:%.*]]
123 ; CHECK-NEXT: [[C_4:%.*]] = icmp sge i8 [[ADD_2]], [[C]]
124 ; CHECK-NEXT: call void @use(i1 [[C_4]])
125 ; CHECK-NEXT: ret void
127 ; CHECK-NEXT: ret void
130 %c.0 = icmp sge i8 %a, %c
131 %c.1 = icmp sge i8 %b, %c
132 %and.0 = and i1 %c.0, %c.1
133 br i1 %and.0, label %if.then, label %if.end
135 if.then: ; preds = %entry
136 %c.2 = icmp sge i8 %a, 0
137 %c.3 = icmp sge i8 %b, 0
138 %and.1 = and i1 %c.2, %c.3
139 br i1 %and.1, label %if.then.2, label %if.end
142 %add.0 = add nsw i8 %a, %b
143 %t.0 = icmp sge i8 %add.0, %c
144 call void @use(i1 %t.0)
145 %add.1 = add nsw i8 %a, %a
146 %t.1 = icmp sge i8 %add.0, %c
147 call void @use(i1 %t.1)
148 %add.2 = add nsw i8 %a, %d
149 %c.4 = icmp sge i8 %add.2, %c
150 call void @use(i1 %c.4)
153 if.end: ; preds = %entry
157 define void @test.decompose.nonconst.no.null.check(i8 %a, i8 %b, i8 %c, i8 %d) {
158 ; CHECK-LABEL: @test.decompose.nonconst.no.null.check(
160 ; CHECK-NEXT: [[C_0:%.*]] = icmp sge i8 [[A:%.*]], [[C:%.*]]
161 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[C]]
162 ; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]]
163 ; CHECK-NEXT: br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
165 ; CHECK-NEXT: [[ADD_0:%.*]] = add nsw i8 [[A]], [[B]]
166 ; CHECK-NEXT: [[T_0:%.*]] = icmp sge i8 [[ADD_0]], [[C]]
167 ; CHECK-NEXT: call void @use(i1 [[T_0]])
168 ; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i8 [[A]], [[A]]
169 ; CHECK-NEXT: [[T_1:%.*]] = icmp sge i8 [[ADD_0]], [[C]]
170 ; CHECK-NEXT: call void @use(i1 [[T_1]])
171 ; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i8 [[A]], [[D:%.*]]
172 ; CHECK-NEXT: [[C_4:%.*]] = icmp sge i8 [[ADD_2]], [[C]]
173 ; CHECK-NEXT: call void @use(i1 [[C_4]])
174 ; CHECK-NEXT: ret void
176 ; CHECK-NEXT: ret void
179 %c.0 = icmp sge i8 %a, %c
180 %c.1 = icmp sge i8 %b, %c
181 %and.0 = and i1 %c.0, %c.1
182 br i1 %and.0, label %if.then, label %if.end
184 if.then: ; preds = %entry
185 %add.0 = add nsw i8 %a, %b
186 %t.0 = icmp sge i8 %add.0, %c
187 call void @use(i1 %t.0)
188 %add.1 = add nsw i8 %a, %a
189 %t.1 = icmp sge i8 %add.0, %c
190 call void @use(i1 %t.1)
191 %add.2 = add nsw i8 %a, %d
192 %c.4 = icmp sge i8 %add.2, %c
193 call void @use(i1 %c.4)
196 if.end: ; preds = %entry
200 define void @test.sge.slt.add.neg(i8 %start, i8 %high) {
201 ; CHECK-LABEL: @test.sge.slt.add.neg(
203 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], -3
204 ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i8 [[ADD_PTR_I]], [[HIGH:%.*]]
205 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
206 ; CHECK-NEXT: [[C_2:%.*]] = icmp slt i8 [[START]], [[HIGH]]
207 ; CHECK-NEXT: call void @use(i1 [[C_2]])
208 ; CHECK-NEXT: [[START_1:%.*]] = add nsw i8 [[START]], 1
209 ; CHECK-NEXT: [[C_3:%.*]] = icmp slt i8 [[START_1]], [[HIGH]]
210 ; CHECK-NEXT: call void @use(i1 [[C_3]])
211 ; CHECK-NEXT: [[START_2:%.*]] = add nsw i8 [[START]], -2
212 ; CHECK-NEXT: [[C_4:%.*]] = icmp slt i8 [[START_2]], [[HIGH]]
213 ; CHECK-NEXT: call void @use(i1 [[C_4]])
214 ; CHECK-NEXT: [[START_3:%.*]] = add nsw i8 [[START]], -3
215 ; CHECK-NEXT: call void @use(i1 true)
216 ; CHECK-NEXT: [[START_4:%.*]] = add nsw i8 [[START]], -4
217 ; CHECK-NEXT: call void @use(i1 true)
218 ; CHECK-NEXT: ret void
221 %add.ptr.i = add nsw i8 %start, -3
222 %c.1 = icmp slt i8 %add.ptr.i, %high
223 call void @llvm.assume(i1 %c.1)
224 %c.2 = icmp slt i8 %start, %high
225 call void @use(i1 %c.2)
226 %start.1 = add nsw i8 %start, 1
227 %c.3 = icmp slt i8 %start.1, %high
228 call void @use(i1 %c.3)
229 %start.2 = add nsw i8 %start, -2
230 %c.4 = icmp slt i8 %start.2, %high
231 call void @use(i1 %c.4)
232 %start.3 = add nsw i8 %start, -3
233 %t.1 = icmp slt i8 %start.3, %high
234 call void @use(i1 %t.1)
235 %start.4 = add nsw i8 %start, -4
236 %t.2 = icmp slt i8 %start.4, %high
237 call void @use(i1 %t.2)
241 define i1 @test_ult_add_nsw_pos_1(i8 %start, i8 %high) {
242 ; CHECK-LABEL: @test_ult_add_nsw_pos_1(
244 ; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
245 ; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
246 ; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
247 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
248 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
249 ; CHECK-NEXT: ret i1 true
252 %high.ext = zext i8 %high to i16
253 %start.ext = zext i8 %start to i16
254 %add.ext = add nsw i16 %start.ext, 3
255 %c.1 = icmp ult i16 %add.ext, %high.ext
256 call void @llvm.assume(i1 %c.1)
258 %t = icmp ult i16 %start.ext, %high.ext
262 define i1 @test_ult_add_nsw_pos_1_assume_pos(i8 %start, i8 %high) {
263 ; CHECK-LABEL: @test_ult_add_nsw_pos_1_assume_pos(
265 ; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
266 ; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
267 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], 3
268 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
269 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
270 ; CHECK-NEXT: ret i1 true
273 %start.pos = icmp sge i8 %start, 0
274 call void @llvm.assume(i1 %start.pos)
275 %add = add nsw i8 %start, 3
276 %c.1 = icmp ult i8 %add, %high
277 call void @llvm.assume(i1 %c.1)
279 %t = icmp ult i8 %start, %high
283 define i1 @test_ult_add_nsw_pos_1_no_assume_pos(i8 %start, i8 %high) {
284 ; CHECK-LABEL: @test_ult_add_nsw_pos_1_no_assume_pos(
286 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START:%.*]], 3
287 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
288 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
289 ; CHECK-NEXT: [[T:%.*]] = icmp ult i8 [[START]], [[HIGH]]
290 ; CHECK-NEXT: ret i1 [[T]]
293 %add = add nsw i8 %start, 3
294 %c.1 = icmp ult i8 %add, %high
295 call void @llvm.assume(i1 %c.1)
297 %t = icmp ult i8 %start, %high
301 define i1 @test_ult_add_nsw_pos_1_cmp_no_ext(i8 %start, i8 %high) {
302 ; CHECK-LABEL: @test_ult_add_nsw_pos_1_cmp_no_ext(
304 ; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
305 ; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
306 ; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
307 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
308 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
309 ; CHECK-NEXT: ret i1 true
312 %high.ext = zext i8 %high to i16
313 %start.ext = zext i8 %start to i16
314 %add.ext = add nsw i16 %start.ext, 3
315 %c.1 = icmp ult i16 %add.ext, %high.ext
316 call void @llvm.assume(i1 %c.1)
318 %t = icmp ult i8 %start, %high
322 define i1 @test_ult_add_nsw_pos_2(i8 %start, i8 %high) {
323 ; CHECK-LABEL: @test_ult_add_nsw_pos_2(
325 ; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
326 ; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
327 ; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
328 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
329 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
330 ; CHECK-NEXT: ret i1 false
333 %high.ext = zext i8 %high to i16
334 %start.ext = zext i8 %start to i16
335 %add.ext = add nsw i16 %start.ext, 3
336 %c.1 = icmp ult i16 %add.ext, %high.ext
337 call void @llvm.assume(i1 %c.1)
339 %f = icmp uge i16 %start.ext, %high.ext
343 define i1 @test_ult_add_nsw_pos_2_assume_pos(i8 %start, i8 %high) {
344 ; CHECK-LABEL: @test_ult_add_nsw_pos_2_assume_pos(
346 ; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
347 ; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
348 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], 3
349 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
350 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
351 ; CHECK-NEXT: ret i1 false
354 %start.pos = icmp sge i8 %start, 0
355 call void @llvm.assume(i1 %start.pos)
356 %add = add nsw i8 %start, 3
357 %c.1 = icmp ult i8 %add, %high
358 call void @llvm.assume(i1 %c.1)
360 %f = icmp uge i8 %start, %high
364 define i1 @test_ult_add_nsw_pos_2_cmp_no_ext(i8 %start, i8 %high) {
365 ; CHECK-LABEL: @test_ult_add_nsw_pos_2_cmp_no_ext(
367 ; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
368 ; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
369 ; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
370 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
371 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
372 ; CHECK-NEXT: ret i1 false
375 %high.ext = zext i8 %high to i16
376 %start.ext = zext i8 %start to i16
377 %add.ext = add nsw i16 %start.ext, 3
378 %c.1 = icmp ult i16 %add.ext, %high.ext
379 call void @llvm.assume(i1 %c.1)
381 %c = icmp uge i8 %start, %high
385 define i1 @test_ult_add_nsw_pos_3(i8 %start, i8 %high) {
386 ; CHECK-LABEL: @test_ult_add_nsw_pos_3(
388 ; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
389 ; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
390 ; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
391 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
392 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
393 ; CHECK-NEXT: [[ADD_4:%.*]] = add nsw i16 [[START_EXT]], 4
394 ; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[ADD_4]], [[HIGH_EXT]]
395 ; CHECK-NEXT: ret i1 [[C]]
398 %high.ext = zext i8 %high to i16
399 %start.ext = zext i8 %start to i16
400 %add.ext = add nsw i16 %start.ext, 3
401 %c.1 = icmp ult i16 %add.ext, %high.ext
402 call void @llvm.assume(i1 %c.1)
404 %add.4 = add nsw i16 %start.ext, 4
405 %c = icmp ult i16 %add.4, %high.ext
409 define i1 @test_ult_add_nsw_pos_3_assume_pos(i8 %start, i8 %high) {
410 ; CHECK-LABEL: @test_ult_add_nsw_pos_3_assume_pos(
412 ; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
413 ; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
414 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], 3
415 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
416 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
417 ; CHECK-NEXT: [[ADD_4:%.*]] = add nsw i8 [[START]], 4
418 ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_4]], [[HIGH]]
419 ; CHECK-NEXT: ret i1 [[C]]
422 %start.pos = icmp sge i8 %start, 0
423 call void @llvm.assume(i1 %start.pos)
424 %add = add nsw i8 %start, 3
425 %c.1 = icmp ult i8 %add, %high
426 call void @llvm.assume(i1 %c.1)
428 %add.4 = add nsw i8 %start, 4
429 %c = icmp ult i8 %add.4, %high
433 define i1 @test_ult_add_nsw_pos_4(i8 %start, i8 %high) {
434 ; CHECK-LABEL: @test_ult_add_nsw_pos_4(
436 ; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
437 ; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
438 ; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
439 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
440 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
441 ; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i16 [[START_EXT]], 2
442 ; CHECK-NEXT: ret i1 true
445 %high.ext = zext i8 %high to i16
446 %start.ext = zext i8 %start to i16
447 %add.ext = add nsw i16 %start.ext, 3
448 %c.1 = icmp ult i16 %add.ext, %high.ext
449 call void @llvm.assume(i1 %c.1)
451 %add.2 = add nsw i16 %start.ext, 2
452 %c = icmp ult i16 %add.2, %high.ext
456 define i1 @test_ult_add_nsw_pos_4_assume_pos(i8 %start, i8 %high) {
457 ; CHECK-LABEL: @test_ult_add_nsw_pos_4_assume_pos(
459 ; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
460 ; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
461 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], 3
462 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
463 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
464 ; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i8 [[START]], 2
465 ; CHECK-NEXT: ret i1 true
468 %start.pos = icmp sge i8 %start, 0
469 call void @llvm.assume(i1 %start.pos)
470 %add = add nsw i8 %start, 3
471 %c.1 = icmp ult i8 %add, %high
472 call void @llvm.assume(i1 %c.1)
474 %add.2 = add nsw i8 %start, 2
475 %c = icmp ult i8 %add.2, %high
479 define i1 @test_ult_add_nsw_neg_5(i8 %start, i8 %high) {
480 ; CHECK-LABEL: @test_ult_add_nsw_neg_5(
482 ; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
483 ; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
484 ; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
485 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
486 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
487 ; CHECK-NEXT: [[SUB_2:%.*]] = add nsw i16 [[START_EXT]], -2
488 ; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[SUB_2]], [[HIGH_EXT]]
489 ; CHECK-NEXT: ret i1 [[C]]
492 %high.ext = zext i8 %high to i16
493 %start.ext = zext i8 %start to i16
494 %add.ext = add nsw i16 %start.ext, 3
495 %c.1 = icmp ult i16 %add.ext, %high.ext
496 call void @llvm.assume(i1 %c.1)
498 %sub.2 = add nsw i16 %start.ext, -2
499 %c = icmp ult i16 %sub.2, %high.ext
503 define i1 @test_ult_add_nsw_neg_5_assume_pos(i8 %start, i8 %high) {
504 ; CHECK-LABEL: @test_ult_add_nsw_neg_5_assume_pos(
506 ; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
507 ; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
508 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], 3
509 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
510 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
511 ; CHECK-NEXT: [[SUB_2:%.*]] = add nsw i8 [[START]], -2
512 ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[SUB_2]], [[HIGH]]
513 ; CHECK-NEXT: ret i1 [[C]]
516 %start.pos = icmp sge i8 %start, 0
517 call void @llvm.assume(i1 %start.pos)
518 %add = add nsw i8 %start, 3
519 %c.1 = icmp ult i8 %add, %high
520 call void @llvm.assume(i1 %c.1)
522 %sub.2 = add nsw i8 %start, -2
523 %c = icmp ult i8 %sub.2, %high
527 define i1 @test_ult_add_no_nsw_pos_6(i8 %start, i8 %high) {
528 ; CHECK-LABEL: @test_ult_add_no_nsw_pos_6(
530 ; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
531 ; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
532 ; CHECK-NEXT: [[ADD_EXT:%.*]] = add i16 [[START_EXT]], 3
533 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
534 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
535 ; CHECK-NEXT: [[ADD_2:%.*]] = add i16 [[START_EXT]], 2
536 ; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[ADD_2]], [[HIGH_EXT]]
537 ; CHECK-NEXT: ret i1 [[C]]
540 %high.ext = zext i8 %high to i16
541 %start.ext = zext i8 %start to i16
542 %add.ext = add i16 %start.ext, 3
543 %c.1 = icmp ult i16 %add.ext, %high.ext
544 call void @llvm.assume(i1 %c.1)
546 %add.2 = add i16 %start.ext, 2
547 %c = icmp ult i16 %add.2, %high.ext
551 define i1 @test_ult_add_no_nsw_pos_6_assume_pos(i8 %start, i8 %high) {
552 ; CHECK-LABEL: @test_ult_add_no_nsw_pos_6_assume_pos(
554 ; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
555 ; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
556 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[START]], 3
557 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
558 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
559 ; CHECK-NEXT: [[ADD_2:%.*]] = add i8 [[START]], 2
560 ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_2]], [[HIGH]]
561 ; CHECK-NEXT: ret i1 [[C]]
564 %start.pos = icmp sge i8 %start, 0
565 call void @llvm.assume(i1 %start.pos)
566 %add = add i8 %start, 3
567 %c.1 = icmp ult i8 %add, %high
568 call void @llvm.assume(i1 %c.1)
570 %add.2 = add i8 %start, 2
571 %c = icmp ult i8 %add.2, %high
575 define i1 @test_ult_add_nsw_var_7(i8 %start, i8 %off, i8 %high) {
576 ; CHECK-LABEL: @test_ult_add_nsw_var_7(
578 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START:%.*]], [[OFF:%.*]]
579 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
580 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
581 ; CHECK-NEXT: [[OFF_POS:%.*]] = icmp sge i8 [[OFF]], 0
582 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_POS]])
583 ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[START]], [[HIGH]]
584 ; CHECK-NEXT: ret i1 [[C]]
587 %add = add nsw i8 %start, %off
588 %c.1 = icmp ult i8 %add, %high
589 call void @llvm.assume(i1 %c.1)
590 %off.pos = icmp sge i8 %off, 0
591 call void @llvm.assume(i1 %off.pos)
593 %c = icmp ult i8 %start, %high
597 define i1 @test_ult_add_no_nsw_var_7(i8 %start, i8 %off, i8 %high) {
598 ; CHECK-LABEL: @test_ult_add_no_nsw_var_7(
600 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[START:%.*]], [[OFF:%.*]]
601 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
602 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
603 ; CHECK-NEXT: [[OFF_POS:%.*]] = icmp sge i8 [[OFF]], 0
604 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_POS]])
605 ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[START]], [[HIGH]]
606 ; CHECK-NEXT: ret i1 [[C]]
609 %add = add i8 %start, %off
610 %c.1 = icmp ult i8 %add, %high
611 call void @llvm.assume(i1 %c.1)
612 %off.pos = icmp sge i8 %off, 0
613 call void @llvm.assume(i1 %off.pos)
615 %c = icmp ult i8 %start, %high
619 define i1 @test_ult_add_nsw_var_8(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
620 ; CHECK-LABEL: @test_ult_add_nsw_var_8(
622 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START:%.*]], [[OFF_2:%.*]]
623 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
624 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
625 ; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
626 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]])
627 ; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
628 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]])
629 ; CHECK-NEXT: [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]]
630 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_ULT]])
631 ; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
632 ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]]
633 ; CHECK-NEXT: ret i1 [[C]]
636 %add = add nsw i8 %start, %off.2
637 %c.1 = icmp ult i8 %add, %high
638 call void @llvm.assume(i1 %c.1)
639 %off.1.pos = icmp sge i8 %off.1, 0
640 call void @llvm.assume(i1 %off.1.pos)
641 %off.2.pos = icmp sge i8 %off.2, 0
642 call void @llvm.assume(i1 %off.2.pos)
643 %off.1.ult = icmp ult i8 %off.1, %off.2
644 call void @llvm.assume(i1 %off.1.ult)
646 %add.off.2 = add nsw i8 %start, %off.1
647 %c = icmp ult i8 %add.off.2, %high
651 define i1 @test_ult_add_nsw_var_8_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
652 ; CHECK-LABEL: @test_ult_add_nsw_var_8_all_pos(
654 ; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
655 ; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
656 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], [[OFF_2:%.*]]
657 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
658 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
659 ; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
660 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]])
661 ; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
662 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]])
663 ; CHECK-NEXT: [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]]
664 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_ULT]])
665 ; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
666 ; CHECK-NEXT: ret i1 true
669 %start.pos = icmp sge i8 %start, 0
670 call void @llvm.assume(i1 %start.pos)
671 %add = add nsw i8 %start, %off.2
672 %c.1 = icmp ult i8 %add, %high
673 call void @llvm.assume(i1 %c.1)
674 %off.1.pos = icmp sge i8 %off.1, 0
675 call void @llvm.assume(i1 %off.1.pos)
676 %off.2.pos = icmp sge i8 %off.2, 0
677 call void @llvm.assume(i1 %off.2.pos)
678 %off.1.ult = icmp ult i8 %off.1, %off.2
679 call void @llvm.assume(i1 %off.1.ult)
681 %add.off.2 = add nsw i8 %start, %off.1
682 %c = icmp ult i8 %add.off.2, %high
686 define i1 @test_ult_add_no_nsw_var_8_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
687 ; CHECK-LABEL: @test_ult_add_no_nsw_var_8_all_pos(
689 ; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
690 ; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
691 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[START]], [[OFF_2:%.*]]
692 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
693 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
694 ; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
695 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]])
696 ; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
697 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]])
698 ; CHECK-NEXT: [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]]
699 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_ULT]])
700 ; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
701 ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]]
702 ; CHECK-NEXT: ret i1 [[C]]
705 %start.pos = icmp sge i8 %start, 0
706 call void @llvm.assume(i1 %start.pos)
707 %add = add i8 %start, %off.2
708 %c.1 = icmp ult i8 %add, %high
709 call void @llvm.assume(i1 %c.1)
710 %off.1.pos = icmp sge i8 %off.1, 0
711 call void @llvm.assume(i1 %off.1.pos)
712 %off.2.pos = icmp sge i8 %off.2, 0
713 call void @llvm.assume(i1 %off.2.pos)
714 %off.1.ult = icmp ult i8 %off.1, %off.2
715 call void @llvm.assume(i1 %off.1.ult)
717 %add.off.2 = add nsw i8 %start, %off.1
718 %c = icmp ult i8 %add.off.2, %high
722 define i1 @test_ult_add_nsw_var_9_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
723 ; CHECK-LABEL: @test_ult_add_nsw_var_9_all_pos(
725 ; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
726 ; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]])
727 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], [[OFF_2:%.*]]
728 ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
729 ; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]])
730 ; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
731 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]])
732 ; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
733 ; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]])
734 ; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
735 ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]]
736 ; CHECK-NEXT: ret i1 [[C]]
739 %start.pos = icmp sge i8 %start, 0
740 call void @llvm.assume(i1 %start.pos)
741 %add = add nsw i8 %start, %off.2
742 %c.1 = icmp ult i8 %add, %high
743 call void @llvm.assume(i1 %c.1)
744 %off.1.pos = icmp sge i8 %off.1, 0
745 call void @llvm.assume(i1 %off.1.pos)
746 %off.2.pos = icmp sge i8 %off.2, 0
747 call void @llvm.assume(i1 %off.2.pos)
749 %add.off.2 = add nsw i8 %start, %off.1
750 %c = icmp ult i8 %add.off.2, %high
754 define i1 @add_neg_1_known_sge_ult_1(i32 %a) {
755 ; CHECK-LABEL: @add_neg_1_known_sge_ult_1(
757 ; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 1
758 ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]])
759 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1
760 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]]
761 ; CHECK-NEXT: ret i1 [[C]]
764 %a.sge = icmp sge i32 %a, 1
765 call void @llvm.assume(i1 %a.sge)
766 %sub = add nsw i32 %a, -1
767 %c = icmp ult i32 %sub, %a
771 define i1 @add_neg_1_known_sge_uge_1(i32 %a) {
772 ; CHECK-LABEL: @add_neg_1_known_sge_uge_1(
774 ; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 1
775 ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]])
776 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1
777 ; CHECK-NEXT: ret i1 true
780 %a.sge = icmp sge i32 %a, 1
781 call void @llvm.assume(i1 %a.sge)
782 %sub = add nsw i32 %a, -1
783 %c = icmp uge i32 %sub, 0
787 define i1 @add_neg_1_not_known_sge_ult_1(i32 %a) {
788 ; CHECK-LABEL: @add_neg_1_not_known_sge_ult_1(
790 ; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 0
791 ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]])
792 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1
793 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]]
794 ; CHECK-NEXT: ret i1 [[C]]
797 %a.sge = icmp sge i32 %a, 0
798 call void @llvm.assume(i1 %a.sge)
799 %sub = add nsw i32 %a, -1
800 %c = icmp ult i32 %sub, %a
804 define i1 @add_neg_1_not_known_sge_uge_1(i32 %a) {
805 ; CHECK-LABEL: @add_neg_1_not_known_sge_uge_1(
807 ; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 0
808 ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]])
809 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1
810 ; CHECK-NEXT: ret i1 true
813 %a.sge = icmp sge i32 %a, 0
814 call void @llvm.assume(i1 %a.sge)
815 %sub = add nsw i32 %a, -1
816 %c = icmp uge i32 %sub, 0
820 define i1 @add_neg_3_known_sge_ult_1(i32 %a) {
821 ; CHECK-LABEL: @add_neg_3_known_sge_ult_1(
823 ; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 3
824 ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]])
825 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3
826 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]]
827 ; CHECK-NEXT: ret i1 [[C]]
830 %a.sge = icmp sge i32 %a, 3
831 call void @llvm.assume(i1 %a.sge)
832 %sub = add nsw i32 %a, -3
833 %c = icmp ult i32 %sub, %a
837 define i1 @add_neg_3_known_sge_uge_1(i32 %a) {
838 ; CHECK-LABEL: @add_neg_3_known_sge_uge_1(
840 ; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 4
841 ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]])
842 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3
843 ; CHECK-NEXT: ret i1 true
846 %a.sge = icmp sge i32 %a, 4
847 call void @llvm.assume(i1 %a.sge)
848 %sub = add nsw i32 %a, -3
849 %c = icmp uge i32 %sub, 0
853 define i1 @add_neg_3_not_known_sge_ult_1(i32 %a) {
854 ; CHECK-LABEL: @add_neg_3_not_known_sge_ult_1(
856 ; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 2
857 ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]])
858 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3
859 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]]
860 ; CHECK-NEXT: ret i1 [[C]]
863 %a.sge = icmp sge i32 %a, 2
864 call void @llvm.assume(i1 %a.sge)
865 %sub = add nsw i32 %a, -3
866 %c = icmp ult i32 %sub, %a
870 define i1 @add_neg_3_not_known_sge_uge_1(i32 %a) {
871 ; CHECK-LABEL: @add_neg_3_not_known_sge_uge_1(
873 ; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 2
874 ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]])
875 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3
876 ; CHECK-NEXT: ret i1 true
879 %a.sge = icmp sge i32 %a, 2
880 call void @llvm.assume(i1 %a.sge)
881 %sub = add nsw i32 %a, -3
882 %c = icmp uge i32 %sub, 0
886 define i1 @add_neg_3_not_known_sge_ult_2(i32 %a, i32 %b) {
887 ; CHECK-LABEL: @add_neg_3_not_known_sge_ult_2(
889 ; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], [[B:%.*]]
890 ; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]])
891 ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3
892 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]]
893 ; CHECK-NEXT: ret i1 [[C]]
896 %a.sge = icmp sge i32 %a, %b
897 call void @llvm.assume(i1 %a.sge)
898 %sub = add nsw i32 %a, -3
899 %c = icmp ult i32 %sub, %a